Merge branch 'master' into sourceFileUpdate

This commit is contained in:
Cyrus Najmabadi 2014-12-16 02:59:05 -08:00
commit 6326b9d51f
7 changed files with 225 additions and 58 deletions

View file

@ -227,23 +227,27 @@ module ts {
if (symbolKind & SymbolFlags.HasLocals) {
node.locals = {};
}
var saveParent = parent;
var saveContainer = container;
var savedBlockScopeContainer = blockScopeContainer;
parent = node;
if (symbolKind & SymbolFlags.IsContainer) {
container = node;
// If container is not on container list, add it to the list
if (lastContainer !== container && !container.nextContainer) {
if (lastContainer) {
lastContainer.nextContainer = container;
}
lastContainer = container;
Debug.assert(container.nextContainer === undefined);
if (lastContainer) {
Debug.assert(lastContainer.nextContainer === undefined);
lastContainer.nextContainer = container;
}
lastContainer = container;
}
if (isBlockScopeContainer) {
blockScopeContainer = node;
}
forEachChild(node, bind);
container = saveContainer;
parent = saveParent;
@ -292,15 +296,6 @@ module ts {
bindChildren(node, symbolKind, isBlockScopeContainer);
}
function bindConstructorDeclaration(node: ConstructorDeclaration) {
bindDeclaration(node, SymbolFlags.Constructor, 0, /*isBlockScopeContainer*/ true);
forEach(node.parameters, p => {
if (p.flags & (NodeFlags.Public | NodeFlags.Private | NodeFlags.Protected)) {
bindDeclaration(p, SymbolFlags.Property, SymbolFlags.PropertyExcludes, /*isBlockScopeContainer*/ false);
}
});
}
function bindModuleDeclaration(node: ModuleDeclaration) {
if (node.name.kind === SyntaxKind.StringLiteral) {
bindDeclaration(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes, /*isBlockScopeContainer*/ true);
@ -389,12 +384,7 @@ module ts {
bindDeclaration(<Declaration>node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes, /*isBlockScopeContainer*/ false);
break;
case SyntaxKind.Parameter:
if (isBindingPattern((<Declaration>node).name)) {
bindAnonymousDeclaration(<Declaration>node, SymbolFlags.FunctionScopedVariable, getDestructuringParameterName(<Declaration>node), /*isBlockScopeContainer*/ false);
}
else {
bindDeclaration(<Declaration>node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes, /*isBlockScopeContainer*/ false);
}
bindParameter(<ParameterDeclaration>node);
break;
case SyntaxKind.VariableDeclaration:
case SyntaxKind.BindingElement:
@ -437,7 +427,7 @@ module ts {
bindDeclaration(<Declaration>node, SymbolFlags.Function, SymbolFlags.FunctionExcludes, /*isBlockScopeContainer*/ true);
break;
case SyntaxKind.Constructor:
bindConstructorDeclaration(<ConstructorDeclaration>node);
bindDeclaration(<Declaration>node, SymbolFlags.Constructor, /*symbolExcludes:*/ 0, /*isBlockScopeContainer:*/ true);
break;
case SyntaxKind.GetAccessor:
bindDeclaration(<Declaration>node, SymbolFlags.GetAccessor, SymbolFlags.GetAccessorExcludes, /*isBlockScopeContainer*/ true);
@ -506,5 +496,24 @@ module ts {
parent = saveParent;
}
}
function bindParameter(node: ParameterDeclaration) {
if (isBindingPattern(node.name)) {
bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, getDestructuringParameterName(node), /*isBlockScopeContainer*/ false);
}
else {
bindDeclaration(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes, /*isBlockScopeContainer*/ false);
}
// If this is a property-parameter, then also declare the property symbol into the
// containing class.
if (node.flags & NodeFlags.AccessibilityModifier &&
node.parent.kind === SyntaxKind.Constructor &&
node.parent.parent.kind === SyntaxKind.ClassDeclaration) {
var classDeclaration = <ClassDeclaration>node.parent.parent;
declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
}
}
}
}

View file

@ -4732,14 +4732,49 @@ module ts {
return type;
}
}
/*Transitively mark all linked imports as referenced*/
function markLinkedImportsAsReferenced(node: ImportDeclaration): void {
var nodeLinks = getNodeLinks(node);
while (nodeLinks.importOnRightSide) {
var rightSide = nodeLinks.importOnRightSide;
nodeLinks.importOnRightSide = undefined;
getSymbolLinks(rightSide).referenced = true;
Debug.assert((rightSide.flags & SymbolFlags.Import) !== 0);
nodeLinks = getNodeLinks(getDeclarationOfKind(rightSide, SyntaxKind.ImportDeclaration))
}
}
function checkIdentifier(node: Identifier): Type {
var symbol = getResolvedSymbol(node);
if (symbol.flags & SymbolFlags.Import) {
// Mark the import as referenced so that we emit it in the final .js file.
// exception: identifiers that appear in type queries, const enums, modules that contain only const enums
getSymbolLinks(symbol).referenced = getSymbolLinks(symbol).referenced || (!isInTypeQuery(node) && !isConstEnumOrConstEnumOnlyModule(resolveImport(symbol)));
var symbolLinks = getSymbolLinks(symbol);
if (!symbolLinks.referenced) {
var importOrExportAssignment = getLeftSideOfImportOrExportAssignment(node);
// decision about whether import is referenced can be made now if
// - import that are used anywhere except right side of import declarations
// - imports that are used on the right side of exported import declarations
// for other cases defer decision until the check of left side
if (!importOrExportAssignment ||
(importOrExportAssignment.flags & NodeFlags.Export) ||
(importOrExportAssignment.kind === SyntaxKind.ExportAssignment)) {
// Mark the import as referenced so that we emit it in the final .js file.
// exception: identifiers that appear in type queries, const enums, modules that contain only const enums
symbolLinks.referenced = !isInTypeQuery(node) && !isConstEnumOrConstEnumOnlyModule(resolveImport(symbol));
}
else {
var nodeLinks = getNodeLinks(importOrExportAssignment);
Debug.assert(!nodeLinks.importOnRightSide);
nodeLinks.importOnRightSide = symbol;
}
}
if (symbolLinks.referenced) {
markLinkedImportsAsReferenced(<ImportDeclaration>getDeclarationOfKind(symbol, SyntaxKind.ImportDeclaration));
}
}
checkCollisionWithCapturedSuperVariable(node, node);
@ -8868,6 +8903,8 @@ module ts {
if (symbol && symbol.flags & SymbolFlags.Import) {
// Mark the import as referenced so that we emit it in the final .js file.
getSymbolLinks(symbol).referenced = true;
// mark any import declarations that depend upon this import as referenced
markLinkedImportsAsReferenced(<ImportDeclaration>getDeclarationOfKind(symbol, SyntaxKind.ImportDeclaration))
}
}
@ -9093,19 +9130,24 @@ module ts {
return false;
}
function getLeftSideOfImportOrExportAssignment(nodeOnRightSide: EntityName): ImportDeclaration | ExportAssignment {
while (nodeOnRightSide.parent.kind === SyntaxKind.QualifiedName) {
nodeOnRightSide = <QualifiedName>nodeOnRightSide.parent;
}
if (nodeOnRightSide.parent.kind === SyntaxKind.ImportDeclaration) {
return (<ImportDeclaration>nodeOnRightSide.parent).moduleReference === nodeOnRightSide && <ImportDeclaration>nodeOnRightSide.parent;
}
if (nodeOnRightSide.parent.kind === SyntaxKind.ExportAssignment) {
return (<ExportAssignment>nodeOnRightSide.parent).exportName === nodeOnRightSide && <ExportAssignment>nodeOnRightSide.parent;
}
return undefined;
}
function isInRightSideOfImportOrExportAssignment(node: EntityName) {
while (node.parent.kind === SyntaxKind.QualifiedName) {
node = <QualifiedName>node.parent;
}
if (node.parent.kind === SyntaxKind.ImportDeclaration) {
return (<ImportDeclaration>node.parent).moduleReference === node;
}
if (node.parent.kind === SyntaxKind.ExportAssignment) {
return (<ExportAssignment>node.parent).exportName === node;
}
return false;
return getLeftSideOfImportOrExportAssignment(node) !== undefined;
}
function isRightSideOfQualifiedNameOrPropertyAccess(node: Node) {

View file

@ -4146,38 +4146,39 @@ module ts {
// DECLARATIONS
function parseBindingElement(context: ParsingContext): BindingElement {
if (context === ParsingContext.ArrayBindingElements && token === SyntaxKind.CommaToken) {
function parseArrayBindingElement(): BindingElement {
if (token === SyntaxKind.CommaToken) {
return <BindingElement>createNode(SyntaxKind.OmittedExpression);
}
var node = <BindingElement>createNode(SyntaxKind.BindingElement);
if (context === ParsingContext.ObjectBindingElements) {
// TODO(andersh): Handle computed properties
var id = parsePropertyName();
if (id.kind === SyntaxKind.Identifier && token !== SyntaxKind.ColonToken) {
node.name = <Identifier>id;
}
else {
parseExpected(SyntaxKind.ColonToken);
node.propertyName = <Identifier>id;
node.name = parseIdentifierOrPattern();
}
}
else {
node.name = parseIdentifierOrPattern();
}
node.name = parseIdentifierOrPattern();
node.initializer = parseInitializer(/*inParameter*/ false);
return finishNode(node);
}
function parseBindingList(context: ParsingContext): NodeArray<BindingElement> {
return parseDelimitedList(context, () => parseBindingElement(context));
function parseObjectBindingElement(): BindingElement {
var node = <BindingElement>createNode(SyntaxKind.BindingElement);
// TODO(andersh): Handle computed properties
var id = parsePropertyName();
if (id.kind === SyntaxKind.Identifier && token !== SyntaxKind.ColonToken) {
node.name = <Identifier>id;
}
else {
parseExpected(SyntaxKind.ColonToken);
node.propertyName = <Identifier>id;
node.name = parseIdentifierOrPattern();
}
node.initializer = parseInitializer(/*inParameter*/ false);
return finishNode(node);
}
function parseObjectBindingPattern(): BindingPattern {
var node = <BindingPattern>createNode(SyntaxKind.ObjectBindingPattern);
parseExpected(SyntaxKind.OpenBraceToken);
node.elements = parseBindingList(ParsingContext.ObjectBindingElements);
node.elements = parseDelimitedList(ParsingContext.ObjectBindingElements, parseObjectBindingElement);
parseExpected(SyntaxKind.CloseBraceToken);
return finishNode(node);
}
@ -4185,7 +4186,7 @@ module ts {
function parseArrayBindingPattern(): BindingPattern {
var node = <BindingPattern>createNode(SyntaxKind.ArrayBindingPattern);
parseExpected(SyntaxKind.OpenBracketToken);
node.elements = parseBindingList(ParsingContext.ArrayBindingElements);
node.elements = parseDelimitedList(ParsingContext.ArrayBindingElements, parseArrayBindingElement);
parseExpected(SyntaxKind.CloseBracketToken);
return finishNode(node);
}

View file

@ -1233,6 +1233,7 @@ module ts {
isVisible?: boolean; // Is this node visible
localModuleName?: string; // Local name for module instance
assignmentChecks?: Map<boolean>; // Cache of assignment checks
importOnRightSide?: Symbol; // for import declarations - import that appear on the right side
}
export const enum TypeFlags {

View file

@ -0,0 +1,55 @@
//// [tests/cases/compiler/importedAliasesInTypePositions.ts] ////
//// [file1.ts]
export module elaborate.nested.mod.name {
export class ReferredTo {
doSomething(): void {
}
}
}
//// [file2.ts]
import RT_ALIAS = require("file1");
import ReferredTo = RT_ALIAS.elaborate.nested.mod.name.ReferredTo;
export module ImportingModule {
class UsesReferredType {
constructor(private referred: ReferredTo) { }
}
}
//// [file1.js]
define(["require", "exports"], function (require, exports) {
var elaborate;
(function (elaborate) {
var nested;
(function (nested) {
var mod;
(function (mod) {
var name;
(function (name) {
var ReferredTo = (function () {
function ReferredTo() {
}
ReferredTo.prototype.doSomething = function () {
};
return ReferredTo;
})();
name.ReferredTo = ReferredTo;
})(name = mod.name || (mod.name = {}));
})(mod = nested.mod || (nested.mod = {}));
})(nested = elaborate.nested || (elaborate.nested = {}));
})(elaborate = exports.elaborate || (exports.elaborate = {}));
});
//// [file2.js]
define(["require", "exports"], function (require, exports) {
var ImportingModule;
(function (ImportingModule) {
var UsesReferredType = (function () {
function UsesReferredType(referred) {
this.referred = referred;
}
return UsesReferredType;
})();
})(ImportingModule = exports.ImportingModule || (exports.ImportingModule = {}));
});

View file

@ -0,0 +1,40 @@
=== tests/cases/compiler/file2.ts ===
import RT_ALIAS = require("file1");
>RT_ALIAS : typeof RT_ALIAS
import ReferredTo = RT_ALIAS.elaborate.nested.mod.name.ReferredTo;
>ReferredTo : typeof ReferredTo
>RT_ALIAS : typeof RT_ALIAS
>elaborate : typeof RT_ALIAS.elaborate
>nested : typeof RT_ALIAS.elaborate.nested
>mod : typeof RT_ALIAS.elaborate.nested.mod
>name : typeof RT_ALIAS.elaborate.nested.mod.name
>ReferredTo : ReferredTo
export module ImportingModule {
>ImportingModule : typeof ImportingModule
class UsesReferredType {
>UsesReferredType : UsesReferredType
constructor(private referred: ReferredTo) { }
>referred : ReferredTo
>ReferredTo : ReferredTo
}
}
=== tests/cases/compiler/file1.ts ===
export module elaborate.nested.mod.name {
>elaborate : typeof elaborate
>nested : typeof nested
>mod : typeof mod
>name : typeof name
export class ReferredTo {
>ReferredTo : ReferredTo
doSomething(): void {
>doSomething : () => void
}
}
}

View file

@ -0,0 +1,19 @@
// @module:amd
// @Filename: file1.ts
export module elaborate.nested.mod.name {
export class ReferredTo {
doSomething(): void {
}
}
}
// @Filename: file2.ts
// @module: amd
import RT_ALIAS = require("file1");
import ReferredTo = RT_ALIAS.elaborate.nested.mod.name.ReferredTo;
export module ImportingModule {
class UsesReferredType {
constructor(private referred: ReferredTo) { }
}
}