mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into sideEffects
Conflicts: tests/baselines/reference/recursiveClassReferenceTest.js.map
This commit is contained in:
+50
-31
@@ -15,12 +15,12 @@ module ts {
|
||||
if (node.kind === SyntaxKind.InterfaceDeclaration || node.kind === SyntaxKind.TypeAliasDeclaration) {
|
||||
return ModuleInstanceState.NonInstantiated;
|
||||
}
|
||||
// 2. const enum declarations don't make module instantiated
|
||||
// 2. const enum declarations
|
||||
else if (isConstEnumDeclaration(node)) {
|
||||
return ModuleInstanceState.ConstEnumOnly;
|
||||
}
|
||||
// 3. non - exported import declarations
|
||||
else if (node.kind === SyntaxKind.ImportDeclaration && !(node.flags & NodeFlags.Export)) {
|
||||
// 3. non-exported import declarations
|
||||
else if ((node.kind === SyntaxKind.ImportDeclaration || node.kind === SyntaxKind.ImportEqualsDeclaration) && !(node.flags & NodeFlags.Export)) {
|
||||
return ModuleInstanceState.NonInstantiated;
|
||||
}
|
||||
// 4. other uninstantiated module declarations.
|
||||
@@ -179,41 +179,39 @@ module ts {
|
||||
}
|
||||
|
||||
function declareModuleMember(node: Declaration, symbolKind: SymbolFlags, symbolExcludes: SymbolFlags) {
|
||||
// Exported module members are given 2 symbols: A local symbol that is classified with an ExportValue,
|
||||
// ExportType, or ExportContainer flag, and an associated export symbol with all the correct flags set
|
||||
// on it. There are 2 main reasons:
|
||||
//
|
||||
// 1. We treat locals and exports of the same name as mutually exclusive within a container.
|
||||
// That means the binder will issue a Duplicate Identifier error if you mix locals and exports
|
||||
// with the same name in the same container.
|
||||
// TODO: Make this a more specific error and decouple it from the exclusion logic.
|
||||
// 2. When we checkIdentifier in the checker, we set its resolved symbol to the local symbol,
|
||||
// but return the export symbol (by calling getExportSymbolOfValueSymbolIfExported). That way
|
||||
// when the emitter comes back to it, it knows not to qualify the name if it was found in a containing scope.
|
||||
var exportKind = 0;
|
||||
if (symbolKind & SymbolFlags.Value) {
|
||||
exportKind |= SymbolFlags.ExportValue;
|
||||
var hasExportModifier = getCombinedNodeFlags(node) & NodeFlags.Export;
|
||||
if (symbolKind & SymbolFlags.Import) {
|
||||
if (node.kind === SyntaxKind.ExportSpecifier || (node.kind === SyntaxKind.ImportEqualsDeclaration && hasExportModifier)) {
|
||||
declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes);
|
||||
}
|
||||
else {
|
||||
declareSymbol(container.locals, undefined, node, symbolKind, symbolExcludes);
|
||||
}
|
||||
}
|
||||
if (symbolKind & SymbolFlags.Type) {
|
||||
exportKind |= SymbolFlags.ExportType;
|
||||
}
|
||||
if (symbolKind & SymbolFlags.Namespace) {
|
||||
exportKind |= SymbolFlags.ExportNamespace;
|
||||
}
|
||||
|
||||
if (getCombinedNodeFlags(node) & NodeFlags.Export || (node.kind !== SyntaxKind.ImportDeclaration && isAmbientContext(container))) {
|
||||
if (exportKind) {
|
||||
else {
|
||||
// Exported module members are given 2 symbols: A local symbol that is classified with an ExportValue,
|
||||
// ExportType, or ExportContainer flag, and an associated export symbol with all the correct flags set
|
||||
// on it. There are 2 main reasons:
|
||||
//
|
||||
// 1. We treat locals and exports of the same name as mutually exclusive within a container.
|
||||
// That means the binder will issue a Duplicate Identifier error if you mix locals and exports
|
||||
// with the same name in the same container.
|
||||
// TODO: Make this a more specific error and decouple it from the exclusion logic.
|
||||
// 2. When we checkIdentifier in the checker, we set its resolved symbol to the local symbol,
|
||||
// but return the export symbol (by calling getExportSymbolOfValueSymbolIfExported). That way
|
||||
// when the emitter comes back to it, it knows not to qualify the name if it was found in a containing scope.
|
||||
if (hasExportModifier || isAmbientContext(container)) {
|
||||
var exportKind = (symbolKind & SymbolFlags.Value ? SymbolFlags.ExportValue : 0) |
|
||||
(symbolKind & SymbolFlags.Type ? SymbolFlags.ExportType : 0) |
|
||||
(symbolKind & SymbolFlags.Namespace ? SymbolFlags.ExportNamespace : 0);
|
||||
var local = declareSymbol(container.locals, undefined, node, exportKind, symbolExcludes);
|
||||
local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes);
|
||||
node.localSymbol = local;
|
||||
}
|
||||
else {
|
||||
declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes);
|
||||
declareSymbol(container.locals, undefined, node, symbolKind, symbolExcludes);
|
||||
}
|
||||
}
|
||||
else {
|
||||
declareSymbol(container.locals, undefined, node, symbolKind, symbolExcludes);
|
||||
}
|
||||
}
|
||||
|
||||
// All container nodes are kept on a linked list in declaration order. This list is used by the getLocalNameOfContainer function
|
||||
@@ -312,6 +310,13 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
function bindExportDeclaration(node: ExportDeclaration) {
|
||||
if (!node.exportClause) {
|
||||
((<ExportContainer>container).exportStars || ((<ExportContainer>container).exportStars = [])).push(node);
|
||||
}
|
||||
bindChildren(node, 0, /*isBlockScopeContainer*/ false);
|
||||
}
|
||||
|
||||
function bindFunctionOrConstructorType(node: SignatureDeclaration) {
|
||||
// For a given function symbol "<...>(...) => T" we want to generate a symbol identical
|
||||
// to the one we would get for: { <...>(...): T }
|
||||
@@ -467,9 +472,23 @@ module ts {
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
bindModuleDeclaration(<ModuleDeclaration>node);
|
||||
break;
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
case SyntaxKind.NamespaceImport:
|
||||
case SyntaxKind.ImportSpecifier:
|
||||
case SyntaxKind.ExportSpecifier:
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.Import, SymbolFlags.ImportExcludes, /*isBlockScopeContainer*/ false);
|
||||
break;
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
bindExportDeclaration(<ExportDeclaration>node);
|
||||
break;
|
||||
case SyntaxKind.ImportClause:
|
||||
if ((<ImportClause>node).name) {
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.Import, SymbolFlags.ImportExcludes, /*isBlockScopeContainer*/ false);
|
||||
}
|
||||
else {
|
||||
bindChildren(node, 0, /*isBlockScopeContainer*/ false);
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.SourceFile:
|
||||
if (isExternalModule(<SourceFile>node)) {
|
||||
bindAnonymousDeclaration(<SourceFile>node, SymbolFlags.ValueModule, '"' + removeFileExtension((<SourceFile>node).fileName) + '"', /*isBlockScopeContainer*/ true);
|
||||
|
||||
+434
-157
@@ -186,7 +186,7 @@ module ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function extendSymbol(target: Symbol, source: Symbol) {
|
||||
function mergeSymbol(target: Symbol, source: Symbol) {
|
||||
if (!(target.flags & getExcludedSymbolFlags(source.flags))) {
|
||||
if (source.flags & SymbolFlags.ValueModule && target.flags & SymbolFlags.ValueModule && target.constEnumOnlyModule && !source.constEnumOnlyModule) {
|
||||
// reset flag when merging instantiated module into value module that has only const enums
|
||||
@@ -199,11 +199,11 @@ module ts {
|
||||
});
|
||||
if (source.members) {
|
||||
if (!target.members) target.members = {};
|
||||
extendSymbolTable(target.members, source.members);
|
||||
mergeSymbolTable(target.members, source.members);
|
||||
}
|
||||
if (source.exports) {
|
||||
if (!target.exports) target.exports = {};
|
||||
extendSymbolTable(target.exports, source.exports);
|
||||
mergeSymbolTable(target.exports, source.exports);
|
||||
}
|
||||
recordMergedSymbol(target, source);
|
||||
}
|
||||
@@ -229,7 +229,7 @@ module ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function extendSymbolTable(target: SymbolTable, source: SymbolTable) {
|
||||
function mergeSymbolTable(target: SymbolTable, source: SymbolTable) {
|
||||
for (var id in source) {
|
||||
if (hasProperty(source, id)) {
|
||||
if (!hasProperty(target, id)) {
|
||||
@@ -240,12 +240,20 @@ module ts {
|
||||
if (!(symbol.flags & SymbolFlags.Merged)) {
|
||||
target[id] = symbol = cloneSymbol(symbol);
|
||||
}
|
||||
extendSymbol(symbol, source[id]);
|
||||
mergeSymbol(symbol, source[id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function extendSymbolTable(target: SymbolTable, source: SymbolTable) {
|
||||
for (var id in source) {
|
||||
if (!hasProperty(target, id)) {
|
||||
target[id] = source[id];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getSymbolLinks(symbol: Symbol): SymbolLinks {
|
||||
if (symbol.flags & SymbolFlags.Transient) return <TransientSymbol>symbol;
|
||||
if (!symbol.id) symbol.id = nextSymbolId++;
|
||||
@@ -323,7 +331,10 @@ module ts {
|
||||
if (!isExternalModule(<SourceFile>location)) break;
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
if (result = getSymbol(getSymbolOfNode(location).exports, name, meaning & SymbolFlags.ModuleMember)) {
|
||||
break loop;
|
||||
if (!(result.flags & SymbolFlags.Import && getDeclarationOfImportSymbol(result).kind === SyntaxKind.ExportSpecifier)) {
|
||||
break loop;
|
||||
}
|
||||
result = undefined;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
@@ -449,22 +460,89 @@ module ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function isImportSymbolDeclaration(node: Node): boolean {
|
||||
return node.kind === SyntaxKind.ImportEqualsDeclaration ||
|
||||
node.kind === SyntaxKind.ImportClause && !!(<ImportClause>node).name ||
|
||||
node.kind === SyntaxKind.NamespaceImport ||
|
||||
node.kind === SyntaxKind.ImportSpecifier ||
|
||||
node.kind === SyntaxKind.ExportSpecifier;
|
||||
}
|
||||
|
||||
function getDeclarationOfImportSymbol(symbol: Symbol): Declaration {
|
||||
return forEach(symbol.declarations, d => isImportSymbolDeclaration(d) ? d : undefined);
|
||||
}
|
||||
|
||||
function getTargetOfImportEqualsDeclaration(node: ImportEqualsDeclaration): Symbol {
|
||||
if (node.moduleReference.kind === SyntaxKind.ExternalModuleReference) {
|
||||
var moduleSymbol = resolveExternalModuleName(node, getExternalModuleImportEqualsDeclarationExpression(node));
|
||||
var exportAssignmentSymbol = moduleSymbol && getResolvedExportAssignmentSymbol(moduleSymbol);
|
||||
return exportAssignmentSymbol || moduleSymbol;
|
||||
}
|
||||
return getSymbolOfPartOfRightHandSideOfImportEquals(<EntityName>node.moduleReference, node);
|
||||
}
|
||||
|
||||
function getTargetOfImportClause(node: ImportClause): Symbol {
|
||||
var moduleSymbol = resolveExternalModuleName(node, (<ImportDeclaration>node.parent).moduleSpecifier);
|
||||
if (moduleSymbol) {
|
||||
var exportAssignmentSymbol = getResolvedExportAssignmentSymbol(moduleSymbol);
|
||||
if (!exportAssignmentSymbol) {
|
||||
error(node.name, Diagnostics.External_module_0_has_no_default_export_or_export_assignment, symbolToString(moduleSymbol));
|
||||
}
|
||||
return exportAssignmentSymbol;
|
||||
}
|
||||
}
|
||||
|
||||
function getTargetOfNamespaceImport(node: NamespaceImport): Symbol {
|
||||
return resolveExternalModuleName(node, (<ImportDeclaration>node.parent.parent).moduleSpecifier);
|
||||
}
|
||||
|
||||
function getExternalModuleMember(node: ImportDeclaration | ExportDeclaration, specifier: ImportOrExportSpecifier): Symbol {
|
||||
var moduleSymbol = resolveExternalModuleName(node, node.moduleSpecifier);
|
||||
if (moduleSymbol) {
|
||||
var name = specifier.propertyName || specifier.name;
|
||||
if (name.text) {
|
||||
var symbol = getSymbol(getExportsOfSymbol(moduleSymbol), name.text, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace);
|
||||
if (!symbol) {
|
||||
error(name, Diagnostics.Module_0_has_no_exported_member_1, getFullyQualifiedName(moduleSymbol), declarationNameToString(name));
|
||||
return;
|
||||
}
|
||||
return symbol.flags & (SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace) ? symbol : resolveImport(symbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getTargetOfImportSpecifier(node: ImportSpecifier): Symbol {
|
||||
return getExternalModuleMember(<ImportDeclaration>node.parent.parent.parent, node);
|
||||
}
|
||||
|
||||
function getTargetOfExportSpecifier(node: ExportSpecifier): Symbol {
|
||||
return (<ExportDeclaration>node.parent.parent).moduleSpecifier ?
|
||||
getExternalModuleMember(<ExportDeclaration>node.parent.parent, node) :
|
||||
resolveEntityName(node, node.propertyName || node.name, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace);
|
||||
}
|
||||
|
||||
function getTargetOfImportDeclaration(node: Declaration): Symbol {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
return getTargetOfImportEqualsDeclaration(<ImportEqualsDeclaration>node);
|
||||
case SyntaxKind.ImportClause:
|
||||
return getTargetOfImportClause(<ImportClause>node);
|
||||
case SyntaxKind.NamespaceImport:
|
||||
return getTargetOfNamespaceImport(<NamespaceImport>node);
|
||||
case SyntaxKind.ImportSpecifier:
|
||||
return getTargetOfImportSpecifier(<ImportSpecifier>node);
|
||||
case SyntaxKind.ExportSpecifier:
|
||||
return getTargetOfExportSpecifier(<ExportSpecifier>node);
|
||||
}
|
||||
}
|
||||
|
||||
function resolveImport(symbol: Symbol): Symbol {
|
||||
Debug.assert((symbol.flags & SymbolFlags.Import) !== 0, "Should only get Imports here.");
|
||||
var links = getSymbolLinks(symbol);
|
||||
if (!links.target) {
|
||||
links.target = resolvingSymbol;
|
||||
var node = <ImportDeclaration>getDeclarationOfKind(symbol, SyntaxKind.ImportDeclaration);
|
||||
// Grammar checking
|
||||
if (node.moduleReference.kind === SyntaxKind.ExternalModuleReference) {
|
||||
if ((<ExternalModuleReference>node.moduleReference).expression.kind !== SyntaxKind.StringLiteral) {
|
||||
grammarErrorOnNode((<ExternalModuleReference>node.moduleReference).expression, Diagnostics.String_literal_expected);
|
||||
}
|
||||
}
|
||||
|
||||
var target = node.moduleReference.kind === SyntaxKind.ExternalModuleReference
|
||||
? resolveExternalModuleName(node, getExternalModuleImportDeclarationExpression(node))
|
||||
: getSymbolOfPartOfRightHandSideOfImport(<EntityName>node.moduleReference, node);
|
||||
var node = getDeclarationOfImportSymbol(symbol);
|
||||
var target = getTargetOfImportDeclaration(node);
|
||||
if (links.target === resolvingSymbol) {
|
||||
links.target = target || unknownSymbol;
|
||||
}
|
||||
@@ -479,9 +557,9 @@ module ts {
|
||||
}
|
||||
|
||||
// This function is only for imports with entity names
|
||||
function getSymbolOfPartOfRightHandSideOfImport(entityName: EntityName, importDeclaration?: ImportDeclaration): Symbol {
|
||||
function getSymbolOfPartOfRightHandSideOfImportEquals(entityName: EntityName, importDeclaration?: ImportEqualsDeclaration): Symbol {
|
||||
if (!importDeclaration) {
|
||||
importDeclaration = <ImportDeclaration>getAncestor(entityName, SyntaxKind.ImportDeclaration);
|
||||
importDeclaration = <ImportEqualsDeclaration>getAncestor(entityName, SyntaxKind.ImportEqualsDeclaration);
|
||||
Debug.assert(importDeclaration !== undefined);
|
||||
}
|
||||
// There are three things we might try to look for. In the following examples,
|
||||
@@ -500,7 +578,7 @@ module ts {
|
||||
else {
|
||||
// Case 2 in above example
|
||||
// entityName.kind could be a QualifiedName or a Missing identifier
|
||||
Debug.assert(entityName.parent.kind === SyntaxKind.ImportDeclaration);
|
||||
Debug.assert(entityName.parent.kind === SyntaxKind.ImportEqualsDeclaration);
|
||||
return resolveEntityName(importDeclaration, entityName, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace);
|
||||
}
|
||||
}
|
||||
@@ -524,7 +602,7 @@ module ts {
|
||||
else if (name.kind === SyntaxKind.QualifiedName) {
|
||||
var namespace = resolveEntityName(location,(<QualifiedName>name).left, SymbolFlags.Namespace);
|
||||
if (!namespace || namespace === unknownSymbol || getFullWidth((<QualifiedName>name).right) === 0) return;
|
||||
var symbol = getSymbol(namespace.exports,(<QualifiedName>name).right.text, meaning);
|
||||
var symbol = getSymbol(getExportsOfSymbol(namespace), (<QualifiedName>name).right.text, meaning);
|
||||
if (!symbol) {
|
||||
error(location, Diagnostics.Module_0_has_no_exported_member_1, getFullyQualifiedName(namespace),
|
||||
declarationNameToString((<QualifiedName>name).right));
|
||||
@@ -559,7 +637,7 @@ module ts {
|
||||
if (!isRelative) {
|
||||
var symbol = getSymbol(globals, '"' + moduleName + '"', SymbolFlags.ValueModule);
|
||||
if (symbol) {
|
||||
return getResolvedExportSymbol(symbol);
|
||||
return symbol;
|
||||
}
|
||||
}
|
||||
while (true) {
|
||||
@@ -572,7 +650,7 @@ module ts {
|
||||
}
|
||||
if (sourceFile) {
|
||||
if (sourceFile.symbol) {
|
||||
return getResolvedExportSymbol(sourceFile.symbol);
|
||||
return sourceFile.symbol;
|
||||
}
|
||||
error(moduleReferenceLiteral, Diagnostics.File_0_is_not_an_external_module, sourceFile.fileName);
|
||||
return;
|
||||
@@ -580,7 +658,7 @@ module ts {
|
||||
error(moduleReferenceLiteral, Diagnostics.Cannot_find_external_module_0, moduleName);
|
||||
}
|
||||
|
||||
function getResolvedExportSymbol(moduleSymbol: Symbol): Symbol {
|
||||
function getResolvedExportAssignmentSymbol(moduleSymbol: Symbol): Symbol {
|
||||
var symbol = getExportAssignmentSymbol(moduleSymbol);
|
||||
if (symbol) {
|
||||
if (symbol.flags & (SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace)) {
|
||||
@@ -590,18 +668,16 @@ module ts {
|
||||
return resolveImport(symbol);
|
||||
}
|
||||
}
|
||||
return moduleSymbol;
|
||||
}
|
||||
|
||||
function getExportAssignmentSymbol(symbol: Symbol): Symbol {
|
||||
checkTypeOfExportAssignmentSymbol(symbol);
|
||||
var symbolLinks = getSymbolLinks(symbol);
|
||||
return symbolLinks.exportAssignSymbol === unknownSymbol ? undefined : symbolLinks.exportAssignSymbol;
|
||||
return getSymbolLinks(symbol).exportAssignmentSymbol;
|
||||
}
|
||||
|
||||
function checkTypeOfExportAssignmentSymbol(containerSymbol: Symbol): void {
|
||||
var symbolLinks = getSymbolLinks(containerSymbol);
|
||||
if (!symbolLinks.exportAssignSymbol) {
|
||||
if (!symbolLinks.exportAssignmentChecked) {
|
||||
var exportInformation = collectExportInformationForSourceFileOrModule(containerSymbol);
|
||||
if (exportInformation.exportAssignments.length) {
|
||||
if (exportInformation.exportAssignments.length > 1) {
|
||||
@@ -621,8 +697,9 @@ module ts {
|
||||
var meaning = SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace;
|
||||
var exportSymbol = resolveName(node, node.exportName.text, meaning, Diagnostics.Cannot_find_name_0, node.exportName);
|
||||
}
|
||||
symbolLinks.exportAssignmentSymbol = exportSymbol || unknownSymbol;
|
||||
}
|
||||
symbolLinks.exportAssignSymbol = exportSymbol || unknownSymbol;
|
||||
symbolLinks.exportAssignmentChecked = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -646,6 +723,41 @@ module ts {
|
||||
};
|
||||
}
|
||||
|
||||
function getExportsOfSymbol(symbol: Symbol): SymbolTable {
|
||||
return symbol.flags & SymbolFlags.Module ? getExportsOfModule(symbol) : symbol.exports;
|
||||
}
|
||||
|
||||
function getExportsOfModule(symbol: Symbol): SymbolTable {
|
||||
var links = getSymbolLinks(symbol);
|
||||
return links.resolvedExports || (links.resolvedExports = getExportsForModule(symbol));
|
||||
}
|
||||
|
||||
function getExportsForModule(symbol: Symbol): SymbolTable {
|
||||
var result: SymbolTable;
|
||||
var visitedSymbols: Symbol[] = [];
|
||||
visit(symbol);
|
||||
return result;
|
||||
|
||||
function visit(symbol: Symbol) {
|
||||
if (!contains(visitedSymbols, symbol)) {
|
||||
visitedSymbols.push(symbol);
|
||||
if (!result) {
|
||||
result = symbol.exports;
|
||||
}
|
||||
else {
|
||||
extendSymbolTable(result, symbol.exports);
|
||||
}
|
||||
forEach(symbol.declarations, node => {
|
||||
if (node.kind === SyntaxKind.SourceFile || node.kind === SyntaxKind.ModuleDeclaration) {
|
||||
forEach((<ExportContainer>node).exportStars, exportStar => {
|
||||
visit(resolveExternalModuleName(exportStar, exportStar.moduleSpecifier));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getMergedSymbol(symbol: Symbol): Symbol {
|
||||
var merged: Symbol;
|
||||
return symbol && symbol.mergeId && (merged = mergedSymbols[symbol.mergeId]) ? merged : symbol;
|
||||
@@ -824,7 +936,7 @@ module ts {
|
||||
if (symbolFromSymbolTable.flags & SymbolFlags.Import) {
|
||||
if (!useOnlyExternalAliasing || // We can use any type of alias to get the name
|
||||
// Is this external alias, then use it to name
|
||||
ts.forEach(symbolFromSymbolTable.declarations, isExternalModuleImportDeclaration)) {
|
||||
ts.forEach(symbolFromSymbolTable.declarations, isExternalModuleImportEqualsDeclaration)) {
|
||||
|
||||
var resolvedImportedSymbol = resolveImport(symbolFromSymbolTable);
|
||||
if (isAccessible(symbolFromSymbolTable, resolveImport(symbolFromSymbolTable))) {
|
||||
@@ -950,7 +1062,7 @@ module ts {
|
||||
}
|
||||
|
||||
function hasVisibleDeclarations(symbol: Symbol): SymbolVisibilityResult {
|
||||
var aliasesToMakeVisible: ImportDeclaration[];
|
||||
var aliasesToMakeVisible: ImportEqualsDeclaration[];
|
||||
if (forEach(symbol.declarations, declaration => !getIsDeclarationVisible(declaration))) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -960,17 +1072,17 @@ module ts {
|
||||
if (!isDeclarationVisible(declaration)) {
|
||||
// Mark the unexported alias as visible if its parent is visible
|
||||
// because these kind of aliases can be used to name types in declaration file
|
||||
if (declaration.kind === SyntaxKind.ImportDeclaration &&
|
||||
if (declaration.kind === SyntaxKind.ImportEqualsDeclaration &&
|
||||
!(declaration.flags & NodeFlags.Export) &&
|
||||
isDeclarationVisible(<Declaration>declaration.parent)) {
|
||||
getNodeLinks(declaration).isVisible = true;
|
||||
if (aliasesToMakeVisible) {
|
||||
if (!contains(aliasesToMakeVisible, declaration)) {
|
||||
aliasesToMakeVisible.push(<ImportDeclaration>declaration);
|
||||
aliasesToMakeVisible.push(<ImportEqualsDeclaration>declaration);
|
||||
}
|
||||
}
|
||||
else {
|
||||
aliasesToMakeVisible = [<ImportDeclaration>declaration];
|
||||
aliasesToMakeVisible = [<ImportEqualsDeclaration>declaration];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -991,7 +1103,7 @@ module ts {
|
||||
meaning = SymbolFlags.Value | SymbolFlags.ExportValue;
|
||||
}
|
||||
else if (entityName.kind === SyntaxKind.QualifiedName ||
|
||||
entityName.parent.kind === SyntaxKind.ImportDeclaration) {
|
||||
entityName.parent.kind === SyntaxKind.ImportEqualsDeclaration) {
|
||||
// Left identifier from type reference or TypeAlias
|
||||
// Entity name of the import declaration
|
||||
meaning = SymbolFlags.Namespace;
|
||||
@@ -1602,11 +1714,11 @@ module ts {
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
var parent = getDeclarationContainer(node);
|
||||
// If the node is not exported or it is not ambient module element (except import declaration)
|
||||
if (!(getCombinedNodeFlags(node) & NodeFlags.Export) &&
|
||||
!(node.kind !== SyntaxKind.ImportDeclaration && parent.kind !== SyntaxKind.SourceFile && isInAmbientContext(parent))) {
|
||||
!(node.kind !== SyntaxKind.ImportEqualsDeclaration && parent.kind !== SyntaxKind.SourceFile && isInAmbientContext(parent))) {
|
||||
return isGlobalSourceFile(parent) || isUsedInExportAssignment(node);
|
||||
}
|
||||
// Exported members/ambient module elements (exception import declaration) are visible if parent is visible
|
||||
@@ -2419,7 +2531,7 @@ module ts {
|
||||
var callSignatures: Signature[] = emptyArray;
|
||||
var constructSignatures: Signature[] = emptyArray;
|
||||
if (symbol.flags & SymbolFlags.HasExports) {
|
||||
members = symbol.exports;
|
||||
members = getExportsOfSymbol(symbol);
|
||||
}
|
||||
if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method)) {
|
||||
callSignatures = getSignaturesOfSymbol(symbol);
|
||||
@@ -4885,16 +4997,18 @@ module ts {
|
||||
}
|
||||
|
||||
/*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;
|
||||
function markLinkedImportsAsReferenced(node: ImportEqualsDeclaration): void {
|
||||
if (node) {
|
||||
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);
|
||||
getSymbolLinks(rightSide).referenced = true;
|
||||
Debug.assert((rightSide.flags & SymbolFlags.Import) !== 0);
|
||||
|
||||
nodeLinks = getNodeLinks(getDeclarationOfKind(rightSide, SyntaxKind.ImportDeclaration))
|
||||
nodeLinks = getNodeLinks(getDeclarationOfKind(rightSide, SyntaxKind.ImportEqualsDeclaration))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4908,13 +5022,25 @@ module ts {
|
||||
// To avoid that we will give an error to users if they use arguments objects in arrow function so that they
|
||||
// can explicitly bound arguments objects
|
||||
if (symbol === argumentsSymbol && getContainingFunction(node).kind === SyntaxKind.ArrowFunction) {
|
||||
error(node, Diagnostics.The_arguments_object_cannot_be_referenced_in_an_arrow_function_Consider_using_a_standard_function_expression);
|
||||
error(node, Diagnostics.The_arguments_object_cannot_be_referenced_in_an_arrow_function_Consider_using_a_standard_function_expression);
|
||||
}
|
||||
|
||||
if (symbol.flags & SymbolFlags.Import) {
|
||||
|
||||
//var symbolLinks = getSymbolLinks(symbol);
|
||||
//if (!symbolLinks.referenced) {
|
||||
// if (!isInTypeQuery(node) && !isConstEnumOrConstEnumOnlyModule(resolveImport(symbol))) {
|
||||
// symbolLinks.referenced = true;
|
||||
// }
|
||||
//}
|
||||
|
||||
// TODO: AndersH: This needs to be simplified. In an import of the form "import x = a.b.c;" we only need
|
||||
// to resolve "a" and mark it as referenced. If "b" and/or "c" are aliases, we would be able to access them
|
||||
// unless they're exported, and in that case they're already implicitly referenced.
|
||||
|
||||
var symbolLinks = getSymbolLinks(symbol);
|
||||
if (!symbolLinks.referenced) {
|
||||
var importOrExportAssignment = getLeftSideOfImportOrExportAssignment(node);
|
||||
var importOrExportAssignment = getLeftSideOfImportEqualsOrExportAssignment(node);
|
||||
|
||||
// decision about whether import is referenced can be made now if
|
||||
// - import that are used anywhere except right side of import declarations
|
||||
@@ -4935,7 +5061,7 @@ module ts {
|
||||
}
|
||||
|
||||
if (symbolLinks.referenced) {
|
||||
markLinkedImportsAsReferenced(<ImportDeclaration>getDeclarationOfKind(symbol, SyntaxKind.ImportDeclaration));
|
||||
markLinkedImportsAsReferenced(<ImportEqualsDeclaration>getDeclarationOfKind(symbol, SyntaxKind.ImportEqualsDeclaration));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8170,7 +8296,7 @@ module ts {
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
return SymbolFlags.ExportType | SymbolFlags.ExportValue;
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
var result: SymbolFlags = 0;
|
||||
var target = resolveImport(getSymbolOfNode(d));
|
||||
forEach(target.declarations, d => { result |= getDeclarationSpaces(d); });
|
||||
@@ -9416,13 +9542,12 @@ module ts {
|
||||
for (var i = 0, n = statements.length; i < n; i++) {
|
||||
var statement = statements[i];
|
||||
|
||||
// TODO: AndersH: No reason to do a separate pass over the statements for this check, we should
|
||||
// just fold it into checkExportAssignment.
|
||||
if (statement.kind === SyntaxKind.ExportAssignment) {
|
||||
// Export assignments are not allowed in an internal module
|
||||
grammarErrorOnNode(statement, Diagnostics.An_export_assignment_cannot_be_used_in_an_internal_module);
|
||||
}
|
||||
else if (isExternalModuleImportDeclaration(statement)) {
|
||||
grammarErrorOnNode(getExternalModuleImportDeclarationExpression(statement), Diagnostics.Import_declarations_in_an_internal_module_cannot_reference_an_external_module);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9468,18 +9593,81 @@ module ts {
|
||||
return <Identifier>node;
|
||||
}
|
||||
|
||||
function checkImportDeclaration(node: ImportDeclaration) {
|
||||
// Grammar checking
|
||||
checkGrammarModifiers(node);
|
||||
function checkExternalImportOrExportDeclaration(node: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration): boolean {
|
||||
var moduleName = getExternalModuleName(node);
|
||||
if (getFullWidth(moduleName) !== 0 && moduleName.kind !== SyntaxKind.StringLiteral) {
|
||||
error(moduleName, Diagnostics.String_literal_expected);
|
||||
return false;
|
||||
}
|
||||
var inAmbientExternalModule = node.parent.kind === SyntaxKind.ModuleBlock && (<ModuleDeclaration>node.parent.parent).name.kind === SyntaxKind.StringLiteral;
|
||||
if (node.parent.kind !== SyntaxKind.SourceFile && !inAmbientExternalModule) {
|
||||
error(moduleName, node.kind === SyntaxKind.ExportDeclaration ?
|
||||
Diagnostics.Export_declarations_are_not_permitted_in_an_internal_module :
|
||||
Diagnostics.Import_declarations_in_an_internal_module_cannot_reference_an_external_module);
|
||||
return false;
|
||||
}
|
||||
if (inAmbientExternalModule && isExternalModuleNameRelative((<LiteralExpression>moduleName).text)) {
|
||||
// TypeScript 1.0 spec (April 2013): 12.1.6
|
||||
// An ExternalImportDeclaration in an AmbientExternalModuleDeclaration may reference
|
||||
// other external modules only through top - level external module names.
|
||||
// Relative external module names are not permitted.
|
||||
error(node, Diagnostics.Import_or_export_declaration_in_an_ambient_external_module_declaration_cannot_reference_external_module_through_relative_external_module_name);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function checkImportSymbol(node: ImportEqualsDeclaration | ImportClause | NamespaceImport | ImportSpecifier | ExportSpecifier) {
|
||||
var symbol = getSymbolOfNode(node);
|
||||
var target = resolveImport(symbol);
|
||||
if (target !== unknownSymbol) {
|
||||
var excludedMeanings =
|
||||
(symbol.flags & SymbolFlags.Value ? SymbolFlags.Value : 0) |
|
||||
(symbol.flags & SymbolFlags.Type ? SymbolFlags.Type : 0) |
|
||||
(symbol.flags & SymbolFlags.Namespace ? SymbolFlags.Namespace : 0);
|
||||
if (target.flags & excludedMeanings) {
|
||||
var message = node.kind === SyntaxKind.ExportSpecifier ?
|
||||
Diagnostics.Export_declaration_conflicts_with_exported_declaration_of_0 :
|
||||
Diagnostics.Import_declaration_conflicts_with_local_declaration_of_0;
|
||||
error(node, message, symbolToString(symbol));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkImportBinding(node: ImportEqualsDeclaration | ImportClause | NamespaceImport | ImportSpecifier) {
|
||||
checkCollisionWithCapturedThisVariable(node, node.name);
|
||||
checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
|
||||
var symbol = getSymbolOfNode(node);
|
||||
var target: Symbol;
|
||||
|
||||
if (isInternalModuleImportDeclaration(node)) {
|
||||
target = resolveImport(symbol);
|
||||
// Import declaration for an internal module
|
||||
checkImportSymbol(node);
|
||||
}
|
||||
|
||||
function checkImportDeclaration(node: ImportDeclaration) {
|
||||
if (!checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) {
|
||||
grammarErrorOnFirstToken(node, Diagnostics.An_import_declaration_cannot_have_modifiers);
|
||||
}
|
||||
if (checkExternalImportOrExportDeclaration(node)) {
|
||||
var importClause = node.importClause;
|
||||
if (importClause) {
|
||||
if (importClause.name) {
|
||||
checkImportBinding(importClause);
|
||||
}
|
||||
if (importClause.namedBindings) {
|
||||
if (importClause.namedBindings.kind === SyntaxKind.NamespaceImport) {
|
||||
checkImportBinding(<NamespaceImport>importClause.namedBindings);
|
||||
}
|
||||
else {
|
||||
forEach((<NamedImports>importClause.namedBindings).elements, checkImportBinding);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkImportEqualsDeclaration(node: ImportEqualsDeclaration) {
|
||||
checkGrammarModifiers(node);
|
||||
if (isInternalModuleImportEqualsDeclaration(node)) {
|
||||
checkImportBinding(node);
|
||||
var symbol = getSymbolOfNode(node);
|
||||
var target = resolveImport(symbol);
|
||||
if (target !== unknownSymbol) {
|
||||
if (target.flags & SymbolFlags.Value) {
|
||||
// Target is a value symbol, check that it is not hidden by a local declaration with the same name and
|
||||
@@ -9498,40 +9686,19 @@ module ts {
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Import declaration for an external module
|
||||
if (node.parent.kind === SyntaxKind.SourceFile) {
|
||||
target = resolveImport(symbol);
|
||||
}
|
||||
else if (node.parent.kind === SyntaxKind.ModuleBlock && (<ModuleDeclaration>node.parent.parent).name.kind === SyntaxKind.StringLiteral) {
|
||||
// TypeScript 1.0 spec (April 2013): 12.1.6
|
||||
// An ExternalImportDeclaration in an AmbientExternalModuleDeclaration may reference
|
||||
// other external modules only through top - level external module names.
|
||||
// Relative external module names are not permitted.
|
||||
if (getExternalModuleImportDeclarationExpression(node).kind === SyntaxKind.StringLiteral) {
|
||||
if (isExternalModuleNameRelative((<LiteralExpression>getExternalModuleImportDeclarationExpression(node)).text)) {
|
||||
error(node, Diagnostics.Import_declaration_in_an_ambient_external_module_declaration_cannot_reference_external_module_through_relative_external_module_name);
|
||||
target = unknownSymbol;
|
||||
}
|
||||
else {
|
||||
target = resolveImport(symbol);
|
||||
}
|
||||
}
|
||||
else {
|
||||
target = unknownSymbol;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Parent is an internal module (syntax error is already reported)
|
||||
target = unknownSymbol;
|
||||
if (checkExternalImportOrExportDeclaration(node)) {
|
||||
checkImportBinding(node);
|
||||
}
|
||||
}
|
||||
if (target !== unknownSymbol) {
|
||||
var excludedMeanings =
|
||||
(symbol.flags & SymbolFlags.Value ? SymbolFlags.Value : 0) |
|
||||
(symbol.flags & SymbolFlags.Type ? SymbolFlags.Type : 0) |
|
||||
(symbol.flags & SymbolFlags.Namespace ? SymbolFlags.Namespace : 0);
|
||||
if (target.flags & excludedMeanings) {
|
||||
error(node, Diagnostics.Import_declaration_conflicts_with_local_declaration_of_0, symbolToString(symbol));
|
||||
}
|
||||
|
||||
function checkExportDeclaration(node: ExportDeclaration) {
|
||||
if (!checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) {
|
||||
grammarErrorOnFirstToken(node, Diagnostics.An_export_declaration_cannot_have_modifiers);
|
||||
}
|
||||
if (!node.moduleSpecifier || checkExternalImportOrExportDeclaration(node)) {
|
||||
if (node.exportClause) {
|
||||
forEach(node.exportClause.elements, checkImportSymbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9641,6 +9808,10 @@ module ts {
|
||||
return checkModuleDeclaration(<ModuleDeclaration>node);
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
return checkImportDeclaration(<ImportDeclaration>node);
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
return checkImportEqualsDeclaration(<ImportEqualsDeclaration>node);
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
return checkExportDeclaration(<ExportDeclaration>node);
|
||||
case SyntaxKind.ExportAssignment:
|
||||
return checkExportAssignment(<ExportAssignment>node);
|
||||
case SyntaxKind.EmptyStatement:
|
||||
@@ -9766,7 +9937,7 @@ module ts {
|
||||
// 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))
|
||||
markLinkedImportsAsReferenced(<ImportEqualsDeclaration>getDeclarationOfKind(symbol, SyntaxKind.ImportEqualsDeclaration))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9984,13 +10155,13 @@ module ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
function getLeftSideOfImportOrExportAssignment(nodeOnRightSide: EntityName): ImportDeclaration | ExportAssignment {
|
||||
function getLeftSideOfImportEqualsOrExportAssignment(nodeOnRightSide: EntityName): ImportEqualsDeclaration | 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.ImportEqualsDeclaration) {
|
||||
return (<ImportEqualsDeclaration>nodeOnRightSide.parent).moduleReference === nodeOnRightSide && <ImportEqualsDeclaration>nodeOnRightSide.parent;
|
||||
}
|
||||
|
||||
if (nodeOnRightSide.parent.kind === SyntaxKind.ExportAssignment) {
|
||||
@@ -10001,7 +10172,7 @@ module ts {
|
||||
}
|
||||
|
||||
function isInRightSideOfImportOrExportAssignment(node: EntityName) {
|
||||
return getLeftSideOfImportOrExportAssignment(node) !== undefined;
|
||||
return getLeftSideOfImportEqualsOrExportAssignment(node) !== undefined;
|
||||
}
|
||||
|
||||
function isRightSideOfQualifiedNameOrPropertyAccess(node: Node) {
|
||||
@@ -10022,7 +10193,7 @@ module ts {
|
||||
if (entityName.kind !== SyntaxKind.PropertyAccessExpression) {
|
||||
if (isInRightSideOfImportOrExportAssignment(<EntityName>entityName)) {
|
||||
// Since we already checked for ExportAssignment, this really could only be an Import
|
||||
return getSymbolOfPartOfRightHandSideOfImport(<EntityName>entityName);
|
||||
return getSymbolOfPartOfRightHandSideOfImportEquals(<EntityName>entityName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10083,7 +10254,7 @@ module ts {
|
||||
if (node.kind === SyntaxKind.Identifier && isInRightSideOfImportOrExportAssignment(<Identifier>node)) {
|
||||
return node.parent.kind === SyntaxKind.ExportAssignment
|
||||
? getSymbolOfEntityNameOrPropertyAccessExpression(<Identifier>node)
|
||||
: getSymbolOfPartOfRightHandSideOfImport(<Identifier>node);
|
||||
: getSymbolOfPartOfRightHandSideOfImportEquals(<Identifier>node);
|
||||
}
|
||||
|
||||
switch (node.kind) {
|
||||
@@ -10107,8 +10278,8 @@ module ts {
|
||||
|
||||
case SyntaxKind.StringLiteral:
|
||||
// External module name in an import declaration
|
||||
if (isExternalModuleImportDeclaration(node.parent.parent) &&
|
||||
getExternalModuleImportDeclarationExpression(node.parent.parent) === node) {
|
||||
if (isExternalModuleImportEqualsDeclaration(node.parent.parent) &&
|
||||
getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node) {
|
||||
var importSymbol = getSymbolOfNode(node.parent.parent);
|
||||
var moduleType = getTypeOfSymbol(importSymbol);
|
||||
return moduleType ? moduleType.symbol : undefined;
|
||||
@@ -10241,73 +10412,172 @@ module ts {
|
||||
function isUniqueLocalName(name: string, container: Node): boolean {
|
||||
for (var node = container; isNodeDescendentOf(node, container); node = node.nextContainer) {
|
||||
if (node.locals && hasProperty(node.locals, name)) {
|
||||
var symbolWithRelevantName = node.locals[name];
|
||||
if (symbolWithRelevantName.flags & (SymbolFlags.Value | SymbolFlags.ExportValue)) {
|
||||
// We conservatively include import symbols to cover cases where they're emitted as locals
|
||||
if (node.locals[name].flags & (SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Import)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// An import can be emitted too, if it is referenced as a value.
|
||||
// Make sure the name in question does not collide with an import.
|
||||
if (symbolWithRelevantName.flags & SymbolFlags.Import) {
|
||||
var importDeclarationWithRelevantName = <ImportDeclaration>getDeclarationOfKind(symbolWithRelevantName, SyntaxKind.ImportDeclaration);
|
||||
if (isReferencedImportDeclaration(importDeclarationWithRelevantName)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function getLocalNameOfContainer(container: ModuleDeclaration | EnumDeclaration): string {
|
||||
var links = getNodeLinks(container);
|
||||
if (!links.localModuleName) {
|
||||
var prefix = "";
|
||||
var name = unescapeIdentifier(container.name.text);
|
||||
while (!isUniqueLocalName(escapeIdentifier(prefix + name), container)) {
|
||||
prefix += "_";
|
||||
}
|
||||
links.localModuleName = prefix + getTextOfNode(container.name);
|
||||
function getGeneratedNamesForSourceFile(sourceFile: SourceFile): Map<string> {
|
||||
var links = getNodeLinks(sourceFile);
|
||||
var generatedNames = links.generatedNames;
|
||||
if (!generatedNames) {
|
||||
generatedNames = links.generatedNames = {};
|
||||
generateNames(sourceFile);
|
||||
}
|
||||
return generatedNames;
|
||||
|
||||
function generateNames(node: Node) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
generateNameForModuleOrEnum(<ModuleDeclaration>node);
|
||||
generateNames((<ModuleDeclaration>node).body);
|
||||
break;
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
generateNameForModuleOrEnum(<EnumDeclaration>node);
|
||||
break;
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
generateNameForImportDeclaration(<ImportDeclaration>node);
|
||||
break;
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
generateNameForExportDeclaration(<ExportDeclaration>node);
|
||||
break;
|
||||
case SyntaxKind.SourceFile:
|
||||
case SyntaxKind.ModuleBlock:
|
||||
forEach((<SourceFile | ModuleBlock>node).statements, generateNames);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function isExistingName(name: string) {
|
||||
return hasProperty(globals, name) || hasProperty(sourceFile.identifiers, name) || hasProperty(generatedNames, name);
|
||||
}
|
||||
|
||||
function makeUniqueName(baseName: string): string {
|
||||
// First try '_name'
|
||||
if (baseName.charCodeAt(0) !== CharacterCodes._) {
|
||||
var baseName = "_" + baseName;
|
||||
if (!isExistingName(baseName)) {
|
||||
return generatedNames[baseName] = baseName;
|
||||
}
|
||||
}
|
||||
// Find the first unique '_name_n', where n is a positive number
|
||||
if (baseName.charCodeAt(baseName.length - 1) !== CharacterCodes._) {
|
||||
baseName += "_";
|
||||
}
|
||||
var i = 1;
|
||||
while (true) {
|
||||
name = baseName + i;
|
||||
if (!isExistingName(name)) {
|
||||
return generatedNames[name] = name;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
function assignGeneratedName(node: Node, name: string) {
|
||||
getNodeLinks(node).generatedName = unescapeIdentifier(name);
|
||||
}
|
||||
|
||||
function generateNameForModuleOrEnum(node: ModuleDeclaration | EnumDeclaration) {
|
||||
if (node.name.kind === SyntaxKind.Identifier) {
|
||||
var name = node.name.text;
|
||||
// Use module/enum name itself if it is unique, otherwise make a unique variation
|
||||
assignGeneratedName(node, isUniqueLocalName(name, node) ? name : makeUniqueName(name));
|
||||
}
|
||||
}
|
||||
|
||||
function generateNameForImportOrExportDeclaration(node: ImportDeclaration | ExportDeclaration) {
|
||||
var expr = getExternalModuleName(node);
|
||||
var baseName = expr.kind === SyntaxKind.StringLiteral ?
|
||||
escapeIdentifier(makeIdentifierFromModuleName((<LiteralExpression>expr).text)) : "module";
|
||||
assignGeneratedName(node, makeUniqueName(baseName));
|
||||
}
|
||||
|
||||
function generateNameForImportDeclaration(node: ImportDeclaration) {
|
||||
if (node.importClause && node.importClause.namedBindings && node.importClause.namedBindings.kind === SyntaxKind.NamedImports) {
|
||||
generateNameForImportOrExportDeclaration(node);
|
||||
}
|
||||
}
|
||||
|
||||
function generateNameForExportDeclaration(node: ExportDeclaration) {
|
||||
if (node.moduleSpecifier) {
|
||||
generateNameForImportOrExportDeclaration(node);
|
||||
}
|
||||
}
|
||||
return links.localModuleName;
|
||||
}
|
||||
|
||||
function getLocalNameForSymbol(symbol: Symbol, location: Node): string {
|
||||
function getGeneratedNameForNode(node: ModuleDeclaration | EnumDeclaration | ImportDeclaration | ExportDeclaration) {
|
||||
var links = getNodeLinks(node);
|
||||
if (!links.generatedName) {
|
||||
getGeneratedNamesForSourceFile(getSourceFile(node));
|
||||
}
|
||||
return links.generatedName;
|
||||
}
|
||||
|
||||
function getLocalNameOfContainer(container: ModuleDeclaration | EnumDeclaration): string {
|
||||
return getGeneratedNameForNode(container);
|
||||
}
|
||||
|
||||
function getLocalNameForImportDeclaration(node: ImportDeclaration): string {
|
||||
return getGeneratedNameForNode(node);
|
||||
}
|
||||
|
||||
function getImportNameSubstitution(symbol: Symbol): string {
|
||||
var declaration = getDeclarationOfImportSymbol(symbol);
|
||||
if (declaration && declaration.kind === SyntaxKind.ImportSpecifier) {
|
||||
var moduleName = getGeneratedNameForNode(<ImportDeclaration>declaration.parent.parent.parent);
|
||||
var propertyName = (<ImportSpecifier>declaration).propertyName || (<ImportSpecifier>declaration).name;
|
||||
return moduleName + "." + unescapeIdentifier(propertyName.text);
|
||||
}
|
||||
}
|
||||
|
||||
function getExportNameSubstitution(symbol: Symbol, location: Node): string {
|
||||
if (isExternalModuleSymbol(symbol.parent)) {
|
||||
return "exports." + unescapeIdentifier(symbol.name);
|
||||
}
|
||||
var node = location;
|
||||
var containerSymbol = getParentOfSymbol(symbol);
|
||||
while (node) {
|
||||
if ((node.kind === SyntaxKind.ModuleDeclaration || node.kind === SyntaxKind.EnumDeclaration) && getSymbolOfNode(node) === symbol) {
|
||||
return getLocalNameOfContainer(<ModuleDeclaration | EnumDeclaration>node);
|
||||
if ((node.kind === SyntaxKind.ModuleDeclaration || node.kind === SyntaxKind.EnumDeclaration) && getSymbolOfNode(node) === containerSymbol) {
|
||||
return getGeneratedNameForNode(<ModuleDeclaration | EnumDeclaration>node) + "." + unescapeIdentifier(symbol.name);
|
||||
}
|
||||
node = node.parent;
|
||||
}
|
||||
Debug.fail("getLocalNameForSymbol failed");
|
||||
}
|
||||
|
||||
function getExpressionNamePrefix(node: Identifier): string {
|
||||
function getExpressionNameSubstitution(node: Identifier): string {
|
||||
var symbol = getNodeLinks(node).resolvedSymbol;
|
||||
if (symbol) {
|
||||
// In general, we need to prefix an identifier with its parent name if it references
|
||||
// an exported entity from another module declaration. If we reference an exported
|
||||
// entity within the same module declaration, then whether we prefix depends on the
|
||||
// kind of entity. SymbolFlags.ExportHasLocal encompasses all the kinds that we
|
||||
// do NOT prefix.
|
||||
// Whan an identifier resolves to a parented symbol, it references an exported entity from
|
||||
// another declaration of the same internal module.
|
||||
if (symbol.parent) {
|
||||
return getExportNameSubstitution(symbol, node.parent);
|
||||
}
|
||||
// If we reference an exported entity within the same module declaration, then whether
|
||||
// we prefix depends on the kind of entity. SymbolFlags.ExportHasLocal encompasses all the
|
||||
// kinds that we do NOT prefix.
|
||||
var exportSymbol = getExportSymbolOfValueSymbolIfExported(symbol);
|
||||
if (symbol !== exportSymbol && !(exportSymbol.flags & SymbolFlags.ExportHasLocal)) {
|
||||
symbol = exportSymbol;
|
||||
return getExportNameSubstitution(exportSymbol, node.parent);
|
||||
}
|
||||
if (symbol.parent) {
|
||||
return isExternalModuleSymbol(symbol.parent) ? "exports" : getLocalNameForSymbol(getParentOfSymbol(symbol), node.parent);
|
||||
// Named imports from ES6 import declarations are rewritten
|
||||
if (symbol.flags & SymbolFlags.Import) {
|
||||
return getImportNameSubstitution(symbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getExportAssignmentName(node: SourceFile): string {
|
||||
var symbol = getExportAssignmentSymbol(getSymbolOfNode(node));
|
||||
return symbol && symbolIsValue(symbol) && !isConstEnumSymbol(symbol) ? symbolToString(symbol): undefined;
|
||||
return symbol && symbol !== unknownSymbol && symbolIsValue(symbol) && !isConstEnumSymbol(symbol) ? symbolToString(symbol): undefined;
|
||||
}
|
||||
|
||||
function isTopLevelValueImportWithEntityName(node: ImportDeclaration): boolean {
|
||||
if (node.parent.kind !== SyntaxKind.SourceFile || !isInternalModuleImportDeclaration(node)) {
|
||||
function isTopLevelValueImportEqualsWithEntityName(node: ImportEqualsDeclaration): boolean {
|
||||
if (node.parent.kind !== SyntaxKind.SourceFile || !isInternalModuleImportEqualsDeclaration(node)) {
|
||||
// parent is not source file or it is not reference to internal module
|
||||
return false;
|
||||
}
|
||||
@@ -10324,17 +10594,19 @@ module ts {
|
||||
return isConstEnumSymbol(s) || s.constEnumOnlyModule;
|
||||
}
|
||||
|
||||
function isReferencedImportDeclaration(node: ImportDeclaration): boolean {
|
||||
var symbol = getSymbolOfNode(node);
|
||||
if (getSymbolLinks(symbol).referenced) {
|
||||
return true;
|
||||
function isReferencedImportDeclaration(node: Node): boolean {
|
||||
if (isImportSymbolDeclaration(node)) {
|
||||
var symbol = getSymbolOfNode(node);
|
||||
if (getSymbolLinks(symbol).referenced) {
|
||||
return true;
|
||||
}
|
||||
// logic below will answer 'true' for exported import declaration in a nested module that itself is not exported.
|
||||
// As a consequence this might cause emitting extra.
|
||||
if (node.kind === SyntaxKind.ImportEqualsDeclaration && node.flags & NodeFlags.Export && isImportResolvedToValue(symbol)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// logic below will answer 'true' for exported import declaration in a nested module that itself is not exported.
|
||||
// As a consequence this might cause emitting extra.
|
||||
if (node.flags & NodeFlags.Export) {
|
||||
return isImportResolvedToValue(symbol);
|
||||
}
|
||||
return false;
|
||||
return forEachChild(node, isReferencedImportDeclaration);
|
||||
}
|
||||
|
||||
function isImplementationOfOverload(node: FunctionLikeDeclaration) {
|
||||
@@ -10400,17 +10672,18 @@ module ts {
|
||||
}
|
||||
|
||||
function isUnknownIdentifier(location: Node, name: string): boolean {
|
||||
return !resolveName(location, name, SymbolFlags.Value, /*nodeNotFoundMessage*/ undefined, /*nameArg*/ undefined);
|
||||
return !resolveName(location, name, SymbolFlags.Value, /*nodeNotFoundMessage*/ undefined, /*nameArg*/ undefined) &&
|
||||
!hasProperty(getGeneratedNamesForSourceFile(getSourceFile(location)), name);
|
||||
}
|
||||
|
||||
function createResolver(): EmitResolver {
|
||||
return {
|
||||
getLocalNameOfContainer,
|
||||
getExpressionNamePrefix,
|
||||
getGeneratedNameForNode,
|
||||
getExpressionNameSubstitution,
|
||||
getExportAssignmentName,
|
||||
isReferencedImportDeclaration,
|
||||
getNodeCheckFlags,
|
||||
isTopLevelValueImportWithEntityName,
|
||||
isTopLevelValueImportEqualsWithEntityName,
|
||||
isDeclarationVisible,
|
||||
isImplementationOfOverload,
|
||||
writeTypeOfDeclaration,
|
||||
@@ -10431,7 +10704,7 @@ module ts {
|
||||
// Initialize global symbol table
|
||||
forEach(host.getSourceFiles(), file => {
|
||||
if (!isExternalModule(file)) {
|
||||
extendSymbolTable(globals, file.locals);
|
||||
mergeSymbolTable(globals, file.locals);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -10486,11 +10759,13 @@ module ts {
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
case SyntaxKind.ExportAssignment:
|
||||
case SyntaxKind.VariableStatement:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
case SyntaxKind.ExportAssignment:
|
||||
case SyntaxKind.Parameter:
|
||||
break;
|
||||
default:
|
||||
@@ -10595,7 +10870,7 @@ module ts {
|
||||
return grammarErrorOnNode(lastPrivate, Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "private");
|
||||
}
|
||||
}
|
||||
else if (node.kind === SyntaxKind.ImportDeclaration && flags & NodeFlags.Ambient) {
|
||||
else if ((node.kind === SyntaxKind.ImportDeclaration || node.kind === SyntaxKind.ImportEqualsDeclaration) && flags & NodeFlags.Ambient) {
|
||||
return grammarErrorOnNode(lastDeclare, Diagnostics.A_declare_modifier_cannot_be_used_with_an_import_declaration, "declare");
|
||||
}
|
||||
else if (node.kind === SyntaxKind.InterfaceDeclaration && flags & NodeFlags.Ambient) {
|
||||
@@ -11386,6 +11661,8 @@ module ts {
|
||||
//
|
||||
if (node.kind === SyntaxKind.InterfaceDeclaration ||
|
||||
node.kind === SyntaxKind.ImportDeclaration ||
|
||||
node.kind === SyntaxKind.ImportEqualsDeclaration ||
|
||||
node.kind === SyntaxKind.ExportDeclaration ||
|
||||
node.kind === SyntaxKind.ExportAssignment ||
|
||||
(node.flags & NodeFlags.Ambient)) {
|
||||
|
||||
|
||||
@@ -150,6 +150,10 @@ module ts {
|
||||
Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement: { code: 1188, category: DiagnosticCategory.Error, key: "Only a single variable declaration is allowed in a 'for...of' statement." },
|
||||
The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer: { code: 1189, category: DiagnosticCategory.Error, key: "The variable declaration of a 'for...in' statement cannot have an initializer." },
|
||||
The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer: { code: 1190, category: DiagnosticCategory.Error, key: "The variable declaration of a 'for...of' statement cannot have an initializer." },
|
||||
An_import_declaration_cannot_have_modifiers: { code: 1191, category: DiagnosticCategory.Error, key: "An import declaration cannot have modifiers." },
|
||||
External_module_0_has_no_default_export_or_export_assignment: { code: 1192, category: DiagnosticCategory.Error, key: "External module '{0}' has no default export or export assignment." },
|
||||
An_export_declaration_cannot_have_modifiers: { code: 1193, category: DiagnosticCategory.Error, key: "An export declaration cannot have modifiers." },
|
||||
Export_declarations_are_not_permitted_in_an_internal_module: { code: 1194, category: DiagnosticCategory.Error, key: "Export declarations are not permitted in an internal module." },
|
||||
Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." },
|
||||
Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." },
|
||||
Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." },
|
||||
@@ -278,7 +282,7 @@ module ts {
|
||||
Ambient_external_module_declaration_cannot_specify_relative_module_name: { code: 2436, category: DiagnosticCategory.Error, key: "Ambient external module declaration cannot specify relative module name." },
|
||||
Module_0_is_hidden_by_a_local_declaration_with_the_same_name: { code: 2437, category: DiagnosticCategory.Error, key: "Module '{0}' is hidden by a local declaration with the same name" },
|
||||
Import_name_cannot_be_0: { code: 2438, category: DiagnosticCategory.Error, key: "Import name cannot be '{0}'" },
|
||||
Import_declaration_in_an_ambient_external_module_declaration_cannot_reference_external_module_through_relative_external_module_name: { code: 2439, category: DiagnosticCategory.Error, key: "Import declaration in an ambient external module declaration cannot reference external module through relative external module name." },
|
||||
Import_or_export_declaration_in_an_ambient_external_module_declaration_cannot_reference_external_module_through_relative_external_module_name: { code: 2439, category: DiagnosticCategory.Error, key: "Import or export declaration in an ambient external module declaration cannot reference external module through relative external module name." },
|
||||
Import_declaration_conflicts_with_local_declaration_of_0: { code: 2440, category: DiagnosticCategory.Error, key: "Import declaration conflicts with local declaration of '{0}'" },
|
||||
Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_an_external_module: { code: 2441, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'. Compiler reserves name '{1}' in top level scope of an external module." },
|
||||
Types_have_separate_declarations_of_a_private_property_0: { code: 2442, category: DiagnosticCategory.Error, key: "Types have separate declarations of a private property '{0}'." },
|
||||
@@ -322,6 +326,7 @@ module ts {
|
||||
Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1: { code: 2481, category: DiagnosticCategory.Error, key: "Cannot initialize outer scoped variable '{0}' in the same scope as block scoped declaration '{1}'." },
|
||||
for_of_statements_are_only_available_when_targeting_ECMAScript_6_or_higher: { code: 2482, category: DiagnosticCategory.Error, key: "'for...of' statements are only available when targeting ECMAScript 6 or higher." },
|
||||
The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation: { code: 2483, category: DiagnosticCategory.Error, key: "The left-hand side of a 'for...of' statement cannot use a type annotation." },
|
||||
Export_declaration_conflicts_with_exported_declaration_of_0: { code: 2484, category: DiagnosticCategory.Error, key: "Export declaration conflicts with exported declaration of '{0}'" },
|
||||
Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." },
|
||||
Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." },
|
||||
Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported interface has or is using private name '{1}'." },
|
||||
|
||||
@@ -591,6 +591,22 @@
|
||||
"category": "Error",
|
||||
"code": 1190
|
||||
},
|
||||
"An import declaration cannot have modifiers.": {
|
||||
"category": "Error",
|
||||
"code": 1191
|
||||
},
|
||||
"External module '{0}' has no default export or export assignment.": {
|
||||
"category": "Error",
|
||||
"code": 1192
|
||||
},
|
||||
"An export declaration cannot have modifiers.": {
|
||||
"category": "Error",
|
||||
"code": 1193
|
||||
},
|
||||
"Export declarations are not permitted in an internal module.": {
|
||||
"category": "Error",
|
||||
"code": 1194
|
||||
},
|
||||
|
||||
"Duplicate identifier '{0}'.": {
|
||||
"category": "Error",
|
||||
@@ -1104,7 +1120,7 @@
|
||||
"category": "Error",
|
||||
"code": 2438
|
||||
},
|
||||
"Import declaration in an ambient external module declaration cannot reference external module through relative external module name.": {
|
||||
"Import or export declaration in an ambient external module declaration cannot reference external module through relative external module name.": {
|
||||
"category": "Error",
|
||||
"code": 2439
|
||||
},
|
||||
@@ -1280,6 +1296,10 @@
|
||||
"category": "Error",
|
||||
"code": 2483
|
||||
},
|
||||
"Export declaration conflicts with exported declaration of '{0}'": {
|
||||
"category": "Error",
|
||||
"code": 2484
|
||||
},
|
||||
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
|
||||
+284
-76
@@ -16,6 +16,12 @@ module ts {
|
||||
getIndent(): number;
|
||||
}
|
||||
|
||||
interface ExternalImportInfo {
|
||||
rootNode: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration;
|
||||
declarationNode?: ImportEqualsDeclaration | ImportClause | NamespaceImport;
|
||||
namedImports?: NamedImports;
|
||||
}
|
||||
|
||||
interface SymbolAccessibilityDiagnostic {
|
||||
errorNode: Node;
|
||||
diagnosticMessage: DiagnosticMessage;
|
||||
@@ -34,7 +40,7 @@ module ts {
|
||||
}
|
||||
|
||||
interface AliasDeclarationEmitInfo {
|
||||
declaration: ImportDeclaration;
|
||||
declaration: ImportEqualsDeclaration;
|
||||
outputPos: number;
|
||||
indent: number;
|
||||
asynchronousOutput?: string; // If the output for alias was written asynchronously, the corresponding output
|
||||
@@ -468,9 +474,9 @@ module ts {
|
||||
decreaseIndent = newWriter.decreaseIndent;
|
||||
}
|
||||
|
||||
function writeAsychronousImportDeclarations(importDeclarations: ImportDeclaration[]) {
|
||||
function writeAsychronousImportEqualsDeclarations(importEqualsDeclarations: ImportEqualsDeclaration[]) {
|
||||
var oldWriter = writer;
|
||||
forEach(importDeclarations, aliasToWrite => {
|
||||
forEach(importEqualsDeclarations, aliasToWrite => {
|
||||
var aliasEmitInfo = forEach(aliasDeclarationEmitInfo, declEmitInfo => declEmitInfo.declaration === aliasToWrite ? declEmitInfo : undefined);
|
||||
// If the alias was marked as not visible when we saw its declaration, we would have saved the aliasEmitInfo, but if we haven't yet visited the alias declaration
|
||||
// then we don't need to write it at this point. We will write it when we actually see its declaration
|
||||
@@ -484,7 +490,7 @@ module ts {
|
||||
for (var declarationIndent = aliasEmitInfo.indent; declarationIndent; declarationIndent--) {
|
||||
increaseIndent();
|
||||
}
|
||||
writeImportDeclaration(aliasToWrite);
|
||||
writeImportEqualsDeclaration(aliasToWrite);
|
||||
aliasEmitInfo.asynchronousOutput = writer.getText();
|
||||
}
|
||||
});
|
||||
@@ -495,7 +501,7 @@ module ts {
|
||||
if (symbolAccesibilityResult.accessibility === SymbolAccessibility.Accessible) {
|
||||
// write the aliases
|
||||
if (symbolAccesibilityResult && symbolAccesibilityResult.aliasesToMakeVisible) {
|
||||
writeAsychronousImportDeclarations(symbolAccesibilityResult.aliasesToMakeVisible);
|
||||
writeAsychronousImportEqualsDeclarations(symbolAccesibilityResult.aliasesToMakeVisible);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -621,7 +627,7 @@ module ts {
|
||||
function emitEntityName(entityName: EntityName) {
|
||||
var visibilityResult = resolver.isEntityNameVisible(entityName,
|
||||
// Aliases can be written asynchronously so use correct enclosing declaration
|
||||
entityName.parent.kind === SyntaxKind.ImportDeclaration ? entityName.parent : enclosingDeclaration);
|
||||
entityName.parent.kind === SyntaxKind.ImportEqualsDeclaration ? entityName.parent : enclosingDeclaration);
|
||||
|
||||
handleSymbolAccessibilityError(visibilityResult);
|
||||
writeEntityName(entityName);
|
||||
@@ -727,7 +733,7 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
function emitImportDeclaration(node: ImportDeclaration) {
|
||||
function emitImportEqualsDeclaration(node: ImportEqualsDeclaration) {
|
||||
var nodeEmitInfo = {
|
||||
declaration: node,
|
||||
outputPos: writer.getTextPos(),
|
||||
@@ -736,12 +742,12 @@ module ts {
|
||||
};
|
||||
aliasDeclarationEmitInfo.push(nodeEmitInfo);
|
||||
if (nodeEmitInfo.hasWritten) {
|
||||
writeImportDeclaration(node);
|
||||
writeImportEqualsDeclaration(node);
|
||||
}
|
||||
}
|
||||
|
||||
function writeImportDeclaration(node: ImportDeclaration) {
|
||||
// note usage of writer. methods instead of aliases created, just to make sure we are using
|
||||
function writeImportEqualsDeclaration(node: ImportEqualsDeclaration) {
|
||||
// note usage of writer. methods instead of aliases created, just to make sure we are using
|
||||
// correct writer especially to handle asynchronous alias writing
|
||||
emitJsDocComments(node);
|
||||
if (node.flags & NodeFlags.Export) {
|
||||
@@ -750,13 +756,13 @@ module ts {
|
||||
write("import ");
|
||||
writeTextOfNode(currentSourceFile, node.name);
|
||||
write(" = ");
|
||||
if (isInternalModuleImportDeclaration(node)) {
|
||||
if (isInternalModuleImportEqualsDeclaration(node)) {
|
||||
emitTypeWithNewGetSymbolAccessibilityDiagnostic(<EntityName>node.moduleReference, getImportEntityNameVisibilityError);
|
||||
write(";");
|
||||
}
|
||||
else {
|
||||
write("require(");
|
||||
writeTextOfNode(currentSourceFile, getExternalModuleImportDeclarationExpression(node));
|
||||
writeTextOfNode(currentSourceFile, getExternalModuleImportEqualsDeclarationExpression(node));
|
||||
write(");");
|
||||
}
|
||||
writer.writeLine();
|
||||
@@ -1483,8 +1489,8 @@ module ts {
|
||||
return emitEnumDeclaration(<EnumDeclaration>node);
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
return emitModuleDeclaration(<ModuleDeclaration>node);
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
return emitImportDeclaration(<ImportDeclaration>node);
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
return emitImportEqualsDeclaration(<ImportEqualsDeclaration>node);
|
||||
case SyntaxKind.ExportAssignment:
|
||||
return emitExportAssignment(<ExportAssignment>node);
|
||||
case SyntaxKind.SourceFile:
|
||||
@@ -1572,6 +1578,8 @@ module ts {
|
||||
var tempCount = 0;
|
||||
var tempVariables: Identifier[];
|
||||
var tempParameters: Identifier[];
|
||||
var externalImports: ExternalImportInfo[];
|
||||
var exportSpecifiers: Map<ExportSpecifier[]>;
|
||||
|
||||
/** write emitted output to disk*/
|
||||
var writeEmittedFiles = writeJavaScriptFile;
|
||||
@@ -2378,7 +2386,7 @@ module ts {
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
return (<Declaration>parent).name === node;
|
||||
case SyntaxKind.BreakStatement:
|
||||
case SyntaxKind.ContinueStatement:
|
||||
@@ -2392,12 +2400,13 @@ module ts {
|
||||
}
|
||||
|
||||
function emitExpressionIdentifier(node: Identifier) {
|
||||
var prefix = resolver.getExpressionNamePrefix(node);
|
||||
if (prefix) {
|
||||
write(prefix);
|
||||
write(".");
|
||||
var substitution = resolver.getExpressionNameSubstitution(node);
|
||||
if (substitution) {
|
||||
write(substitution);
|
||||
}
|
||||
else {
|
||||
writeTextOfNode(currentSourceFile, node);
|
||||
}
|
||||
writeTextOfNode(currentSourceFile, node);
|
||||
}
|
||||
|
||||
function emitIdentifier(node: Identifier) {
|
||||
@@ -2619,8 +2628,12 @@ module ts {
|
||||
return (<PropertyAssignment>property).initializer;
|
||||
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
var prefix = createIdentifier(resolver.getExpressionNamePrefix((<ShorthandPropertyAssignment>property).name));
|
||||
return createPropertyAccessExpression(prefix, (<ShorthandPropertyAssignment>property).name);
|
||||
// TODO: (andersh) Technically it isn't correct to make an identifier here since getExpressionNamePrefix returns
|
||||
// a string containing a dotted name. In general I'm not a fan of mini tree rewriters as this one, elsewhere we
|
||||
// manage by just emitting strings (which is a lot more performant).
|
||||
//var prefix = createIdentifier(resolver.getExpressionNamePrefix((<ShorthandPropertyAssignment>property).name));
|
||||
//return createPropertyAccessExpression(prefix, (<ShorthandPropertyAssignment>property).name);
|
||||
return createIdentifier(resolver.getExpressionNameSubstitution((<ShorthandPropertyAssignment>property).name));
|
||||
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
return createFunctionExpression((<MethodDeclaration>property).parameters, (<MethodDeclaration>property).body);
|
||||
@@ -2815,7 +2828,7 @@ module ts {
|
||||
// export var obj = { y };
|
||||
// }
|
||||
// The short-hand property in obj need to emit as such ... = { y : m.y } regardless of the TargetScript version
|
||||
if (languageVersion <= ScriptTarget.ES5 || resolver.getExpressionNamePrefix(node.name)) {
|
||||
if (languageVersion < ScriptTarget.ES6 || resolver.getExpressionNameSubstitution(node.name)) {
|
||||
// Emit identifier as an identifier
|
||||
write(": ");
|
||||
// Even though this is stored as identifier treat it as an expression
|
||||
@@ -3417,17 +3430,37 @@ module ts {
|
||||
return <ModuleDeclaration>node;
|
||||
}
|
||||
|
||||
function emitContainingModuleName(node: Node) {
|
||||
var container = getContainingModule(node);
|
||||
write(container ? resolver.getGeneratedNameForNode(container) : "exports");
|
||||
}
|
||||
|
||||
function emitModuleMemberName(node: Declaration) {
|
||||
emitStart(node.name);
|
||||
if (getCombinedNodeFlags(node) & NodeFlags.Export) {
|
||||
var container = getContainingModule(node);
|
||||
write(container ? resolver.getLocalNameOfContainer(container) : "exports");
|
||||
emitContainingModuleName(node);
|
||||
write(".");
|
||||
}
|
||||
emitNode(node.name);
|
||||
emitEnd(node.name);
|
||||
}
|
||||
|
||||
function emitExportMemberAssignments(name: Identifier) {
|
||||
if (exportSpecifiers && hasProperty(exportSpecifiers, name.text)) {
|
||||
forEach(exportSpecifiers[name.text], specifier => {
|
||||
writeLine();
|
||||
emitStart(specifier.name);
|
||||
emitContainingModuleName(specifier);
|
||||
write(".");
|
||||
emitNode(specifier.name);
|
||||
emitEnd(specifier.name);
|
||||
write(" = ");
|
||||
emitNode(name);
|
||||
write(";");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function emitDestructuring(root: BinaryExpression | VariableDeclaration | ParameterDeclaration, value?: Expression) {
|
||||
var emitCount = 0;
|
||||
// An exported declaration is actually emitted as an assignment (to a property on the module object), so
|
||||
@@ -3660,6 +3693,16 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
function emitExportVariableAssignments(node: VariableDeclaration | BindingElement) {
|
||||
var name = (<VariableLikeDeclaration>node).name;
|
||||
if (name.kind === SyntaxKind.Identifier) {
|
||||
emitExportMemberAssignments(<Identifier>name);
|
||||
}
|
||||
else if (isBindingPattern(name)) {
|
||||
forEach((<BindingPattern>name).elements, emitExportVariableAssignments);
|
||||
}
|
||||
}
|
||||
|
||||
function emitVariableStatement(node: VariableStatement) {
|
||||
if (!(node.flags & NodeFlags.Export)) {
|
||||
if (isLet(node.declarationList)) {
|
||||
@@ -3674,6 +3717,9 @@ module ts {
|
||||
}
|
||||
emitCommaList(node.declarationList.declarations);
|
||||
write(";");
|
||||
if (languageVersion < ScriptTarget.ES6 && node.parent === currentSourceFile) {
|
||||
forEach(node.declarationList.declarations, emitExportVariableAssignments);
|
||||
}
|
||||
}
|
||||
|
||||
function emitParameter(node: ParameterDeclaration) {
|
||||
@@ -3798,6 +3844,9 @@ module ts {
|
||||
emit(node.name);
|
||||
}
|
||||
emitSignatureAndBody(node);
|
||||
if (languageVersion < ScriptTarget.ES6 && node.kind === SyntaxKind.FunctionDeclaration && node.parent === currentSourceFile) {
|
||||
emitExportMemberAssignments((<FunctionDeclaration>node).name);
|
||||
}
|
||||
if (node.kind !== SyntaxKind.MethodDeclaration && node.kind !== SyntaxKind.MethodSignature) {
|
||||
emitTrailingComments(node);
|
||||
}
|
||||
@@ -4208,6 +4257,9 @@ module ts {
|
||||
emitEnd(node);
|
||||
write(";");
|
||||
}
|
||||
if (languageVersion < ScriptTarget.ES6 && node.parent === currentSourceFile) {
|
||||
emitExportMemberAssignments(node.name);
|
||||
}
|
||||
|
||||
function emitConstructorOfClass() {
|
||||
var saveTempCount = tempCount;
|
||||
@@ -4308,7 +4360,7 @@ module ts {
|
||||
emitStart(node);
|
||||
write("(function (");
|
||||
emitStart(node.name);
|
||||
write(resolver.getLocalNameOfContainer(node));
|
||||
write(resolver.getGeneratedNameForNode(node));
|
||||
emitEnd(node.name);
|
||||
write(") {");
|
||||
increaseIndent();
|
||||
@@ -4334,14 +4386,17 @@ module ts {
|
||||
emitEnd(node);
|
||||
write(";");
|
||||
}
|
||||
if (languageVersion < ScriptTarget.ES6 && node.parent === currentSourceFile) {
|
||||
emitExportMemberAssignments(node.name);
|
||||
}
|
||||
}
|
||||
|
||||
function emitEnumMember(node: EnumMember) {
|
||||
var enumParent = <EnumDeclaration>node.parent;
|
||||
emitStart(node);
|
||||
write(resolver.getLocalNameOfContainer(enumParent));
|
||||
write(resolver.getGeneratedNameForNode(enumParent));
|
||||
write("[");
|
||||
write(resolver.getLocalNameOfContainer(enumParent));
|
||||
write(resolver.getGeneratedNameForNode(enumParent));
|
||||
write("[");
|
||||
emitExpressionForPropertyName(node.name);
|
||||
write("] = ");
|
||||
@@ -4397,7 +4452,7 @@ module ts {
|
||||
emitStart(node);
|
||||
write("(function (");
|
||||
emitStart(node.name);
|
||||
write(resolver.getLocalNameOfContainer(node));
|
||||
write(resolver.getGeneratedNameForNode(node));
|
||||
emitEnd(node.name);
|
||||
write(") ");
|
||||
if (node.body.kind === SyntaxKind.ModuleBlock) {
|
||||
@@ -4432,65 +4487,200 @@ module ts {
|
||||
emitModuleMemberName(node);
|
||||
write(" = {}));");
|
||||
emitEnd(node);
|
||||
if (languageVersion < ScriptTarget.ES6 && node.name.kind === SyntaxKind.Identifier && node.parent === currentSourceFile) {
|
||||
emitExportMemberAssignments(<Identifier>node.name);
|
||||
}
|
||||
}
|
||||
|
||||
function emitImportDeclaration(node: ImportDeclaration) {
|
||||
var emitImportDeclaration = resolver.isReferencedImportDeclaration(node);
|
||||
|
||||
if (!emitImportDeclaration) {
|
||||
// preserve old compiler's behavior: emit 'var' for import declaration (even if we do not consider them referenced) when
|
||||
// - current file is not external module
|
||||
// - import declaration is top level and target is value imported by entity name
|
||||
emitImportDeclaration = !isExternalModule(currentSourceFile) && resolver.isTopLevelValueImportWithEntityName(node);
|
||||
function emitRequire(moduleName: Expression) {
|
||||
if (moduleName.kind === SyntaxKind.StringLiteral) {
|
||||
write("require(");
|
||||
emitStart(moduleName);
|
||||
emitLiteral(<LiteralExpression>moduleName);
|
||||
emitEnd(moduleName);
|
||||
emitToken(SyntaxKind.CloseParenToken, moduleName.end);
|
||||
write(";");
|
||||
}
|
||||
else {
|
||||
write("require();");
|
||||
}
|
||||
}
|
||||
|
||||
if (emitImportDeclaration) {
|
||||
if (isExternalModuleImportDeclaration(node) && node.parent.kind === SyntaxKind.SourceFile && compilerOptions.module === ModuleKind.AMD) {
|
||||
if (node.flags & NodeFlags.Export) {
|
||||
writeLine();
|
||||
emitLeadingComments(node);
|
||||
emitStart(node);
|
||||
emitModuleMemberName(node);
|
||||
write(" = ");
|
||||
emit(node.name);
|
||||
write(";");
|
||||
emitEnd(node);
|
||||
emitTrailingComments(node);
|
||||
}
|
||||
}
|
||||
else {
|
||||
writeLine();
|
||||
function emitImportDeclaration(node: ImportDeclaration | ImportEqualsDeclaration) {
|
||||
var info = getExternalImportInfo(node);
|
||||
if (info) {
|
||||
var declarationNode = info.declarationNode;
|
||||
var namedImports = info.namedImports;
|
||||
if (compilerOptions.module !== ModuleKind.AMD) {
|
||||
emitLeadingComments(node);
|
||||
emitStart(node);
|
||||
if (!(node.flags & NodeFlags.Export)) write("var ");
|
||||
emitModuleMemberName(node);
|
||||
write(" = ");
|
||||
if (isInternalModuleImportDeclaration(node)) {
|
||||
emit(node.moduleReference);
|
||||
var moduleName = getExternalModuleName(node);
|
||||
if (declarationNode) {
|
||||
if (!(declarationNode.flags & NodeFlags.Export)) write("var ");
|
||||
emitModuleMemberName(declarationNode);
|
||||
write(" = ");
|
||||
emitRequire(moduleName);
|
||||
}
|
||||
else if (namedImports) {
|
||||
write("var ");
|
||||
write(resolver.getGeneratedNameForNode(<ImportDeclaration>node));
|
||||
write(" = ");
|
||||
emitRequire(moduleName);
|
||||
}
|
||||
else {
|
||||
var literal = <LiteralExpression>getExternalModuleImportDeclarationExpression(node);
|
||||
write("require(");
|
||||
emitStart(literal);
|
||||
emitLiteral(literal);
|
||||
emitEnd(literal);
|
||||
emitToken(SyntaxKind.CloseParenToken, literal.end);
|
||||
emitRequire(moduleName);
|
||||
}
|
||||
write(";");
|
||||
emitEnd(node);
|
||||
emitTrailingComments(node);
|
||||
}
|
||||
else {
|
||||
if (declarationNode) {
|
||||
if (declarationNode.flags & NodeFlags.Export) {
|
||||
emitModuleMemberName(declarationNode);
|
||||
write(" = ");
|
||||
emit(declarationNode.name);
|
||||
write(";");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getExternalImportDeclarations(node: SourceFile): ImportDeclaration[] {
|
||||
var result: ImportDeclaration[] = [];
|
||||
forEach(node.statements, statement => {
|
||||
if (isExternalModuleImportDeclaration(statement) && resolver.isReferencedImportDeclaration(<ImportDeclaration>statement)) {
|
||||
result.push(<ImportDeclaration>statement);
|
||||
function emitImportEqualsDeclaration(node: ImportEqualsDeclaration) {
|
||||
if (isExternalModuleImportEqualsDeclaration(node)) {
|
||||
emitImportDeclaration(node);
|
||||
return;
|
||||
}
|
||||
// preserve old compiler's behavior: emit 'var' for import declaration (even if we do not consider them referenced) when
|
||||
// - current file is not external module
|
||||
// - import declaration is top level and target is value imported by entity name
|
||||
if (resolver.isReferencedImportDeclaration(node) ||
|
||||
(!isExternalModule(currentSourceFile) && resolver.isTopLevelValueImportEqualsWithEntityName(node))) {
|
||||
emitLeadingComments(node);
|
||||
emitStart(node);
|
||||
if (!(node.flags & NodeFlags.Export)) write("var ");
|
||||
emitModuleMemberName(node);
|
||||
write(" = ");
|
||||
emit(node.moduleReference);
|
||||
write(";");
|
||||
emitEnd(node);
|
||||
emitTrailingComments(node);
|
||||
}
|
||||
}
|
||||
|
||||
function emitExportDeclaration(node: ExportDeclaration) {
|
||||
if (node.moduleSpecifier) {
|
||||
emitStart(node);
|
||||
var generatedName = resolver.getGeneratedNameForNode(node);
|
||||
if (compilerOptions.module !== ModuleKind.AMD) {
|
||||
write("var ");
|
||||
write(generatedName);
|
||||
write(" = ");
|
||||
emitRequire(getExternalModuleName(node));
|
||||
}
|
||||
if (node.exportClause) {
|
||||
// export { x, y, ... }
|
||||
forEach(node.exportClause.elements, specifier => {
|
||||
writeLine();
|
||||
emitStart(specifier);
|
||||
emitContainingModuleName(specifier);
|
||||
write(".");
|
||||
emitNode(specifier.name);
|
||||
write(" = ");
|
||||
write(generatedName);
|
||||
write(".");
|
||||
emitNode(specifier.propertyName || specifier.name);
|
||||
write(";");
|
||||
emitEnd(specifier);
|
||||
});
|
||||
}
|
||||
else {
|
||||
// export *
|
||||
var tempName = createTempVariable(node).text;
|
||||
writeLine();
|
||||
write("for (var " + tempName + " in " + generatedName + ") if (!");
|
||||
emitContainingModuleName(node);
|
||||
write(".hasOwnProperty(" + tempName + ")) ");
|
||||
emitContainingModuleName(node);
|
||||
write("[" + tempName + "] = " + generatedName + "[" + tempName + "];");
|
||||
}
|
||||
emitEnd(node);
|
||||
}
|
||||
}
|
||||
|
||||
function createExternalImportInfo(node: Node): ExternalImportInfo {
|
||||
if (node.kind === SyntaxKind.ImportEqualsDeclaration) {
|
||||
if ((<ImportEqualsDeclaration>node).moduleReference.kind === SyntaxKind.ExternalModuleReference) {
|
||||
return {
|
||||
rootNode: <ImportEqualsDeclaration>node,
|
||||
declarationNode: <ImportEqualsDeclaration>node
|
||||
};
|
||||
}
|
||||
}
|
||||
else if (node.kind === SyntaxKind.ImportDeclaration) {
|
||||
var importClause = (<ImportDeclaration>node).importClause;
|
||||
if (importClause) {
|
||||
if (importClause.name) {
|
||||
return {
|
||||
rootNode: <ImportDeclaration>node,
|
||||
declarationNode: importClause
|
||||
};
|
||||
}
|
||||
if (importClause.namedBindings.kind === SyntaxKind.NamespaceImport) {
|
||||
return {
|
||||
rootNode: <ImportDeclaration>node,
|
||||
declarationNode: <NamespaceImport>importClause.namedBindings
|
||||
};
|
||||
}
|
||||
return {
|
||||
rootNode: <ImportDeclaration>node,
|
||||
namedImports: <NamedImports>importClause.namedBindings,
|
||||
localName: resolver.getGeneratedNameForNode(<ImportDeclaration>node)
|
||||
};
|
||||
}
|
||||
return {
|
||||
rootNode: <ImportDeclaration>node
|
||||
}
|
||||
}
|
||||
else if (node.kind === SyntaxKind.ExportDeclaration) {
|
||||
if ((<ExportDeclaration>node).moduleSpecifier) {
|
||||
return {
|
||||
rootNode: <ExportDeclaration>node,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createExternalModuleInfo(sourceFile: SourceFile) {
|
||||
externalImports = [];
|
||||
exportSpecifiers = {};
|
||||
forEach(sourceFile.statements, node => {
|
||||
if (node.kind === SyntaxKind.ExportDeclaration && !(<ExportDeclaration>node).moduleSpecifier) {
|
||||
forEach((<ExportDeclaration>node).exportClause.elements, specifier => {
|
||||
var name = (specifier.propertyName || specifier.name).text;
|
||||
(exportSpecifiers[name] || (exportSpecifiers[name] = [])).push(specifier);
|
||||
});
|
||||
}
|
||||
else {
|
||||
var info = createExternalImportInfo(node);
|
||||
if (info) {
|
||||
if ((!info.declarationNode && !info.namedImports) || resolver.isReferencedImportDeclaration(node)) {
|
||||
externalImports.push(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
function getExternalImportInfo(node: ImportDeclaration | ImportEqualsDeclaration): ExternalImportInfo {
|
||||
if (externalImports) {
|
||||
for (var i = 0; i < externalImports.length; i++) {
|
||||
var info = externalImports[i];
|
||||
if (info.rootNode === node) {
|
||||
return info;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getFirstExportAssignment(sourceFile: SourceFile) {
|
||||
@@ -4515,7 +4705,6 @@ module ts {
|
||||
}
|
||||
|
||||
function emitAMDModule(node: SourceFile, startIndex: number) {
|
||||
var imports = getExternalImportDeclarations(node);
|
||||
writeLine();
|
||||
write("define(");
|
||||
sortAMDModules(node.amdDependencies);
|
||||
@@ -4523,9 +4712,15 @@ module ts {
|
||||
write("\"" + node.amdModuleName + "\", ");
|
||||
}
|
||||
write("[\"require\", \"exports\"");
|
||||
forEach(imports, imp => {
|
||||
forEach(externalImports, info => {
|
||||
write(", ");
|
||||
emitLiteral(<LiteralExpression>getExternalModuleImportDeclarationExpression(imp));
|
||||
var moduleName = getExternalModuleName(info.rootNode);
|
||||
if (moduleName.kind === SyntaxKind.StringLiteral) {
|
||||
emitLiteral(<LiteralExpression>moduleName);
|
||||
}
|
||||
else {
|
||||
write("\"\"");
|
||||
}
|
||||
});
|
||||
forEach(node.amdDependencies, amdDependency => {
|
||||
var text = "\"" + amdDependency.path + "\"";
|
||||
@@ -4533,9 +4728,14 @@ module ts {
|
||||
write(text);
|
||||
});
|
||||
write("], function (require, exports");
|
||||
forEach(imports, imp => {
|
||||
forEach(externalImports, info => {
|
||||
write(", ");
|
||||
emit(imp.name);
|
||||
if (info.declarationNode) {
|
||||
emit(info.declarationNode.name);
|
||||
}
|
||||
else {
|
||||
write(resolver.getGeneratedNameForNode(<ImportDeclaration | ExportDeclaration>info.rootNode));
|
||||
}
|
||||
});
|
||||
forEach(node.amdDependencies, amdDependency => {
|
||||
if (amdDependency.name) {
|
||||
@@ -4625,6 +4825,7 @@ module ts {
|
||||
extendsEmitted = true;
|
||||
}
|
||||
if (isExternalModule(node)) {
|
||||
createExternalModuleInfo(node);
|
||||
if (compilerOptions.module === ModuleKind.AMD) {
|
||||
emitAMDModule(node, startIndex);
|
||||
}
|
||||
@@ -4633,6 +4834,8 @@ module ts {
|
||||
}
|
||||
}
|
||||
else {
|
||||
externalImports = undefined;
|
||||
exportSpecifiers = undefined;
|
||||
emitCaptureThisForNodeIfNecessary(node);
|
||||
emitLinesStartingAt(node.statements, startIndex);
|
||||
emitTempDeclarations(/*newLine*/ true);
|
||||
@@ -4669,6 +4872,7 @@ module ts {
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
case SyntaxKind.ExportAssignment:
|
||||
return false;
|
||||
@@ -4833,6 +5037,10 @@ module ts {
|
||||
return emitModuleDeclaration(<ModuleDeclaration>node);
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
return emitImportDeclaration(<ImportDeclaration>node);
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
return emitImportEqualsDeclaration(<ImportEqualsDeclaration>node);
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
return emitExportDeclaration(<ExportDeclaration>node);
|
||||
case SyntaxKind.SourceFile:
|
||||
return emitSourceFile(<SourceFile>node);
|
||||
}
|
||||
|
||||
+253
-63
@@ -252,10 +252,30 @@ module ts {
|
||||
return visitNodes(cbNodes, node.modifiers) ||
|
||||
visitNode(cbNode, (<ModuleDeclaration>node).name) ||
|
||||
visitNode(cbNode, (<ModuleDeclaration>node).body);
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
return visitNodes(cbNodes, node.modifiers) ||
|
||||
visitNode(cbNode, (<ImportEqualsDeclaration>node).name) ||
|
||||
visitNode(cbNode, (<ImportEqualsDeclaration>node).moduleReference);
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
return visitNodes(cbNodes, node.modifiers) ||
|
||||
visitNode(cbNode, (<ImportDeclaration>node).name) ||
|
||||
visitNode(cbNode, (<ImportDeclaration>node).moduleReference);
|
||||
visitNode(cbNode, (<ImportDeclaration>node).importClause) ||
|
||||
visitNode(cbNode, (<ImportDeclaration>node).moduleSpecifier);
|
||||
case SyntaxKind.ImportClause:
|
||||
return visitNode(cbNode, (<ImportClause>node).name) ||
|
||||
visitNode(cbNode, (<ImportClause>node).namedBindings);
|
||||
case SyntaxKind.NamespaceImport:
|
||||
return visitNode(cbNode, (<NamespaceImport>node).name);
|
||||
case SyntaxKind.NamedImports:
|
||||
case SyntaxKind.NamedExports:
|
||||
return visitNodes(cbNodes, (<NamedImportsOrExports>node).elements);
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
return visitNodes(cbNodes, node.modifiers) ||
|
||||
visitNode(cbNode, (<ExportDeclaration>node).exportClause) ||
|
||||
visitNode(cbNode, (<ExportDeclaration>node).moduleSpecifier);
|
||||
case SyntaxKind.ImportSpecifier:
|
||||
case SyntaxKind.ExportSpecifier:
|
||||
return visitNode(cbNode, (<ImportOrExportSpecifier>node).propertyName) ||
|
||||
visitNode(cbNode, (<ImportOrExportSpecifier>node).name);
|
||||
case SyntaxKind.ExportAssignment:
|
||||
return visitNodes(cbNodes, node.modifiers) ||
|
||||
visitNode(cbNode, (<ExportAssignment>node).exportName);
|
||||
@@ -273,27 +293,28 @@ module ts {
|
||||
}
|
||||
|
||||
const enum ParsingContext {
|
||||
SourceElements, // Elements in source file
|
||||
ModuleElements, // Elements in module declaration
|
||||
BlockStatements, // Statements in block
|
||||
SwitchClauses, // Clauses in switch statement
|
||||
SwitchClauseStatements, // Statements in switch clause
|
||||
TypeMembers, // Members in interface or type literal
|
||||
ClassMembers, // Members in class declaration
|
||||
EnumMembers, // Members in enum declaration
|
||||
TypeReferences, // Type references in extends or implements clause
|
||||
VariableDeclarations, // Variable declarations in variable statement
|
||||
ObjectBindingElements, // Binding elements in object binding list
|
||||
ArrayBindingElements, // Binding elements in array binding list
|
||||
ArgumentExpressions, // Expressions in argument list
|
||||
ObjectLiteralMembers, // Members in object literal
|
||||
ArrayLiteralMembers, // Members in array literal
|
||||
Parameters, // Parameters in parameter list
|
||||
TypeParameters, // Type parameters in type parameter list
|
||||
TypeArguments, // Type arguments in type argument list
|
||||
TupleElementTypes, // Element types in tuple element type list
|
||||
HeritageClauses, // Heritage clauses for a class or interface declaration.
|
||||
Count // Number of parsing contexts
|
||||
SourceElements, // Elements in source file
|
||||
ModuleElements, // Elements in module declaration
|
||||
BlockStatements, // Statements in block
|
||||
SwitchClauses, // Clauses in switch statement
|
||||
SwitchClauseStatements, // Statements in switch clause
|
||||
TypeMembers, // Members in interface or type literal
|
||||
ClassMembers, // Members in class declaration
|
||||
EnumMembers, // Members in enum declaration
|
||||
TypeReferences, // Type references in extends or implements clause
|
||||
VariableDeclarations, // Variable declarations in variable statement
|
||||
ObjectBindingElements, // Binding elements in object binding list
|
||||
ArrayBindingElements, // Binding elements in array binding list
|
||||
ArgumentExpressions, // Expressions in argument list
|
||||
ObjectLiteralMembers, // Members in object literal
|
||||
ArrayLiteralMembers, // Members in array literal
|
||||
Parameters, // Parameters in parameter list
|
||||
TypeParameters, // Type parameters in type parameter list
|
||||
TypeArguments, // Type arguments in type argument list
|
||||
TupleElementTypes, // Element types in tuple element type list
|
||||
HeritageClauses, // Heritage clauses for a class or interface declaration.
|
||||
ImportOrExportSpecifiers, // Named import clause's import specifier list
|
||||
Count // Number of parsing contexts
|
||||
}
|
||||
|
||||
const enum Tristate {
|
||||
@@ -304,26 +325,27 @@ module ts {
|
||||
|
||||
function parsingContextErrors(context: ParsingContext): DiagnosticMessage {
|
||||
switch (context) {
|
||||
case ParsingContext.SourceElements: return Diagnostics.Declaration_or_statement_expected;
|
||||
case ParsingContext.ModuleElements: return Diagnostics.Declaration_or_statement_expected;
|
||||
case ParsingContext.BlockStatements: return Diagnostics.Statement_expected;
|
||||
case ParsingContext.SwitchClauses: return Diagnostics.case_or_default_expected;
|
||||
case ParsingContext.SwitchClauseStatements: return Diagnostics.Statement_expected;
|
||||
case ParsingContext.TypeMembers: return Diagnostics.Property_or_signature_expected;
|
||||
case ParsingContext.ClassMembers: return Diagnostics.Unexpected_token_A_constructor_method_accessor_or_property_was_expected;
|
||||
case ParsingContext.EnumMembers: return Diagnostics.Enum_member_expected;
|
||||
case ParsingContext.TypeReferences: return Diagnostics.Type_reference_expected;
|
||||
case ParsingContext.VariableDeclarations: return Diagnostics.Variable_declaration_expected;
|
||||
case ParsingContext.ObjectBindingElements: return Diagnostics.Property_destructuring_pattern_expected;
|
||||
case ParsingContext.ArrayBindingElements: return Diagnostics.Array_element_destructuring_pattern_expected;
|
||||
case ParsingContext.ArgumentExpressions: return Diagnostics.Argument_expression_expected;
|
||||
case ParsingContext.ObjectLiteralMembers: return Diagnostics.Property_assignment_expected;
|
||||
case ParsingContext.ArrayLiteralMembers: return Diagnostics.Expression_or_comma_expected;
|
||||
case ParsingContext.Parameters: return Diagnostics.Parameter_declaration_expected;
|
||||
case ParsingContext.TypeParameters: return Diagnostics.Type_parameter_declaration_expected;
|
||||
case ParsingContext.TypeArguments: return Diagnostics.Type_argument_expected;
|
||||
case ParsingContext.TupleElementTypes: return Diagnostics.Type_expected;
|
||||
case ParsingContext.HeritageClauses: return Diagnostics.Unexpected_token_expected;
|
||||
case ParsingContext.SourceElements: return Diagnostics.Declaration_or_statement_expected;
|
||||
case ParsingContext.ModuleElements: return Diagnostics.Declaration_or_statement_expected;
|
||||
case ParsingContext.BlockStatements: return Diagnostics.Statement_expected;
|
||||
case ParsingContext.SwitchClauses: return Diagnostics.case_or_default_expected;
|
||||
case ParsingContext.SwitchClauseStatements: return Diagnostics.Statement_expected;
|
||||
case ParsingContext.TypeMembers: return Diagnostics.Property_or_signature_expected;
|
||||
case ParsingContext.ClassMembers: return Diagnostics.Unexpected_token_A_constructor_method_accessor_or_property_was_expected;
|
||||
case ParsingContext.EnumMembers: return Diagnostics.Enum_member_expected;
|
||||
case ParsingContext.TypeReferences: return Diagnostics.Type_reference_expected;
|
||||
case ParsingContext.VariableDeclarations: return Diagnostics.Variable_declaration_expected;
|
||||
case ParsingContext.ObjectBindingElements: return Diagnostics.Property_destructuring_pattern_expected;
|
||||
case ParsingContext.ArrayBindingElements: return Diagnostics.Array_element_destructuring_pattern_expected;
|
||||
case ParsingContext.ArgumentExpressions: return Diagnostics.Argument_expression_expected;
|
||||
case ParsingContext.ObjectLiteralMembers: return Diagnostics.Property_assignment_expected;
|
||||
case ParsingContext.ArrayLiteralMembers: return Diagnostics.Expression_or_comma_expected;
|
||||
case ParsingContext.Parameters: return Diagnostics.Parameter_declaration_expected;
|
||||
case ParsingContext.TypeParameters: return Diagnostics.Type_parameter_declaration_expected;
|
||||
case ParsingContext.TypeArguments: return Diagnostics.Type_argument_expected;
|
||||
case ParsingContext.TupleElementTypes: return Diagnostics.Type_expected;
|
||||
case ParsingContext.HeritageClauses: return Diagnostics.Unexpected_token_expected;
|
||||
case ParsingContext.ImportOrExportSpecifiers: return Diagnostics.Identifier_expected;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1476,7 +1498,10 @@ module ts {
|
||||
// 'const' is only a modifier if followed by 'enum'.
|
||||
return nextToken() === SyntaxKind.EnumKeyword;
|
||||
}
|
||||
|
||||
if (token === SyntaxKind.ExportKeyword) {
|
||||
nextToken();
|
||||
return token !== SyntaxKind.AsteriskToken && token !== SyntaxKind.OpenBraceToken && canFollowModifier();
|
||||
}
|
||||
nextToken();
|
||||
return canFollowModifier();
|
||||
}
|
||||
@@ -1536,6 +1561,8 @@ module ts {
|
||||
return token === SyntaxKind.CommaToken || isStartOfType();
|
||||
case ParsingContext.HeritageClauses:
|
||||
return isHeritageClause();
|
||||
case ParsingContext.ImportOrExportSpecifiers:
|
||||
return isIdentifierOrKeyword();
|
||||
}
|
||||
|
||||
Debug.fail("Non-exhaustive case in 'isListElement'.");
|
||||
@@ -1572,6 +1599,7 @@ module ts {
|
||||
case ParsingContext.EnumMembers:
|
||||
case ParsingContext.ObjectLiteralMembers:
|
||||
case ParsingContext.ObjectBindingElements:
|
||||
case ParsingContext.ImportOrExportSpecifiers:
|
||||
return token === SyntaxKind.CloseBraceToken;
|
||||
case ParsingContext.SwitchClauseStatements:
|
||||
return token === SyntaxKind.CloseBraceToken || token === SyntaxKind.CaseKeyword || token === SyntaxKind.DefaultKeyword;
|
||||
@@ -1597,7 +1625,6 @@ module ts {
|
||||
return token === SyntaxKind.GreaterThanToken || token === SyntaxKind.OpenParenToken;
|
||||
case ParsingContext.HeritageClauses:
|
||||
return token === SyntaxKind.OpenBraceToken || token === SyntaxKind.CloseBraceToken;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1832,6 +1859,8 @@ module ts {
|
||||
if (node) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
case SyntaxKind.ExportAssignment:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
@@ -4622,15 +4651,75 @@ module ts {
|
||||
return nextToken() === SyntaxKind.OpenParenToken;
|
||||
}
|
||||
|
||||
function parseImportDeclaration(fullStart: number, modifiers: ModifiersArray): ImportDeclaration {
|
||||
var node = <ImportDeclaration>createNode(SyntaxKind.ImportDeclaration, fullStart);
|
||||
setModifiers(node, modifiers);
|
||||
function nextTokenIsCommaOrFromKeyword() {
|
||||
nextToken();
|
||||
return token === SyntaxKind.CommaToken ||
|
||||
token === SyntaxKind.FromKeyword;
|
||||
}
|
||||
|
||||
function parseImportDeclarationOrImportEqualsDeclaration(fullStart: number, modifiers: ModifiersArray): ImportEqualsDeclaration | ImportDeclaration {
|
||||
parseExpected(SyntaxKind.ImportKeyword);
|
||||
node.name = parseIdentifier();
|
||||
parseExpected(SyntaxKind.EqualsToken);
|
||||
node.moduleReference = parseModuleReference();
|
||||
var afterImportPos = scanner.getStartPos();
|
||||
|
||||
var identifier: Identifier;
|
||||
if (isIdentifier()) {
|
||||
identifier = parseIdentifier();
|
||||
if (token !== SyntaxKind.CommaToken && token !== SyntaxKind.FromKeyword) {
|
||||
// ImportEquals declaration of type:
|
||||
// import x = require("mod"); or
|
||||
// import x = M.x;
|
||||
var importEqualsDeclaration = <ImportEqualsDeclaration>createNode(SyntaxKind.ImportEqualsDeclaration, fullStart);
|
||||
setModifiers(importEqualsDeclaration, modifiers);
|
||||
importEqualsDeclaration.name = identifier;
|
||||
parseExpected(SyntaxKind.EqualsToken);
|
||||
importEqualsDeclaration.moduleReference = parseModuleReference();
|
||||
parseSemicolon();
|
||||
return finishNode(importEqualsDeclaration);
|
||||
}
|
||||
}
|
||||
|
||||
// Import statement
|
||||
var importDeclaration = <ImportDeclaration>createNode(SyntaxKind.ImportDeclaration, fullStart);
|
||||
setModifiers(importDeclaration, modifiers);
|
||||
|
||||
// ImportDeclaration:
|
||||
// import ImportClause from ModuleSpecifier ;
|
||||
// import ModuleSpecifier;
|
||||
if (identifier || // import id
|
||||
token === SyntaxKind.AsteriskToken || // import *
|
||||
token === SyntaxKind.OpenBraceToken) { // import {
|
||||
importDeclaration.importClause = parseImportClause(identifier, afterImportPos);
|
||||
parseExpected(SyntaxKind.FromKeyword);
|
||||
}
|
||||
|
||||
importDeclaration.moduleSpecifier = parseModuleSpecifier();
|
||||
parseSemicolon();
|
||||
return finishNode(node);
|
||||
return finishNode(importDeclaration);
|
||||
}
|
||||
|
||||
function parseImportClause(identifier: Identifier, fullStart: number) {
|
||||
//ImportClause:
|
||||
// ImportedDefaultBinding
|
||||
// NameSpaceImport
|
||||
// NamedImports
|
||||
// ImportedDefaultBinding, NameSpaceImport
|
||||
// ImportedDefaultBinding, NamedImports
|
||||
|
||||
var importClause = <ImportClause>createNode(SyntaxKind.ImportClause, fullStart);
|
||||
if (identifier) {
|
||||
// ImportedDefaultBinding:
|
||||
// ImportedBinding
|
||||
importClause.name = identifier;
|
||||
}
|
||||
|
||||
// If there was no default import or if there is comma token after default import
|
||||
// parse namespace or named imports
|
||||
if (!importClause.name ||
|
||||
parseOptional(SyntaxKind.CommaToken)) {
|
||||
importClause.namedBindings = token === SyntaxKind.AsteriskToken ? parseNamespaceImport() : parseNamedImportsOrExports(SyntaxKind.NamedImports);
|
||||
}
|
||||
|
||||
return finishNode(importClause);
|
||||
}
|
||||
|
||||
function parseModuleReference() {
|
||||
@@ -4643,19 +4732,102 @@ module ts {
|
||||
var node = <ExternalModuleReference>createNode(SyntaxKind.ExternalModuleReference);
|
||||
parseExpected(SyntaxKind.RequireKeyword);
|
||||
parseExpected(SyntaxKind.OpenParenToken);
|
||||
node.expression = parseModuleSpecifier();
|
||||
parseExpected(SyntaxKind.CloseParenToken);
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseModuleSpecifier(): Expression {
|
||||
// We allow arbitrary expressions here, even though the grammar only allows string
|
||||
// literals. We check to ensure that it is only a string literal later in the grammar
|
||||
// walker.
|
||||
node.expression = parseExpression();
|
||||
|
||||
var result = parseExpression();
|
||||
// Ensure the string being required is in our 'identifier' table. This will ensure
|
||||
// that features like 'find refs' will look inside this file when search for its name.
|
||||
if (node.expression.kind === SyntaxKind.StringLiteral) {
|
||||
internIdentifier((<LiteralExpression>node.expression).text);
|
||||
if (result.kind === SyntaxKind.StringLiteral) {
|
||||
internIdentifier((<LiteralExpression>result).text);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function parseNamespaceImport(): NamespaceImport {
|
||||
// NameSpaceImport:
|
||||
// * as ImportedBinding
|
||||
var namespaceImport = <NamespaceImport>createNode(SyntaxKind.NamespaceImport);
|
||||
parseExpected(SyntaxKind.AsteriskToken);
|
||||
parseExpected(SyntaxKind.AsKeyword);
|
||||
namespaceImport.name = parseIdentifier();
|
||||
return finishNode(namespaceImport);
|
||||
}
|
||||
|
||||
function parseNamedImportsOrExports(kind: SyntaxKind): NamedImportsOrExports {
|
||||
var node = <NamedImports>createNode(kind);
|
||||
|
||||
// NamedImports:
|
||||
// { }
|
||||
// { ImportsList }
|
||||
// { ImportsList, }
|
||||
|
||||
// ImportsList:
|
||||
// ImportSpecifier
|
||||
// ImportsList, ImportSpecifier
|
||||
node.elements = parseBracketedList(ParsingContext.ImportOrExportSpecifiers,
|
||||
kind === SyntaxKind.NamedImports ? parseImportSpecifier : parseExportSpecifier,
|
||||
SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken);
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseExportSpecifier() {
|
||||
return parseImportOrExportSpecifier(SyntaxKind.ExportSpecifier);
|
||||
}
|
||||
|
||||
function parseImportSpecifier() {
|
||||
return parseImportOrExportSpecifier(SyntaxKind.ImportSpecifier);
|
||||
}
|
||||
|
||||
function parseImportOrExportSpecifier(kind: SyntaxKind): ImportOrExportSpecifier {
|
||||
var node = <ImportSpecifier>createNode(kind);
|
||||
// ImportSpecifier:
|
||||
// ImportedBinding
|
||||
// IdentifierName as ImportedBinding
|
||||
var isFirstIdentifierNameNotAnIdentifier = isKeyword(token) && !isIdentifier();
|
||||
var start = scanner.getTokenPos();
|
||||
var identifierName = parseIdentifierName();
|
||||
if (token === SyntaxKind.AsKeyword) {
|
||||
node.propertyName = identifierName;
|
||||
parseExpected(SyntaxKind.AsKeyword);
|
||||
if (isIdentifier()) {
|
||||
node.name = parseIdentifierName();
|
||||
}
|
||||
else {
|
||||
parseErrorAtCurrentToken(Diagnostics.Identifier_expected);
|
||||
}
|
||||
}
|
||||
else {
|
||||
node.name = identifierName;
|
||||
if (isFirstIdentifierNameNotAnIdentifier) {
|
||||
// Report error identifier expected
|
||||
parseErrorAtPosition(start, identifierName.end - start, Diagnostics.Identifier_expected);
|
||||
}
|
||||
}
|
||||
|
||||
parseExpected(SyntaxKind.CloseParenToken);
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseExportDeclaration(fullStart: number, modifiers: ModifiersArray): ExportDeclaration {
|
||||
var node = <ExportDeclaration>createNode(SyntaxKind.ExportDeclaration, fullStart);
|
||||
setModifiers(node, modifiers);
|
||||
if (parseOptional(SyntaxKind.AsteriskToken)) {
|
||||
parseExpected(SyntaxKind.FromKeyword);
|
||||
node.moduleSpecifier = parseModuleSpecifier();
|
||||
}
|
||||
else {
|
||||
node.exportClause = parseNamedImportsOrExports(SyntaxKind.NamedExports);
|
||||
if (parseOptional(SyntaxKind.FromKeyword)) {
|
||||
node.moduleSpecifier = parseModuleSpecifier();
|
||||
}
|
||||
}
|
||||
parseSemicolon();
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
@@ -4684,16 +4856,18 @@ module ts {
|
||||
case SyntaxKind.ClassKeyword:
|
||||
case SyntaxKind.InterfaceKeyword:
|
||||
case SyntaxKind.EnumKeyword:
|
||||
case SyntaxKind.ImportKeyword:
|
||||
case SyntaxKind.TypeKeyword:
|
||||
// Not true keywords so ensure an identifier follows
|
||||
return lookAhead(nextTokenIsIdentifierOrKeyword);
|
||||
case SyntaxKind.ImportKeyword:
|
||||
// Not true keywords so ensure an identifier follows or is string literal or asterisk or open brace
|
||||
return lookAhead(nextTokenCanFollowImportKeyword);
|
||||
case SyntaxKind.ModuleKeyword:
|
||||
// Not a true keyword so ensure an identifier or string literal follows
|
||||
return lookAhead(nextTokenIsIdentifierOrKeywordOrStringLiteral);
|
||||
case SyntaxKind.ExportKeyword:
|
||||
// Check for export assignment or modifier on source element
|
||||
return lookAhead(nextTokenIsEqualsTokenOrDeclarationStart);
|
||||
return lookAhead(nextTokenCanFollowExportKeyword);
|
||||
case SyntaxKind.DeclareKeyword:
|
||||
case SyntaxKind.PublicKeyword:
|
||||
case SyntaxKind.PrivateKeyword:
|
||||
@@ -4718,9 +4892,16 @@ module ts {
|
||||
return isIdentifierOrKeyword() || token === SyntaxKind.StringLiteral;
|
||||
}
|
||||
|
||||
function nextTokenIsEqualsTokenOrDeclarationStart() {
|
||||
function nextTokenCanFollowImportKeyword() {
|
||||
nextToken();
|
||||
return token === SyntaxKind.EqualsToken || isDeclarationStart();
|
||||
return isIdentifierOrKeyword() || token === SyntaxKind.StringLiteral ||
|
||||
token === SyntaxKind.AsteriskToken || token === SyntaxKind.OpenBraceToken;
|
||||
}
|
||||
|
||||
function nextTokenCanFollowExportKeyword() {
|
||||
nextToken();
|
||||
return token === SyntaxKind.EqualsToken || token === SyntaxKind.AsteriskToken ||
|
||||
token === SyntaxKind.OpenBraceToken || isDeclarationStart();
|
||||
}
|
||||
|
||||
function nextTokenIsDeclarationStart() {
|
||||
@@ -4728,6 +4909,10 @@ module ts {
|
||||
return isDeclarationStart();
|
||||
}
|
||||
|
||||
function nextTokenIsAsKeyword() {
|
||||
return nextToken() === SyntaxKind.AsKeyword;
|
||||
}
|
||||
|
||||
function parseDeclaration(): ModuleElement {
|
||||
var fullStart = getNodePos();
|
||||
var modifiers = parseModifiers();
|
||||
@@ -4736,6 +4921,9 @@ module ts {
|
||||
if (parseOptional(SyntaxKind.EqualsToken)) {
|
||||
return parseExportAssignmentTail(fullStart, modifiers);
|
||||
}
|
||||
if (token === SyntaxKind.AsteriskToken || token === SyntaxKind.OpenBraceToken) {
|
||||
return parseExportDeclaration(fullStart, modifiers);
|
||||
}
|
||||
}
|
||||
|
||||
switch (token) {
|
||||
@@ -4756,7 +4944,7 @@ module ts {
|
||||
case SyntaxKind.ModuleKeyword:
|
||||
return parseModuleDeclaration(fullStart, modifiers);
|
||||
case SyntaxKind.ImportKeyword:
|
||||
return parseImportDeclaration(fullStart, modifiers);
|
||||
return parseImportDeclarationOrImportEqualsDeclaration(fullStart, modifiers);
|
||||
default:
|
||||
Debug.fail("Mismatch between isDeclarationStart and parseDeclaration");
|
||||
}
|
||||
@@ -4846,8 +5034,10 @@ module ts {
|
||||
function setExternalModuleIndicator(sourceFile: SourceFile) {
|
||||
sourceFile.externalModuleIndicator = forEach(sourceFile.statements, node =>
|
||||
node.flags & NodeFlags.Export
|
||||
|| node.kind === SyntaxKind.ImportDeclaration && (<ImportDeclaration>node).moduleReference.kind === SyntaxKind.ExternalModuleReference
|
||||
|| node.kind === SyntaxKind.ImportEqualsDeclaration && (<ImportEqualsDeclaration>node).moduleReference.kind === SyntaxKind.ExternalModuleReference
|
||||
|| node.kind === SyntaxKind.ImportDeclaration
|
||||
|| node.kind === SyntaxKind.ExportAssignment
|
||||
|| node.kind === SyntaxKind.ExportDeclaration
|
||||
? node
|
||||
: undefined);
|
||||
}
|
||||
|
||||
+20
-21
@@ -351,24 +351,23 @@ module ts {
|
||||
|
||||
function processImportedModules(file: SourceFile, basePath: string) {
|
||||
forEach(file.statements, node => {
|
||||
if (isExternalModuleImportDeclaration(node) &&
|
||||
getExternalModuleImportDeclarationExpression(node).kind === SyntaxKind.StringLiteral) {
|
||||
|
||||
var nameLiteral = <LiteralExpression>getExternalModuleImportDeclarationExpression(node);
|
||||
var moduleName = nameLiteral.text;
|
||||
if (moduleName) {
|
||||
var searchPath = basePath;
|
||||
while (true) {
|
||||
var searchName = normalizePath(combinePaths(searchPath, moduleName));
|
||||
if (findModuleSourceFile(searchName + ".ts", nameLiteral) || findModuleSourceFile(searchName + ".d.ts", nameLiteral)) {
|
||||
break;
|
||||
if (node.kind === SyntaxKind.ImportDeclaration || node.kind === SyntaxKind.ImportEqualsDeclaration || node.kind === SyntaxKind.ExportDeclaration) {
|
||||
var moduleNameExpr = getExternalModuleName(node);
|
||||
if (moduleNameExpr && moduleNameExpr.kind === SyntaxKind.StringLiteral) {
|
||||
var moduleNameText = (<LiteralExpression>moduleNameExpr).text;
|
||||
if (moduleNameText) {
|
||||
var searchPath = basePath;
|
||||
while (true) {
|
||||
var searchName = normalizePath(combinePaths(searchPath, moduleNameText));
|
||||
if (findModuleSourceFile(searchName + ".ts", moduleNameExpr) || findModuleSourceFile(searchName + ".d.ts", moduleNameExpr)) {
|
||||
break;
|
||||
}
|
||||
var parentPath = getDirectoryPath(searchPath);
|
||||
if (parentPath === searchPath) {
|
||||
break;
|
||||
}
|
||||
searchPath = parentPath;
|
||||
}
|
||||
|
||||
var parentPath = getDirectoryPath(searchPath);
|
||||
if (parentPath === searchPath) {
|
||||
break;
|
||||
}
|
||||
searchPath = parentPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -379,10 +378,10 @@ module ts {
|
||||
// The StringLiteral must specify a top - level external module name.
|
||||
// Relative external module names are not permitted
|
||||
forEachChild((<ModuleDeclaration>node).body, node => {
|
||||
if (isExternalModuleImportDeclaration(node) &&
|
||||
getExternalModuleImportDeclarationExpression(node).kind === SyntaxKind.StringLiteral) {
|
||||
if (isExternalModuleImportEqualsDeclaration(node) &&
|
||||
getExternalModuleImportEqualsDeclarationExpression(node).kind === SyntaxKind.StringLiteral) {
|
||||
|
||||
var nameLiteral = <LiteralExpression>getExternalModuleImportDeclarationExpression(node);
|
||||
var nameLiteral = <LiteralExpression>getExternalModuleImportEqualsDeclarationExpression(node);
|
||||
var moduleName = nameLiteral.text;
|
||||
if (moduleName) {
|
||||
// TypeScript 1.0 spec (April 2014): 12.1.6
|
||||
@@ -399,7 +398,7 @@ module ts {
|
||||
}
|
||||
});
|
||||
|
||||
function findModuleSourceFile(fileName: string, nameLiteral: LiteralExpression) {
|
||||
function findModuleSourceFile(fileName: string, nameLiteral: Expression) {
|
||||
return findSourceFile(fileName, /* isDefaultLib */ false, file, nameLiteral.pos, nameLiteral.end - nameLiteral.pos);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ module ts {
|
||||
|
||||
var textToToken: Map<SyntaxKind> = {
|
||||
"any": SyntaxKind.AnyKeyword,
|
||||
"as": SyntaxKind.AsKeyword,
|
||||
"boolean": SyntaxKind.BooleanKeyword,
|
||||
"break": SyntaxKind.BreakKeyword,
|
||||
"case": SyntaxKind.CaseKeyword,
|
||||
@@ -58,6 +59,7 @@ module ts {
|
||||
"false": SyntaxKind.FalseKeyword,
|
||||
"finally": SyntaxKind.FinallyKeyword,
|
||||
"for": SyntaxKind.ForKeyword,
|
||||
"from": SyntaxKind.FromKeyword,
|
||||
"function": SyntaxKind.FunctionKeyword,
|
||||
"get": SyntaxKind.GetKeyword,
|
||||
"if": SyntaxKind.IfKeyword,
|
||||
|
||||
+80
-19
@@ -120,6 +120,8 @@ module ts {
|
||||
WhileKeyword,
|
||||
WithKeyword,
|
||||
// Strict mode reserved words
|
||||
AsKeyword,
|
||||
FromKeyword,
|
||||
ImplementsKeyword,
|
||||
InterfaceKeyword,
|
||||
LetKeyword,
|
||||
@@ -230,8 +232,16 @@ module ts {
|
||||
EnumDeclaration,
|
||||
ModuleDeclaration,
|
||||
ModuleBlock,
|
||||
ImportEqualsDeclaration,
|
||||
ImportDeclaration,
|
||||
ImportClause,
|
||||
NamespaceImport,
|
||||
NamedImports,
|
||||
ImportSpecifier,
|
||||
ExportAssignment,
|
||||
ExportDeclaration,
|
||||
NamedExports,
|
||||
ExportSpecifier,
|
||||
|
||||
// Module references
|
||||
ExternalModuleReference,
|
||||
@@ -344,13 +354,13 @@ module ts {
|
||||
// Specific context the parser was in when this node was created. Normally undefined.
|
||||
// Only set when the parser was in some interesting context (like async/yield).
|
||||
parserContextFlags?: ParserContextFlags;
|
||||
modifiers?: ModifiersArray; // Array of modifiers
|
||||
id?: number; // Unique id (used to look up NodeLinks)
|
||||
parent?: Node; // Parent node (initialized by binding)
|
||||
symbol?: Symbol; // Symbol declared by node (initialized by binding)
|
||||
locals?: SymbolTable; // Locals associated with node (initialized by binding)
|
||||
nextContainer?: Node; // Next container in declaration order (initialized by binding)
|
||||
localSymbol?: Symbol; // Local symbol declared by node (initialized by binding only for exported nodes)
|
||||
modifiers?: ModifiersArray; // Array of modifiers
|
||||
}
|
||||
|
||||
export interface NodeArray<T> extends Array<T>, TextRange {
|
||||
@@ -853,7 +863,11 @@ module ts {
|
||||
members: NodeArray<EnumMember>;
|
||||
}
|
||||
|
||||
export interface ModuleDeclaration extends Declaration, ModuleElement {
|
||||
export interface ExportContainer {
|
||||
exportStars?: ExportDeclaration[]; // List of 'export *' statements (initialized by binding)
|
||||
}
|
||||
|
||||
export interface ModuleDeclaration extends Declaration, ModuleElement, ExportContainer {
|
||||
name: Identifier | LiteralExpression;
|
||||
body: ModuleBlock | ModuleDeclaration;
|
||||
}
|
||||
@@ -862,7 +876,7 @@ module ts {
|
||||
statements: NodeArray<ModuleElement>
|
||||
}
|
||||
|
||||
export interface ImportDeclaration extends Declaration, ModuleElement {
|
||||
export interface ImportEqualsDeclaration extends Declaration, ModuleElement {
|
||||
name: Identifier;
|
||||
|
||||
// 'EntityName' for an internal module reference, 'ExternalModuleReference' for an external
|
||||
@@ -874,6 +888,50 @@ module ts {
|
||||
expression?: Expression;
|
||||
}
|
||||
|
||||
// In case of:
|
||||
// import "mod" => importClause = undefined, moduleSpecifier = "mod"
|
||||
// In rest of the cases, module specifier is string literal corresponding to module
|
||||
// ImportClause information is shown at its declaration below.
|
||||
export interface ImportDeclaration extends Statement, ModuleElement {
|
||||
importClause?: ImportClause;
|
||||
moduleSpecifier: Expression;
|
||||
}
|
||||
|
||||
// In case of:
|
||||
// import d from "mod" => name = d, namedBinding = undefined
|
||||
// import * as ns from "mod" => name = undefined, namedBinding: NamespaceImport = { name: ns }
|
||||
// import d, * as ns from "mod" => name = d, namedBinding: NamespaceImport = { name: ns }
|
||||
// import { a, b as x } from "mod" => name = undefined, namedBinding: NamedImports = { elements: [{ name: a }, { name: x, propertyName: b}]}
|
||||
// import d, { a, b as x } from "mod" => name = d, namedBinding: NamedImports = { elements: [{ name: a }, { name: x, propertyName: b}]}
|
||||
export interface ImportClause extends Declaration {
|
||||
name?: Identifier; // Default binding
|
||||
namedBindings?: NamespaceImport | NamedImports;
|
||||
}
|
||||
|
||||
export interface NamespaceImport extends Declaration {
|
||||
name: Identifier;
|
||||
}
|
||||
|
||||
export interface ExportDeclaration extends Statement, ModuleElement {
|
||||
exportClause?: NamedExports;
|
||||
moduleSpecifier?: Expression;
|
||||
}
|
||||
|
||||
export interface NamedImportsOrExports extends Node {
|
||||
elements: NodeArray<ImportOrExportSpecifier>;
|
||||
}
|
||||
|
||||
export type NamedImports = NamedImportsOrExports;
|
||||
export type NamedExports = NamedImportsOrExports;
|
||||
|
||||
export interface ImportOrExportSpecifier extends Declaration {
|
||||
propertyName?: Identifier; // Name preceding "as" keyword (or undefined when "as" is absent)
|
||||
name: Identifier; // Declared name
|
||||
}
|
||||
|
||||
export type ImportSpecifier = ImportOrExportSpecifier;
|
||||
export type ExportSpecifier = ImportOrExportSpecifier;
|
||||
|
||||
export interface ExportAssignment extends Statement, ModuleElement {
|
||||
exportName: Identifier;
|
||||
}
|
||||
@@ -887,7 +945,7 @@ module ts {
|
||||
}
|
||||
|
||||
// Source files are declarations when they are external modules.
|
||||
export interface SourceFile extends Declaration {
|
||||
export interface SourceFile extends Declaration, ExportContainer {
|
||||
statements: NodeArray<ModuleElement>;
|
||||
endOfFileToken: Node;
|
||||
|
||||
@@ -1120,7 +1178,7 @@ module ts {
|
||||
|
||||
export interface SymbolVisibilityResult {
|
||||
accessibility: SymbolAccessibility;
|
||||
aliasesToMakeVisible?: ImportDeclaration[]; // aliases that need to have this symbol visible
|
||||
aliasesToMakeVisible?: ImportEqualsDeclaration[]; // aliases that need to have this symbol visible
|
||||
errorSymbolName?: string; // Optional symbol name that results in error
|
||||
errorNode?: Node; // optional node that results in error
|
||||
}
|
||||
@@ -1130,11 +1188,11 @@ module ts {
|
||||
}
|
||||
|
||||
export interface EmitResolver {
|
||||
getLocalNameOfContainer(container: ModuleDeclaration | EnumDeclaration): string;
|
||||
getExpressionNamePrefix(node: Identifier): string;
|
||||
getGeneratedNameForNode(node: ModuleDeclaration | EnumDeclaration | ImportDeclaration | ExportDeclaration): string;
|
||||
getExpressionNameSubstitution(node: Identifier): string;
|
||||
getExportAssignmentName(node: SourceFile): string;
|
||||
isReferencedImportDeclaration(node: ImportDeclaration): boolean;
|
||||
isTopLevelValueImportWithEntityName(node: ImportDeclaration): boolean;
|
||||
isReferencedImportDeclaration(node: Node): boolean;
|
||||
isTopLevelValueImportEqualsWithEntityName(node: ImportEqualsDeclaration): boolean;
|
||||
getNodeCheckFlags(node: Node): NodeCheckFlags;
|
||||
isDeclarationVisible(node: Declaration): boolean;
|
||||
isImplementationOfOverload(node: FunctionLikeDeclaration): boolean;
|
||||
@@ -1237,18 +1295,20 @@ module ts {
|
||||
members?: SymbolTable; // Class, interface or literal instance members
|
||||
exports?: SymbolTable; // Module exports
|
||||
exportSymbol?: Symbol; // Exported symbol associated with this symbol
|
||||
valueDeclaration?: Declaration // First value declaration of the symbol,
|
||||
constEnumOnlyModule?: boolean // For modules - if true - module contains only const enums or other modules with only const enums.
|
||||
valueDeclaration?: Declaration // First value declaration of the symbol
|
||||
constEnumOnlyModule?: boolean // True if module contains only const enums or other modules with only const enums
|
||||
}
|
||||
|
||||
export interface SymbolLinks {
|
||||
target?: Symbol; // Resolved (non-alias) target of an alias
|
||||
type?: Type; // Type of value symbol
|
||||
declaredType?: Type; // Type of class, interface, enum, or type parameter
|
||||
mapper?: TypeMapper; // Type mapper for instantiation alias
|
||||
referenced?: boolean; // True if alias symbol has been referenced as a value
|
||||
exportAssignSymbol?: Symbol; // Symbol exported from external module
|
||||
unionType?: UnionType; // Containing union type for union property
|
||||
target?: Symbol; // Resolved (non-alias) target of an alias
|
||||
type?: Type; // Type of value symbol
|
||||
declaredType?: Type; // Type of class, interface, enum, or type parameter
|
||||
mapper?: TypeMapper; // Type mapper for instantiation alias
|
||||
referenced?: boolean; // True if alias symbol has been referenced as a value
|
||||
exportAssignmentChecked?: boolean; // True if export assignment was checked
|
||||
exportAssignmentSymbol?: Symbol; // Symbol exported from external module
|
||||
unionType?: UnionType; // Containing union type for union property
|
||||
resolvedExports?: SymbolTable; // Resolved exports of module
|
||||
}
|
||||
|
||||
export interface TransientSymbol extends Symbol, SymbolLinks { }
|
||||
@@ -1278,7 +1338,8 @@ module ts {
|
||||
enumMemberValue?: number; // Constant value of enum member
|
||||
isIllegalTypeReferenceInConstraint?: boolean; // Is type reference in constraint refers to the type parameter from the same list
|
||||
isVisible?: boolean; // Is this node visible
|
||||
localModuleName?: string; // Local name for module instance
|
||||
generatedName?: string; // Generated name for module, enum, or import declaration
|
||||
generatedNames?: Map<string>; // Generated names table for source file
|
||||
assignmentChecks?: Map<boolean>; // Cache of assignment checks
|
||||
hasReportedStatementInAmbientContext?: boolean; // Cache boolean if we report statements in ambient context
|
||||
importOnRightSide?: Symbol; // for import declarations - import that appear on the right side
|
||||
|
||||
+38
-37
@@ -186,6 +186,12 @@ module ts {
|
||||
return identifier.length >= 3 && identifier.charCodeAt(0) === CharacterCodes._ && identifier.charCodeAt(1) === CharacterCodes._ && identifier.charCodeAt(2) === CharacterCodes._ ? identifier.substr(1) : identifier;
|
||||
}
|
||||
|
||||
// Make an identifier from an external module name by extracting the string after the last "/" and replacing
|
||||
// all non-alphanumeric characters with underscores
|
||||
export function makeIdentifierFromModuleName(moduleName: string): string {
|
||||
return getBaseFileName(moduleName).replace(/\W/g, "_");
|
||||
}
|
||||
|
||||
// Return display name of an identifier
|
||||
// Computed property names will just be emitted as "[<expr>]", where <expr> is the source
|
||||
// text of the expression in the computed property.
|
||||
@@ -591,17 +597,32 @@ module ts {
|
||||
(preserveConstEnums && moduleState === ModuleInstanceState.ConstEnumOnly);
|
||||
}
|
||||
|
||||
export function isExternalModuleImportDeclaration(node: Node) {
|
||||
return node.kind === SyntaxKind.ImportDeclaration && (<ImportDeclaration>node).moduleReference.kind === SyntaxKind.ExternalModuleReference;
|
||||
export function isExternalModuleImportEqualsDeclaration(node: Node) {
|
||||
return node.kind === SyntaxKind.ImportEqualsDeclaration && (<ImportEqualsDeclaration>node).moduleReference.kind === SyntaxKind.ExternalModuleReference;
|
||||
}
|
||||
|
||||
export function getExternalModuleImportDeclarationExpression(node: Node) {
|
||||
Debug.assert(isExternalModuleImportDeclaration(node));
|
||||
return (<ExternalModuleReference>(<ImportDeclaration>node).moduleReference).expression;
|
||||
export function getExternalModuleImportEqualsDeclarationExpression(node: Node) {
|
||||
Debug.assert(isExternalModuleImportEqualsDeclaration(node));
|
||||
return (<ExternalModuleReference>(<ImportEqualsDeclaration>node).moduleReference).expression;
|
||||
}
|
||||
|
||||
export function isInternalModuleImportDeclaration(node: Node) {
|
||||
return node.kind === SyntaxKind.ImportDeclaration && (<ImportDeclaration>node).moduleReference.kind !== SyntaxKind.ExternalModuleReference;
|
||||
export function isInternalModuleImportEqualsDeclaration(node: Node) {
|
||||
return node.kind === SyntaxKind.ImportEqualsDeclaration && (<ImportEqualsDeclaration>node).moduleReference.kind !== SyntaxKind.ExternalModuleReference;
|
||||
}
|
||||
|
||||
export function getExternalModuleName(node: Node): Expression {
|
||||
if (node.kind === SyntaxKind.ImportDeclaration) {
|
||||
return (<ImportDeclaration>node).moduleSpecifier;
|
||||
}
|
||||
if (node.kind === SyntaxKind.ImportEqualsDeclaration) {
|
||||
var reference = (<ImportEqualsDeclaration>node).moduleReference;
|
||||
if (reference.kind === SyntaxKind.ExternalModuleReference) {
|
||||
return (<ExternalModuleReference>reference).expression;
|
||||
}
|
||||
}
|
||||
if (node.kind === SyntaxKind.ExportDeclaration) {
|
||||
return (<ExportDeclaration>node).moduleSpecifier;
|
||||
}
|
||||
}
|
||||
|
||||
export function hasDotDotDotToken(node: Node) {
|
||||
@@ -680,7 +701,11 @@ module ts {
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
case SyntaxKind.ImportClause:
|
||||
case SyntaxKind.ImportSpecifier:
|
||||
case SyntaxKind.NamespaceImport:
|
||||
case SyntaxKind.ExportSpecifier:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -767,36 +792,12 @@ module ts {
|
||||
}
|
||||
|
||||
export function getAncestor(node: Node, kind: SyntaxKind): Node {
|
||||
switch (kind) {
|
||||
// special-cases that can be come first
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
while (node) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
return <ClassDeclaration>node;
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
// early exit cases - declarations cannot be nested in classes
|
||||
return undefined;
|
||||
default:
|
||||
node = node.parent;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
while (node) {
|
||||
if (node.kind === kind) {
|
||||
return node;
|
||||
}
|
||||
node = node.parent;
|
||||
}
|
||||
break;
|
||||
while (node) {
|
||||
if (node.kind === kind) {
|
||||
return node;
|
||||
}
|
||||
node = node.parent;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -208,9 +208,9 @@ module ts.server {
|
||||
return response.body[0];
|
||||
}
|
||||
|
||||
getNavigateToItems(searchTerm: string): NavigateToItem[] {
|
||||
getNavigateToItems(searchValue: string): NavigateToItem[] {
|
||||
var args: protocol.NavtoRequestArgs = {
|
||||
searchTerm,
|
||||
searchValue,
|
||||
file: this.host.getScriptFileNames()[0]
|
||||
};
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ module ts.server {
|
||||
ls: ts.LanguageService = null;
|
||||
compilationSettings: ts.CompilerOptions;
|
||||
filenameToScript: ts.Map<ScriptInfo> = {};
|
||||
roots: ScriptInfo[] = [];
|
||||
|
||||
constructor(public host: ServerHost, public project: Project) {
|
||||
}
|
||||
@@ -144,7 +145,7 @@ module ts.server {
|
||||
var scriptInfo = ts.lookUp(this.filenameToScript, info.fileName);
|
||||
if (!scriptInfo) {
|
||||
this.filenameToScript[info.fileName] = info;
|
||||
return info;
|
||||
this.roots.push(info);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,10 +287,12 @@ module ts.server {
|
||||
return this.filenameToSourceFile[info.fileName];
|
||||
}
|
||||
|
||||
getSourceFileFromName(filename: string) {
|
||||
getSourceFileFromName(filename: string, requireOpen?: boolean) {
|
||||
var info = this.projectService.getScriptInfo(filename);
|
||||
if (info) {
|
||||
return this.getSourceFile(info);
|
||||
if ((!requireOpen) || info.isOpen) {
|
||||
return this.getSourceFile(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -324,7 +327,7 @@ module ts.server {
|
||||
// add a root file to project
|
||||
addRoot(info: ScriptInfo) {
|
||||
info.defaultProject = this;
|
||||
return this.compilerService.host.addRoot(info);
|
||||
this.compilerService.host.addRoot(info);
|
||||
}
|
||||
|
||||
filesToString() {
|
||||
@@ -360,7 +363,7 @@ module ts.server {
|
||||
}
|
||||
|
||||
interface ProjectServiceEventHandler {
|
||||
(eventName: string, project: Project): void;
|
||||
(eventName: string, project: Project, fileName: string): void;
|
||||
}
|
||||
|
||||
export class ProjectService {
|
||||
@@ -392,7 +395,6 @@ module ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
log(msg: string, type = "Err") {
|
||||
this.psLogger.msg(msg, type);
|
||||
}
|
||||
@@ -423,7 +425,20 @@ module ts.server {
|
||||
for (var i = 0, len = referencingProjects.length; i < len; i++) {
|
||||
referencingProjects[i].removeReferencedFile(info);
|
||||
}
|
||||
for (var j = 0, flen = this.openFileRoots.length; j < flen; j++) {
|
||||
var openFile = this.openFileRoots[j];
|
||||
if (this.eventHandler) {
|
||||
this.eventHandler("context", openFile.defaultProject, openFile.fileName);
|
||||
}
|
||||
}
|
||||
for (var j = 0, flen = this.openFilesReferenced.length; j < flen; j++) {
|
||||
var openFile = this.openFilesReferenced[j];
|
||||
if (this.eventHandler) {
|
||||
this.eventHandler("context", openFile.defaultProject, openFile.fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.printProjects();
|
||||
}
|
||||
|
||||
@@ -503,19 +518,52 @@ module ts.server {
|
||||
info.close();
|
||||
}
|
||||
|
||||
findReferencingProjects(info: ScriptInfo) {
|
||||
findReferencingProjects(info: ScriptInfo, excludedProject?: Project) {
|
||||
var referencingProjects: Project[] = [];
|
||||
info.defaultProject = undefined;
|
||||
for (var i = 0, len = this.inferredProjects.length; i < len; i++) {
|
||||
this.inferredProjects[i].updateGraph();
|
||||
if (this.inferredProjects[i].getSourceFile(info)) {
|
||||
info.defaultProject = this.inferredProjects[i];
|
||||
referencingProjects.push(this.inferredProjects[i]);
|
||||
if (this.inferredProjects[i] != excludedProject) {
|
||||
if (this.inferredProjects[i].getSourceFile(info)) {
|
||||
info.defaultProject = this.inferredProjects[i];
|
||||
referencingProjects.push(this.inferredProjects[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return referencingProjects;
|
||||
}
|
||||
|
||||
updateProjectStructure() {
|
||||
this.log("updating project structure from ...", "Info");
|
||||
this.printProjects();
|
||||
for (var i = 0, len = this.openFilesReferenced.length; i < len; i++) {
|
||||
var refdFile = this.openFilesReferenced[i];
|
||||
refdFile.defaultProject.updateGraph();
|
||||
var sourceFile = refdFile.defaultProject.getSourceFile(refdFile);
|
||||
if (!sourceFile) {
|
||||
this.openFilesReferenced = copyListRemovingItem(refdFile, this.openFilesReferenced);
|
||||
this.addOpenFile(refdFile);
|
||||
}
|
||||
}
|
||||
var openFileRoots: ScriptInfo[] = [];
|
||||
for (var i = 0, len = this.openFileRoots.length; i < len; i++) {
|
||||
var rootFile = this.openFileRoots[i];
|
||||
var rootedProject = rootFile.defaultProject;
|
||||
var referencingProjects = this.findReferencingProjects(rootFile, rootedProject);
|
||||
if (referencingProjects.length == 0) {
|
||||
rootFile.defaultProject = rootedProject;
|
||||
openFileRoots.push(rootFile);
|
||||
}
|
||||
else {
|
||||
// remove project from inferred projects list
|
||||
this.inferredProjects = copyListRemovingItem(rootedProject, this.inferredProjects);
|
||||
this.openFilesReferenced.push(rootFile);
|
||||
}
|
||||
}
|
||||
this.openFileRoots = openFileRoots;
|
||||
this.printProjects();
|
||||
}
|
||||
|
||||
getScriptInfo(filename: string) {
|
||||
filename = ts.normalizePath(filename);
|
||||
return ts.lookUp(this.filenameToScriptInfo, filename);
|
||||
@@ -621,6 +669,7 @@ module ts.server {
|
||||
this.psLogger.startGroup();
|
||||
for (var i = 0, len = this.inferredProjects.length; i < len; i++) {
|
||||
var project = this.inferredProjects[i];
|
||||
project.updateGraph();
|
||||
this.psLogger.info("Project " + i.toString());
|
||||
this.psLogger.info(project.filesToString());
|
||||
this.psLogger.info("-----------------------------------------------");
|
||||
|
||||
Vendored
+5
-1
@@ -676,7 +676,11 @@ declare module ts.server.protocol {
|
||||
* Search term to navigate to from current location; term can
|
||||
* be '.*' or an identifier prefix.
|
||||
*/
|
||||
searchTerm: string;
|
||||
searchValue: string;
|
||||
/**
|
||||
* Optional limit on the number of items to return.
|
||||
*/
|
||||
maxResultCount?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -82,7 +82,6 @@ module ts.server {
|
||||
private watchedFiles: WatchedFile[] = [];
|
||||
private nextFileToCheck = 0;
|
||||
private watchTimer: NodeJS.Timer;
|
||||
private static fileDeleted = 34;
|
||||
|
||||
// average async stat takes about 30 microseconds
|
||||
// set chunk size to do 30 files in < 1 millisecond
|
||||
@@ -111,13 +110,7 @@ module ts.server {
|
||||
|
||||
fs.stat(watchedFile.fileName,(err, stats) => {
|
||||
if (err) {
|
||||
var msg = err.message;
|
||||
if (err.errno) {
|
||||
msg += " errno: " + err.errno.toString();
|
||||
}
|
||||
if (err.errno == WatchedFileSet.fileDeleted) {
|
||||
watchedFile.callback(watchedFile.fileName);
|
||||
}
|
||||
watchedFile.callback(watchedFile.fileName);
|
||||
}
|
||||
else if (watchedFile.mtime.getTime() != stats.mtime.getTime()) {
|
||||
watchedFile.mtime = WatchedFileSet.getModifiedTime(watchedFile.fileName);
|
||||
|
||||
+50
-42
@@ -52,30 +52,6 @@ module ts.server {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
function sortNavItems(items: ts.NavigateToItem[]) {
|
||||
return items.sort((a, b) => {
|
||||
if (a.matchKind < b.matchKind) {
|
||||
return -1;
|
||||
}
|
||||
else if (a.matchKind == b.matchKind) {
|
||||
var lowa = a.name.toLowerCase();
|
||||
var lowb = b.name.toLowerCase();
|
||||
if (lowa < lowb) {
|
||||
return -1;
|
||||
}
|
||||
else if (lowa == lowb) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function formatDiag(fileName: string, project: Project, diag: ts.Diagnostic) {
|
||||
return {
|
||||
@@ -122,7 +98,6 @@ module ts.server {
|
||||
|
||||
module Errors {
|
||||
export var NoProject = new Error("No Project.");
|
||||
export var NoContent = new Error("No Content.");
|
||||
}
|
||||
|
||||
export interface ServerHost extends ts.System {
|
||||
@@ -138,7 +113,18 @@ module ts.server {
|
||||
changeSeq = 0;
|
||||
|
||||
constructor(private host: ServerHost, private logger: Logger) {
|
||||
this.projectService = new ProjectService(host, logger);
|
||||
this.projectService =
|
||||
new ProjectService(host, logger, (eventName,project,fileName) => {
|
||||
this.handleEvent(eventName, project, fileName);
|
||||
});
|
||||
}
|
||||
|
||||
handleEvent(eventName: string, project: Project, fileName: string) {
|
||||
if (eventName == "context") {
|
||||
this.projectService.log("got context event, updating diagnostics for" + fileName, "Info");
|
||||
this.updateErrorCheck([{ fileName, project }], this.changeSeq,
|
||||
(n) => n == this.changeSeq, 100);
|
||||
}
|
||||
}
|
||||
|
||||
logError(err: Error, cmd: string) {
|
||||
@@ -215,6 +201,14 @@ module ts.server {
|
||||
this.semanticCheck(file, project);
|
||||
}
|
||||
|
||||
updateProjectStructure(seq: number, matchSeq: (seq: number) => boolean, ms = 1500) {
|
||||
setTimeout(() => {
|
||||
if (matchSeq(seq)) {
|
||||
this.projectService.updateProjectStructure();
|
||||
}
|
||||
}, ms);
|
||||
}
|
||||
|
||||
updateErrorCheck(checkList: PendingErrorCheck[], seq: number,
|
||||
matchSeq: (seq: number) => boolean, ms = 1500, followMs = 200) {
|
||||
if (followMs > ms) {
|
||||
@@ -231,7 +225,7 @@ module ts.server {
|
||||
var checkOne = () => {
|
||||
if (matchSeq(seq)) {
|
||||
var checkSpec = checkList[index++];
|
||||
if (checkSpec.project.getSourceFileFromName(checkSpec.fileName)) {
|
||||
if (checkSpec.project.getSourceFileFromName(checkSpec.fileName, true)) {
|
||||
this.syntacticCheck(checkSpec.fileName, checkSpec.project);
|
||||
this.immediateId = setImmediate(() => {
|
||||
this.semanticCheck(checkSpec.fileName, checkSpec.project);
|
||||
@@ -263,7 +257,7 @@ module ts.server {
|
||||
|
||||
var definitions = compilerService.languageService.getDefinitionAtPosition(file, position);
|
||||
if (!definitions) {
|
||||
throw Errors.NoContent;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return definitions.map(def => ({
|
||||
@@ -284,7 +278,7 @@ module ts.server {
|
||||
var position = compilerService.host.lineColToPosition(file, line, col);
|
||||
var renameInfo = compilerService.languageService.getRenameInfo(file, position);
|
||||
if (!renameInfo) {
|
||||
throw Errors.NoContent;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (!renameInfo.canRename) {
|
||||
@@ -296,7 +290,7 @@ module ts.server {
|
||||
|
||||
var renameLocations = compilerService.languageService.findRenameLocations(file, position, findInStrings, findInComments);
|
||||
if (!renameLocations) {
|
||||
throw Errors.NoContent;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var bakedRenameLocs = renameLocations.map(location => (<protocol.FileSpan>{
|
||||
@@ -355,12 +349,12 @@ module ts.server {
|
||||
|
||||
var references = compilerService.languageService.getReferencesAtPosition(file, position);
|
||||
if (!references) {
|
||||
throw Errors.NoContent;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var nameInfo = compilerService.languageService.getQuickInfoAtPosition(file, position);
|
||||
if (!nameInfo) {
|
||||
throw Errors.NoContent;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var displayString = ts.displayPartsToString(nameInfo.displayParts);
|
||||
@@ -404,7 +398,7 @@ module ts.server {
|
||||
var position = compilerService.host.lineColToPosition(file, line, col);
|
||||
var quickInfo = compilerService.languageService.getQuickInfoAtPosition(file, position);
|
||||
if (!quickInfo) {
|
||||
throw Errors.NoContent;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var displayString = ts.displayPartsToString(quickInfo.displayParts);
|
||||
@@ -433,7 +427,7 @@ module ts.server {
|
||||
// TODO: avoid duplicate code (with formatonkey)
|
||||
var edits = compilerService.languageService.getFormattingEditsForRange(file, startPosition, endPosition, compilerService.formatCodeOptions);
|
||||
if (!edits) {
|
||||
throw Errors.NoContent;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return edits.map((edit) => {
|
||||
@@ -473,7 +467,7 @@ module ts.server {
|
||||
}
|
||||
|
||||
if (!edits) {
|
||||
throw Errors.NoContent;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return edits.map((edit) => {
|
||||
@@ -502,7 +496,7 @@ module ts.server {
|
||||
|
||||
var completions = compilerService.languageService.getCompletionsAtPosition(file, position);
|
||||
if (!completions) {
|
||||
throw Errors.NoContent;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return completions.entries.reduce((result: protocol.CompletionEntry[], entry: ts.CompletionEntry) => {
|
||||
@@ -559,6 +553,10 @@ module ts.server {
|
||||
compilerService.host.editScript(file, start, end, insertString);
|
||||
this.changeSeq++;
|
||||
}
|
||||
// update project structure on idle commented out
|
||||
// until we can have the host return only the root files
|
||||
// from getScriptFileNames()
|
||||
//this.updateProjectStructure(this.changeSeq, (n) => n == this.changeSeq);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -619,13 +617,13 @@ module ts.server {
|
||||
var compilerService = project.compilerService;
|
||||
var items = compilerService.languageService.getNavigationBarItems(file);
|
||||
if (!items) {
|
||||
throw Errors.NoContent;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return this.decorateNavigationBarItem(project, fileName, items);
|
||||
}
|
||||
|
||||
getNavigateToItems(searchTerm: string, fileName: string): protocol.NavtoItem[] {
|
||||
getNavigateToItems(searchValue: string, fileName: string, maxResultCount?: number): protocol.NavtoItem[] {
|
||||
var file = ts.normalizePath(fileName);
|
||||
var project = this.projectService.getProjectForFile(file);
|
||||
if (!project) {
|
||||
@@ -633,9 +631,9 @@ module ts.server {
|
||||
}
|
||||
|
||||
var compilerService = project.compilerService;
|
||||
var navItems = sortNavItems(compilerService.languageService.getNavigateToItems(searchTerm));
|
||||
var navItems = compilerService.languageService.getNavigateToItems(searchValue, maxResultCount);
|
||||
if (!navItems) {
|
||||
throw Errors.NoContent;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return navItems.map((navItem) => {
|
||||
@@ -677,7 +675,7 @@ module ts.server {
|
||||
|
||||
var spans = compilerService.languageService.getBraceMatchingAtPosition(file, position);
|
||||
if (!spans) {
|
||||
throw Errors.NoContent;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return spans.map(span => ({
|
||||
@@ -690,6 +688,8 @@ module ts.server {
|
||||
try {
|
||||
var request = <protocol.Request>JSON.parse(message);
|
||||
var response: any;
|
||||
var errorMessage: string;
|
||||
var responseRequired = true;
|
||||
switch (request.command) {
|
||||
case CommandNames.Definition: {
|
||||
var defArgs = <protocol.FileLocationRequestArgs>request.arguments;
|
||||
@@ -709,6 +709,7 @@ module ts.server {
|
||||
case CommandNames.Open: {
|
||||
var openArgs = <protocol.FileRequestArgs>request.arguments;
|
||||
this.openClientFile(openArgs.file);
|
||||
responseRequired = false;
|
||||
break;
|
||||
}
|
||||
case CommandNames.Quickinfo: {
|
||||
@@ -740,12 +741,14 @@ module ts.server {
|
||||
case CommandNames.Geterr: {
|
||||
var geterrArgs = <protocol.GeterrRequestArgs>request.arguments;
|
||||
response = this.getDiagnostics(geterrArgs.delay, geterrArgs.files);
|
||||
responseRequired = false;
|
||||
break;
|
||||
}
|
||||
case CommandNames.Change: {
|
||||
var changeArgs = <protocol.ChangeRequestArgs>request.arguments;
|
||||
this.change(changeArgs.line, changeArgs.col, changeArgs.endLine, changeArgs.endCol,
|
||||
changeArgs.insertString, changeArgs.file);
|
||||
responseRequired = false;
|
||||
break;
|
||||
}
|
||||
case CommandNames.Reload: {
|
||||
@@ -756,16 +759,18 @@ module ts.server {
|
||||
case CommandNames.Saveto: {
|
||||
var savetoArgs = <protocol.SavetoRequestArgs>request.arguments;
|
||||
this.saveToTmp(savetoArgs.file, savetoArgs.tmpfile);
|
||||
responseRequired = false;
|
||||
break;
|
||||
}
|
||||
case CommandNames.Close: {
|
||||
var closeArgs = <protocol.FileRequestArgs>request.arguments;
|
||||
this.closeClientFile(closeArgs.file);
|
||||
responseRequired = false;
|
||||
break;
|
||||
}
|
||||
case CommandNames.Navto: {
|
||||
var navtoArgs = <protocol.NavtoRequestArgs>request.arguments;
|
||||
response = this.getNavigateToItems(navtoArgs.searchTerm, navtoArgs.file);
|
||||
response = this.getNavigateToItems(navtoArgs.searchValue, navtoArgs.file, navtoArgs.maxResultCount);
|
||||
break;
|
||||
}
|
||||
case CommandNames.Brace: {
|
||||
@@ -788,6 +793,9 @@ module ts.server {
|
||||
if (response) {
|
||||
this.output(response, request.command, request.seq);
|
||||
}
|
||||
else if (responseRequired) {
|
||||
this.output(undefined, request.command, request.seq, "No content available.");
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
if (err instanceof OperationCanceledException) {
|
||||
|
||||
@@ -176,9 +176,9 @@ module ts.BreakpointResolver {
|
||||
// span on export = id
|
||||
return textSpan(node, (<ExportAssignment>node).exportName);
|
||||
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
// import statement without including semicolon
|
||||
return textSpan(node,(<ImportDeclaration>node).moduleReference);
|
||||
return textSpan(node,(<ImportEqualsDeclaration>node).moduleReference);
|
||||
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
// span on complete module if it is instantiated
|
||||
|
||||
@@ -452,7 +452,7 @@ module ts.formatting {
|
||||
return true;
|
||||
|
||||
// equal in import a = module('a');
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
// equal in var a = 0;
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
// equal in p = 0;
|
||||
|
||||
+47
-101
@@ -801,7 +801,7 @@ module ts {
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
case SyntaxKind.TypeLiteral:
|
||||
@@ -1552,78 +1552,49 @@ module ts {
|
||||
var file = this.getEntry(fileName);
|
||||
return file && file.scriptSnapshot;
|
||||
}
|
||||
|
||||
public getChangeRange(fileName: string, lastKnownVersion: string, oldScriptSnapshot: IScriptSnapshot): TextChangeRange {
|
||||
var currentVersion = this.getVersion(fileName);
|
||||
if (lastKnownVersion === currentVersion) {
|
||||
return unchangedTextChangeRange; // "No changes"
|
||||
}
|
||||
|
||||
var scriptSnapshot = this.getScriptSnapshot(fileName);
|
||||
return scriptSnapshot.getChangeRange(oldScriptSnapshot);
|
||||
}
|
||||
}
|
||||
|
||||
class SyntaxTreeCache {
|
||||
private hostCache: HostCache;
|
||||
|
||||
// For our syntactic only features, we also keep a cache of the syntax tree for the
|
||||
// currently edited file.
|
||||
private currentFileName: string = "";
|
||||
private currentFileVersion: string = null;
|
||||
private currentSourceFile: SourceFile = null;
|
||||
private currentFileName: string;
|
||||
private currentFileVersion: string;
|
||||
private currentFileScriptSnapshot: IScriptSnapshot;
|
||||
private currentSourceFile: SourceFile;
|
||||
|
||||
constructor(private host: LanguageServiceHost) {
|
||||
}
|
||||
|
||||
private log(message: string) {
|
||||
if (this.host.log) {
|
||||
this.host.log(message);
|
||||
public getCurrentSourceFile(fileName: string): SourceFile {
|
||||
var scriptSnapshot = this.host.getScriptSnapshot(fileName);
|
||||
if (!scriptSnapshot) {
|
||||
// The host does not know about this file.
|
||||
throw new Error("Could not find file: '" + fileName + "'.");
|
||||
}
|
||||
}
|
||||
|
||||
private initialize(fileName: string) {
|
||||
// ensure that both source file and syntax tree are either initialized or not initialized
|
||||
var start = new Date().getTime();
|
||||
this.hostCache = new HostCache(this.host);
|
||||
this.log("SyntaxTreeCache.Initialize: new HostCache: " + (new Date().getTime() - start));
|
||||
|
||||
var version = this.hostCache.getVersion(fileName);
|
||||
var version = this.host.getScriptVersion(fileName);
|
||||
var sourceFile: SourceFile;
|
||||
|
||||
if (this.currentFileName !== fileName) {
|
||||
var scriptSnapshot = this.hostCache.getScriptSnapshot(fileName);
|
||||
|
||||
var start = new Date().getTime();
|
||||
// This is a new file, just parse it
|
||||
sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, ScriptTarget.Latest, version, /*setNodeParents:*/ true);
|
||||
this.log("SyntaxTreeCache.Initialize: createSourceFile: " + (new Date().getTime() - start));
|
||||
}
|
||||
else if (this.currentFileVersion !== version) {
|
||||
var scriptSnapshot = this.hostCache.getScriptSnapshot(fileName);
|
||||
|
||||
var editRange = this.hostCache.getChangeRange(fileName, this.currentFileVersion, this.currentSourceFile.scriptSnapshot);
|
||||
|
||||
var start = new Date().getTime();
|
||||
// This is the same file, just a newer version. Incrementally parse the file.
|
||||
var editRange = scriptSnapshot.getChangeRange(this.currentFileScriptSnapshot);
|
||||
sourceFile = updateLanguageServiceSourceFile(this.currentSourceFile, scriptSnapshot, version, editRange);
|
||||
this.log("SyntaxTreeCache.Initialize: updateSourceFile: " + (new Date().getTime() - start));
|
||||
}
|
||||
|
||||
if (sourceFile) {
|
||||
// All done, ensure state is up to date
|
||||
this.currentFileVersion = version;
|
||||
this.currentFileName = fileName;
|
||||
this.currentFileScriptSnapshot = scriptSnapshot;
|
||||
this.currentSourceFile = sourceFile;
|
||||
}
|
||||
}
|
||||
|
||||
public getCurrentSourceFile(fileName: string): SourceFile {
|
||||
this.initialize(fileName);
|
||||
return this.currentSourceFile;
|
||||
}
|
||||
|
||||
public getCurrentScriptSnapshot(fileName: string): IScriptSnapshot {
|
||||
return this.getCurrentSourceFile(fileName).scriptSnapshot;
|
||||
}
|
||||
}
|
||||
|
||||
function setSourceFileFields(sourceFile: SourceFile, scriptSnapshot: IScriptSnapshot, version: string) {
|
||||
@@ -1924,7 +1895,7 @@ module ts {
|
||||
function isNameOfExternalModuleImportOrDeclaration(node: Node): boolean {
|
||||
if (node.kind === SyntaxKind.StringLiteral) {
|
||||
return isNameOfModuleDeclaration(node) ||
|
||||
(isExternalModuleImportDeclaration(node.parent.parent) && getExternalModuleImportDeclarationExpression(node.parent.parent) === node);
|
||||
(isExternalModuleImportEqualsDeclaration(node.parent.parent) && getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -2069,6 +2040,7 @@ module ts {
|
||||
}
|
||||
|
||||
function getValidSourceFile(fileName: string): SourceFile {
|
||||
fileName = normalizeSlashes(fileName);
|
||||
var sourceFile = program.getSourceFile(getCanonicalFileName(fileName));
|
||||
if (!sourceFile) {
|
||||
throw new Error("Could not find file: '" + fileName + "'.");
|
||||
@@ -2157,7 +2129,7 @@ module ts {
|
||||
}
|
||||
|
||||
// We have an older version of the sourceFile, incrementally parse the changes
|
||||
var textChangeRange = hostCache.getChangeRange(fileName, oldSourceFile.version, oldSourceFile.scriptSnapshot);
|
||||
var textChangeRange = hostFileInformation.scriptSnapshot.getChangeRange(oldSourceFile.scriptSnapshot);
|
||||
return documentRegistry.updateDocument(oldSourceFile, fileName, newSettings, hostFileInformation.scriptSnapshot, hostFileInformation.version, textChangeRange);
|
||||
}
|
||||
}
|
||||
@@ -2222,8 +2194,6 @@ module ts {
|
||||
function getSyntacticDiagnostics(fileName: string) {
|
||||
synchronizeHostData();
|
||||
|
||||
fileName = normalizeSlashes(fileName);
|
||||
|
||||
return program.getSyntacticDiagnostics(getValidSourceFile(fileName));
|
||||
}
|
||||
|
||||
@@ -2234,7 +2204,6 @@ module ts {
|
||||
function getSemanticDiagnostics(fileName: string) {
|
||||
synchronizeHostData();
|
||||
|
||||
fileName = normalizeSlashes(fileName)
|
||||
var targetSourceFile = getValidSourceFile(fileName);
|
||||
|
||||
// Only perform the action per file regardless of '-out' flag as LanguageServiceHost is expected to call this function per file.
|
||||
@@ -2311,8 +2280,6 @@ module ts {
|
||||
function getCompletionsAtPosition(fileName: string, position: number) {
|
||||
synchronizeHostData();
|
||||
|
||||
fileName = normalizeSlashes(fileName);
|
||||
|
||||
var syntacticStart = new Date().getTime();
|
||||
var sourceFile = getValidSourceFile(fileName);
|
||||
|
||||
@@ -2731,8 +2698,6 @@ module ts {
|
||||
function getCompletionEntryDetails(fileName: string, position: number, entryName: string): CompletionEntryDetails {
|
||||
// Note: No need to call synchronizeHostData, as we have captured all the data we need
|
||||
// in the getCompletionsAtPosition earlier
|
||||
fileName = normalizeSlashes(fileName);
|
||||
|
||||
var sourceFile = getValidSourceFile(fileName);
|
||||
|
||||
var session = activeCompletionSession;
|
||||
@@ -3080,19 +3045,19 @@ module ts {
|
||||
displayParts.push(spacePart());
|
||||
addFullSymbolName(symbol);
|
||||
ts.forEach(symbol.declarations, declaration => {
|
||||
if (declaration.kind === SyntaxKind.ImportDeclaration) {
|
||||
var importDeclaration = <ImportDeclaration>declaration;
|
||||
if (isExternalModuleImportDeclaration(importDeclaration)) {
|
||||
if (declaration.kind === SyntaxKind.ImportEqualsDeclaration) {
|
||||
var importEqualsDeclaration = <ImportEqualsDeclaration>declaration;
|
||||
if (isExternalModuleImportEqualsDeclaration(importEqualsDeclaration)) {
|
||||
displayParts.push(spacePart());
|
||||
displayParts.push(operatorPart(SyntaxKind.EqualsToken));
|
||||
displayParts.push(spacePart());
|
||||
displayParts.push(keywordPart(SyntaxKind.RequireKeyword));
|
||||
displayParts.push(punctuationPart(SyntaxKind.OpenParenToken));
|
||||
displayParts.push(displayPart(getTextOfNode(getExternalModuleImportDeclarationExpression(importDeclaration)), SymbolDisplayPartKind.stringLiteral));
|
||||
displayParts.push(displayPart(getTextOfNode(getExternalModuleImportEqualsDeclarationExpression(importEqualsDeclaration)), SymbolDisplayPartKind.stringLiteral));
|
||||
displayParts.push(punctuationPart(SyntaxKind.CloseParenToken));
|
||||
}
|
||||
else {
|
||||
var internalAliasSymbol = typeResolver.getSymbolAtLocation(importDeclaration.moduleReference);
|
||||
var internalAliasSymbol = typeResolver.getSymbolAtLocation(importEqualsDeclaration.moduleReference);
|
||||
if (internalAliasSymbol) {
|
||||
displayParts.push(spacePart());
|
||||
displayParts.push(operatorPart(SyntaxKind.EqualsToken));
|
||||
@@ -3195,7 +3160,6 @@ module ts {
|
||||
function getQuickInfoAtPosition(fileName: string, position: number): QuickInfo {
|
||||
synchronizeHostData();
|
||||
|
||||
fileName = normalizeSlashes(fileName);
|
||||
var sourceFile = getValidSourceFile(fileName);
|
||||
var node = getTouchingPropertyName(sourceFile, position);
|
||||
if (!node) {
|
||||
@@ -3241,7 +3205,6 @@ module ts {
|
||||
function getDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] {
|
||||
synchronizeHostData();
|
||||
|
||||
fileName = normalizeSlashes(fileName);
|
||||
var sourceFile = getValidSourceFile(fileName);
|
||||
|
||||
var node = getTouchingPropertyName(sourceFile, position);
|
||||
@@ -3377,7 +3340,6 @@ module ts {
|
||||
function getOccurrencesAtPosition(fileName: string, position: number): ReferenceEntry[] {
|
||||
synchronizeHostData();
|
||||
|
||||
fileName = normalizeSlashes(fileName);
|
||||
var sourceFile = getValidSourceFile(fileName);
|
||||
|
||||
var node = getTouchingWord(sourceFile, position);
|
||||
@@ -3926,7 +3888,6 @@ module ts {
|
||||
function findReferences(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): ReferenceEntry[] {
|
||||
synchronizeHostData();
|
||||
|
||||
fileName = normalizeSlashes(fileName);
|
||||
var sourceFile = getValidSourceFile(fileName);
|
||||
|
||||
var node = getTouchingPropertyName(sourceFile, position);
|
||||
@@ -4670,7 +4631,6 @@ module ts {
|
||||
function getEmitOutput(fileName: string): EmitOutput {
|
||||
synchronizeHostData();
|
||||
|
||||
fileName = normalizeSlashes(fileName);
|
||||
var sourceFile = getValidSourceFile(fileName);
|
||||
|
||||
var outputFiles: OutputFile[] = [];
|
||||
@@ -4733,7 +4693,7 @@ module ts {
|
||||
return SemanticMeaning.Namespace;
|
||||
}
|
||||
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
return SemanticMeaning.Value | SemanticMeaning.Type | SemanticMeaning.Namespace;
|
||||
|
||||
// An external module can be a Value
|
||||
@@ -4768,10 +4728,10 @@ module ts {
|
||||
while (node.parent.kind === SyntaxKind.QualifiedName) {
|
||||
node = node.parent;
|
||||
}
|
||||
return isInternalModuleImportDeclaration(node.parent) && (<ImportDeclaration>node.parent).moduleReference === node;
|
||||
return isInternalModuleImportEqualsDeclaration(node.parent) && (<ImportEqualsDeclaration>node.parent).moduleReference === node;
|
||||
}
|
||||
|
||||
function getMeaningFromRightHandSideOfImport(node: Node) {
|
||||
function getMeaningFromRightHandSideOfImportEquals(node: Node) {
|
||||
Debug.assert(node.kind === SyntaxKind.Identifier);
|
||||
|
||||
// import a = |b|; // Namespace
|
||||
@@ -4780,7 +4740,7 @@ module ts {
|
||||
|
||||
if (node.parent.kind === SyntaxKind.QualifiedName &&
|
||||
(<QualifiedName>node.parent).right === node &&
|
||||
node.parent.parent.kind === SyntaxKind.ImportDeclaration) {
|
||||
node.parent.parent.kind === SyntaxKind.ImportEqualsDeclaration) {
|
||||
return SemanticMeaning.Value | SemanticMeaning.Type | SemanticMeaning.Namespace;
|
||||
}
|
||||
return SemanticMeaning.Namespace;
|
||||
@@ -4791,7 +4751,7 @@ module ts {
|
||||
return SemanticMeaning.Value | SemanticMeaning.Type | SemanticMeaning.Namespace;
|
||||
}
|
||||
else if (isInRightSideOfImport(node)) {
|
||||
return getMeaningFromRightHandSideOfImport(node);
|
||||
return getMeaningFromRightHandSideOfImportEquals(node);
|
||||
}
|
||||
else if (isDeclarationOrFunctionExpressionOrCatchVariableName(node)) {
|
||||
return getMeaningFromDeclaration(node.parent);
|
||||
@@ -4814,23 +4774,21 @@ module ts {
|
||||
function getSignatureHelpItems(fileName: string, position: number): SignatureHelpItems {
|
||||
synchronizeHostData();
|
||||
|
||||
fileName = normalizeSlashes(fileName);
|
||||
var sourceFile = getValidSourceFile(fileName);
|
||||
|
||||
return SignatureHelp.getSignatureHelpItems(sourceFile, position, typeInfoResolver, cancellationToken);
|
||||
}
|
||||
|
||||
/// Syntactic features
|
||||
function getCurrentSourceFile(fileName: string): SourceFile {
|
||||
fileName = normalizeSlashes(fileName);
|
||||
var currentSourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
|
||||
return currentSourceFile;
|
||||
function getSourceFile(fileName: string): SourceFile {
|
||||
return syntaxTreeCache.getCurrentSourceFile(fileName);
|
||||
}
|
||||
|
||||
function getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): TextSpan {
|
||||
fileName = ts.normalizeSlashes(fileName);
|
||||
var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
|
||||
|
||||
// Get node at the location
|
||||
var node = getTouchingPropertyName(getCurrentSourceFile(fileName), startPos);
|
||||
var node = getTouchingPropertyName(sourceFile, startPos);
|
||||
|
||||
if (!node) {
|
||||
return;
|
||||
@@ -4884,19 +4842,19 @@ module ts {
|
||||
|
||||
function getBreakpointStatementAtPosition(fileName: string, position: number) {
|
||||
// doesn't use compiler - no need to synchronize with host
|
||||
fileName = ts.normalizeSlashes(fileName);
|
||||
return BreakpointResolver.spanInSourceFileAtLocation(getCurrentSourceFile(fileName), position);
|
||||
var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
|
||||
|
||||
return BreakpointResolver.spanInSourceFileAtLocation(sourceFile, position);
|
||||
}
|
||||
|
||||
function getNavigationBarItems(fileName: string): NavigationBarItem[] {
|
||||
fileName = normalizeSlashes(fileName);
|
||||
function getNavigationBarItems(fileName: string): NavigationBarItem[]{
|
||||
var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
|
||||
|
||||
return NavigationBar.getNavigationBarItems(getCurrentSourceFile(fileName));
|
||||
return NavigationBar.getNavigationBarItems(sourceFile);
|
||||
}
|
||||
|
||||
function getSemanticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[] {
|
||||
synchronizeHostData();
|
||||
fileName = normalizeSlashes(fileName);
|
||||
|
||||
var sourceFile = getValidSourceFile(fileName);
|
||||
|
||||
@@ -4970,8 +4928,7 @@ module ts {
|
||||
|
||||
function getSyntacticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[] {
|
||||
// doesn't use compiler - no need to synchronize with host
|
||||
fileName = normalizeSlashes(fileName);
|
||||
var sourceFile = getCurrentSourceFile(fileName);
|
||||
var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
|
||||
|
||||
// Make a scanner we can get trivia from.
|
||||
var triviaScanner = createScanner(ScriptTarget.Latest, /*skipTrivia:*/ false, sourceFile.text);
|
||||
@@ -5189,13 +5146,12 @@ module ts {
|
||||
|
||||
function getOutliningSpans(fileName: string): OutliningSpan[] {
|
||||
// doesn't use compiler - no need to synchronize with host
|
||||
fileName = normalizeSlashes(fileName);
|
||||
var sourceFile = getCurrentSourceFile(fileName);
|
||||
var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
|
||||
return OutliningElementsCollector.collectElements(sourceFile);
|
||||
}
|
||||
|
||||
function getBraceMatchingAtPosition(fileName: string, position: number) {
|
||||
var sourceFile = getCurrentSourceFile(fileName);
|
||||
var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
|
||||
var result: TextSpan[] = [];
|
||||
|
||||
var token = getTouchingToken(sourceFile, position);
|
||||
@@ -5248,10 +5204,8 @@ module ts {
|
||||
}
|
||||
|
||||
function getIndentationAtPosition(fileName: string, position: number, editorOptions: EditorOptions) {
|
||||
fileName = normalizeSlashes(fileName);
|
||||
|
||||
var start = new Date().getTime();
|
||||
var sourceFile = getCurrentSourceFile(fileName);
|
||||
var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
|
||||
log("getIndentationAtPosition: getCurrentSourceFile: " + (new Date().getTime() - start));
|
||||
|
||||
var start = new Date().getTime();
|
||||
@@ -5263,22 +5217,17 @@ module ts {
|
||||
}
|
||||
|
||||
function getFormattingEditsForRange(fileName: string, start: number, end: number, options: FormatCodeOptions): TextChange[] {
|
||||
fileName = normalizeSlashes(fileName);
|
||||
var sourceFile = getCurrentSourceFile(fileName);
|
||||
var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
|
||||
return formatting.formatSelection(start, end, sourceFile, getRuleProvider(options), options);
|
||||
}
|
||||
|
||||
function getFormattingEditsForDocument(fileName: string, options: FormatCodeOptions): TextChange[] {
|
||||
fileName = normalizeSlashes(fileName);
|
||||
|
||||
var sourceFile = getCurrentSourceFile(fileName);
|
||||
var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
|
||||
return formatting.formatDocument(sourceFile, getRuleProvider(options), options);
|
||||
}
|
||||
|
||||
function getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: FormatCodeOptions): TextChange[] {
|
||||
fileName = normalizeSlashes(fileName);
|
||||
|
||||
var sourceFile = getCurrentSourceFile(fileName);
|
||||
var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
|
||||
|
||||
if (key === "}") {
|
||||
return formatting.formatOnClosingCurly(position, sourceFile, getRuleProvider(options), options);
|
||||
@@ -5302,8 +5251,6 @@ module ts {
|
||||
// anything away.
|
||||
synchronizeHostData();
|
||||
|
||||
fileName = normalizeSlashes(fileName);
|
||||
|
||||
var sourceFile = getValidSourceFile(fileName);
|
||||
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
@@ -5446,7 +5393,6 @@ module ts {
|
||||
function getRenameInfo(fileName: string, position: number): RenameInfo {
|
||||
synchronizeHostData();
|
||||
|
||||
fileName = normalizeSlashes(fileName);
|
||||
var sourceFile = getValidSourceFile(fileName);
|
||||
|
||||
var node = getTouchingWord(sourceFile, position);
|
||||
@@ -5530,7 +5476,7 @@ module ts {
|
||||
getFormattingEditsForDocument,
|
||||
getFormattingEditsAfterKeystroke,
|
||||
getEmitOutput,
|
||||
getSourceFile: getCurrentSourceFile,
|
||||
getSourceFile,
|
||||
getProgram
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user