Merge branch 'master' into fix10193

# Conflicts:
#	src/compiler/binder.ts
This commit is contained in:
Kanchalai Tanglertsampan 2016-08-11 10:48:31 -07:00
commit dbcf8e88c9
29 changed files with 1166 additions and 120 deletions

View File

@ -17,6 +17,8 @@ matrix:
node_js: stable
osx_image: xcode7.3
env: workerCount=2
allow_failures:
- os: osx
branches:
only:
@ -32,3 +34,6 @@ install:
cache:
directories:
- node_modules
git:
depth: 1

View File

@ -35,6 +35,7 @@ import merge2 = require("merge2");
import intoStream = require("into-stream");
import * as os from "os";
import Linter = require("tslint");
import fold = require("travis-fold");
const gulp = helpMaker(originalGulp);
const mochaParallel = require("./scripts/mocha-parallel.js");
const {runTestsInParallel} = mochaParallel;
@ -964,6 +965,7 @@ gulp.task("lint", "Runs tslint on the compiler sources. Optional arguments are:
const fileMatcher = RegExp(cmdLineOptions["files"]);
const lintOptions = getLinterOptions();
let failed = 0;
if (fold.isTravis()) console.log(fold.start("lint"));
return gulp.src(lintTargets)
.pipe(insert.transform((contents, file) => {
if (!fileMatcher.test(file.path)) return contents;
@ -975,6 +977,7 @@ gulp.task("lint", "Runs tslint on the compiler sources. Optional arguments are:
return contents; // TODO (weswig): Automatically apply fixes? :3
}))
.on("end", () => {
if (fold.isTravis()) console.log(fold.end("lint"));
if (failed > 0) {
console.error("Linter errors.");
process.exit(1);

View File

@ -5,6 +5,7 @@ var os = require("os");
var path = require("path");
var child_process = require("child_process");
var Linter = require("tslint");
var fold = require("travis-fold");
var runTestsInParallel = require("./scripts/mocha-parallel").runTestsInParallel;
// Variables
@ -560,9 +561,19 @@ compileFile(
desc("Builds language service server library");
task("lssl", [tsserverLibraryFile, tsserverLibraryDefinitionFile]);
desc("Emit the start of the build fold");
task("build-fold-start", [] , function() {
if (fold.isTravis()) console.log(fold.start("build"));
});
desc("Emit the end of the build fold");
task("build-fold-end", [] , function() {
if (fold.isTravis()) console.log(fold.end("build"));
});
// Local target to build the compiler and services
desc("Builds the full compiler and services");
task("local", ["generate-diagnostics", "lib", tscFile, servicesFile, nodeDefinitionsFile, serverFile, builtGeneratedDiagnosticMessagesJSON, "lssl"]);
task("local", ["build-fold-start", "generate-diagnostics", "lib", tscFile, servicesFile, nodeDefinitionsFile, serverFile, builtGeneratedDiagnosticMessagesJSON, "lssl", "build-fold-end"]);
// Local target to build only tsc.js
desc("Builds only the compiler");
@ -998,12 +1009,22 @@ var tslintRulesOutFiles = tslintRules.map(function(p) {
return path.join(builtLocalDirectory, "tslint", p + ".js");
});
desc("Compiles tslint rules to js");
task("build-rules", tslintRulesOutFiles);
task("build-rules", ["build-rules-start"].concat(tslintRulesOutFiles).concat(["build-rules-end"]));
tslintRulesFiles.forEach(function(ruleFile, i) {
compileFile(tslintRulesOutFiles[i], [ruleFile], [ruleFile], [], /*useBuiltCompiler*/ false,
{ noOutFile: true, generateDeclarations: false, outDir: path.join(builtLocalDirectory, "tslint")});
});
desc("Emit the start of the build-rules fold");
task("build-rules-start", [] , function() {
if (fold.isTravis()) console.log(fold.start("build-rules"));
});
desc("Emit the end of the build-rules fold");
task("build-rules-end", [] , function() {
if (fold.isTravis()) console.log(fold.end("build-rules"));
});
function getLinterOptions() {
return {
configuration: require("./tslint.json"),
@ -1047,6 +1068,7 @@ var lintTargets = compilerSources
desc("Runs tslint on the compiler sources. Optional arguments are: f[iles]=regex");
task("lint", ["build-rules"], function() {
if (fold.isTravis()) console.log(fold.start("lint"));
var lintOptions = getLinterOptions();
var failed = 0;
var fileMatcher = RegExp(process.env.f || process.env.file || process.env.files || "");
@ -1062,6 +1084,7 @@ task("lint", ["build-rules"], function() {
done[target] = true;
}
}
if (fold.isTravis()) console.log(fold.end("lint"));
if (failed > 0) {
fail('Linter errors.', failed);
}

View File

@ -30,8 +30,8 @@
},
"devDependencies": {
"@types/browserify": "latest",
"@types/convert-source-map": "latest",
"@types/chai": "latest",
"@types/convert-source-map": "latest",
"@types/del": "latest",
"@types/glob": "latest",
"@types/gulp": "latest",
@ -72,6 +72,7 @@
"run-sequence": "latest",
"sorcery": "latest",
"through2": "latest",
"travis-fold": "latest",
"ts-node": "latest",
"tslint": "next",
"typescript": "next"

View File

@ -1900,20 +1900,20 @@ namespace ts {
}
function bindExportAssignment(node: ExportAssignment | BinaryExpression) {
const boundExpression = node.kind === SyntaxKind.ExportAssignment ? (<ExportAssignment>node).expression : (<BinaryExpression>node).right;
if (!container.symbol || !container.symbol.exports) {
// Export assignment in some sort of block construct
bindAnonymousDeclaration(node, SymbolFlags.Alias, getDeclarationName(node));
}
else if (boundExpression.kind === SyntaxKind.Identifier && node.kind === SyntaxKind.ExportAssignment) {
// An export default clause with an identifier exports all meanings of that identifier
declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.Alias, SymbolFlags.PropertyExcludes | SymbolFlags.AliasExcludes);
}
else {
// An export default clause with an expression exports a value
// We want to exclude both class and function here, this is necessary to issue an error when there are both
// default export-assignment and default export function and class declaration.
declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.Property, SymbolFlags.Class | SymbolFlags.Function | SymbolFlags.Property);
const flags = node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(<ExportAssignment>node)
// An export default clause with an EntityNameExpression exports all meanings of that identifier
? SymbolFlags.Alias
// An export default clause with any other expression exports a value
: SymbolFlags.Property;
declareSymbol(container.symbol.exports, container.symbol, node, flags, SymbolFlags.Property | SymbolFlags.AliasExcludes | SymbolFlags.Class | SymbolFlags.Function); //SymbolFlags.Class | SymbolFlags.Function | SymbolFlags.Property);
}
}

View File

@ -664,7 +664,7 @@ namespace ts {
// Resolve a given name for a given meaning at a given location. An error is reported if the name was not found and
// the nameNotFoundMessage argument is not undefined. Returns the resolved symbol, or undefined if no symbol with
// the given name can be found.
function resolveName(location: Node, name: string, meaning: SymbolFlags, nameNotFoundMessage: DiagnosticMessage, nameArg: string | Identifier): Symbol {
function resolveName(location: Node | undefined, name: string, meaning: SymbolFlags, nameNotFoundMessage: DiagnosticMessage, nameArg: string | Identifier): Symbol {
let result: Symbol;
let lastLocation: Node;
let propertyWithInvalidInitializer: Node;
@ -881,7 +881,8 @@ namespace ts {
if (!result) {
if (nameNotFoundMessage) {
if (!checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg) &&
if (!errorLocation ||
!checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg) &&
!checkAndReportErrorForExtendingInterface(errorLocation)) {
error(errorLocation, nameNotFoundMessage, typeof nameArg === "string" ? nameArg : declarationNameToString(nameArg));
}
@ -930,7 +931,7 @@ namespace ts {
}
function checkAndReportErrorForMissingPrefix(errorLocation: Node, name: string, nameArg: string | Identifier): boolean {
if (!errorLocation || (errorLocation.kind === SyntaxKind.Identifier && (isTypeReferenceIdentifier(<Identifier>errorLocation)) || isInTypeQuery(errorLocation))) {
if ((errorLocation.kind === SyntaxKind.Identifier && (isTypeReferenceIdentifier(<Identifier>errorLocation)) || isInTypeQuery(errorLocation))) {
return false;
}
@ -968,28 +969,30 @@ namespace ts {
function checkAndReportErrorForExtendingInterface(errorLocation: Node): boolean {
let parentClassExpression = errorLocation;
while (parentClassExpression) {
const kind = parentClassExpression.kind;
if (kind === SyntaxKind.Identifier || kind === SyntaxKind.PropertyAccessExpression) {
parentClassExpression = parentClassExpression.parent;
continue;
}
if (kind === SyntaxKind.ExpressionWithTypeArguments) {
break;
}
return false;
}
if (!parentClassExpression) {
return false;
}
const expression = (<ExpressionWithTypeArguments>parentClassExpression).expression;
if (resolveEntityName(expression, SymbolFlags.Interface, /*ignoreErrors*/ true)) {
const expression = getEntityNameForExtendingInterface(errorLocation);
const isError = !!(expression && resolveEntityName(expression, SymbolFlags.Interface, /*ignoreErrors*/ true));
if (isError) {
error(errorLocation, Diagnostics.Cannot_extend_an_interface_0_Did_you_mean_implements, getTextOfNode(expression));
return true;
}
return false;
return isError;
}
/**
* Climbs up parents to an ExpressionWithTypeArguments, and returns its expression,
* but returns undefined if that expression is not an EntityNameExpression.
*/
function getEntityNameForExtendingInterface(node: Node): EntityNameExpression | undefined {
switch (node.kind) {
case SyntaxKind.Identifier:
case SyntaxKind.PropertyAccessExpression:
return node.parent ? getEntityNameForExtendingInterface(node.parent) : undefined;
case SyntaxKind.ExpressionWithTypeArguments:
Debug.assert(isEntityNameExpression((<ExpressionWithTypeArguments>node).expression));
return <EntityNameExpression>(<ExpressionWithTypeArguments>node).expression;
default:
return undefined;
}
}
function checkResolvedBlockScopedVariable(result: Symbol, errorLocation: Node): void {
Debug.assert((result.flags & SymbolFlags.BlockScopedVariable) !== 0);
@ -1033,7 +1036,7 @@ namespace ts {
}
function getDeclarationOfAliasSymbol(symbol: Symbol): Declaration {
return forEach(symbol.declarations, d => isAliasSymbolDeclaration(d) ? d : undefined);
return find(symbol.declarations, d => isAliasSymbolDeclaration(d) ? d : undefined);
}
function getTargetOfImportEqualsDeclaration(node: ImportEqualsDeclaration): Symbol {
@ -1168,7 +1171,7 @@ namespace ts {
}
function getTargetOfExportAssignment(node: ExportAssignment): Symbol {
return resolveEntityName(<Identifier>node.expression, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace);
return resolveEntityName(<EntityNameExpression>node.expression, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace);
}
function getTargetOfAliasDeclaration(node: Declaration): Symbol {
@ -1278,7 +1281,7 @@ namespace ts {
}
// Resolves a qualified name and any involved aliases
function resolveEntityName(name: EntityName | Expression, meaning: SymbolFlags, ignoreErrors?: boolean, dontResolveAlias?: boolean): Symbol {
function resolveEntityName(name: EntityNameOrEntityNameExpression, meaning: SymbolFlags, ignoreErrors?: boolean, dontResolveAlias?: boolean): Symbol | undefined {
if (nodeIsMissing(name)) {
return undefined;
}
@ -1293,7 +1296,7 @@ namespace ts {
}
}
else if (name.kind === SyntaxKind.QualifiedName || name.kind === SyntaxKind.PropertyAccessExpression) {
const left = name.kind === SyntaxKind.QualifiedName ? (<QualifiedName>name).left : (<PropertyAccessExpression>name).expression;
const left = name.kind === SyntaxKind.QualifiedName ? (<QualifiedName>name).left : (<PropertyAccessEntityNameExpression>name).expression;
const right = name.kind === SyntaxKind.QualifiedName ? (<QualifiedName>name).right : (<PropertyAccessExpression>name).name;
const namespace = resolveEntityName(left, SymbolFlags.Namespace, ignoreErrors);
@ -1538,8 +1541,8 @@ namespace ts {
function createType(flags: TypeFlags): Type {
const result = new Type(checker, flags);
result.id = typeCount;
typeCount++;
result.id = typeCount;
return result;
}
@ -1849,7 +1852,7 @@ namespace ts {
}
}
function isEntityNameVisible(entityName: EntityName | Expression, enclosingDeclaration: Node): SymbolVisibilityResult {
function isEntityNameVisible(entityName: EntityNameOrEntityNameExpression, enclosingDeclaration: Node): SymbolVisibilityResult {
// get symbol of the first identifier of the entityName
let meaning: SymbolFlags;
if (entityName.parent.kind === SyntaxKind.TypeQuery || isExpressionWithTypeArgumentsInClassExtendsClause(entityName.parent)) {
@ -3679,7 +3682,7 @@ namespace ts {
const baseTypeNodes = getInterfaceBaseTypeNodes(<InterfaceDeclaration>declaration);
if (baseTypeNodes) {
for (const node of baseTypeNodes) {
if (isSupportedExpressionWithTypeArguments(node)) {
if (isEntityNameExpression(node.expression)) {
const baseSymbol = resolveEntityName(node.expression, SymbolFlags.Type, /*ignoreErrors*/ true);
if (!baseSymbol || !(baseSymbol.flags & SymbolFlags.Interface) || getDeclaredTypeOfClassOrInterface(baseSymbol).thisType) {
return false;
@ -4000,6 +4003,9 @@ namespace ts {
return createTypeReference((<TypeReference>type).target,
concatenate((<TypeReference>type).typeArguments, [thisArgument || (<TypeReference>type).target.thisType]));
}
if (type.flags & TypeFlags.Tuple) {
return createTupleType((type as TupleType).elementTypes, thisArgument);
}
return type;
}
@ -4103,7 +4109,8 @@ namespace ts {
function resolveTupleTypeMembers(type: TupleType) {
const arrayElementType = getUnionType(type.elementTypes);
// Make the tuple type itself the 'this' type by including an extra type argument
const arrayType = resolveStructuredTypeMembers(createTypeFromGenericGlobalType(globalArrayType, [arrayElementType, type]));
// (Unless it's provided in the case that the tuple is a type parameter constraint)
const arrayType = resolveStructuredTypeMembers(createTypeFromGenericGlobalType(globalArrayType, [arrayElementType, type.thisType || type]));
const members = createTupleTypeMemberSymbols(type.elementTypes);
addInheritedMembers(members, arrayType.properties);
setObjectTypeMembers(type, members, arrayType.callSignatures, arrayType.constructSignatures, arrayType.stringIndexInfo, arrayType.numberIndexInfo);
@ -5041,7 +5048,7 @@ namespace ts {
return getDeclaredTypeOfSymbol(symbol);
}
function getTypeReferenceName(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference): LeftHandSideExpression | EntityName {
function getTypeReferenceName(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference): EntityNameOrEntityNameExpression | undefined {
switch (node.kind) {
case SyntaxKind.TypeReference:
return (<TypeReferenceNode>node).typeName;
@ -5050,8 +5057,9 @@ namespace ts {
case SyntaxKind.ExpressionWithTypeArguments:
// We only support expressions that are simple qualified names. For other
// expressions this produces undefined.
if (isSupportedExpressionWithTypeArguments(<ExpressionWithTypeArguments>node)) {
return (<ExpressionWithTypeArguments>node).expression;
const expr = (<ExpressionWithTypeArguments>node).expression;
if (isEntityNameExpression(expr)) {
return expr;
}
// fall through;
@ -5062,7 +5070,7 @@ namespace ts {
function resolveTypeReferenceName(
node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference,
typeReferenceName: LeftHandSideExpression | EntityName) {
typeReferenceName: EntityNameExpression | EntityName) {
if (!typeReferenceName) {
return unknownSymbol;
@ -5103,15 +5111,14 @@ namespace ts {
const typeReferenceName = getTypeReferenceName(node);
symbol = resolveTypeReferenceName(node, typeReferenceName);
type = getTypeReferenceType(node, symbol);
links.resolvedSymbol = symbol;
links.resolvedType = type;
}
else {
// We only support expressions that are simple qualified names. For other expressions this produces undefined.
const typeNameOrExpression = node.kind === SyntaxKind.TypeReference ? (<TypeReferenceNode>node).typeName :
isSupportedExpressionWithTypeArguments(<ExpressionWithTypeArguments>node) ? (<ExpressionWithTypeArguments>node).expression :
undefined;
const typeNameOrExpression: EntityNameOrEntityNameExpression = node.kind === SyntaxKind.TypeReference
? (<TypeReferenceNode>node).typeName
: isEntityNameExpression((<ExpressionWithTypeArguments>node).expression)
? <EntityNameExpression>(<ExpressionWithTypeArguments>node).expression
: undefined;
symbol = typeNameOrExpression && resolveEntityName(typeNameOrExpression, SymbolFlags.Type) || unknownSymbol;
type = symbol === unknownSymbol ? unknownType :
symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface) ? getTypeFromClassOrInterfaceReference(node, symbol) :
@ -5230,15 +5237,16 @@ namespace ts {
return links.resolvedType;
}
function createTupleType(elementTypes: Type[]) {
const id = getTypeListId(elementTypes);
return tupleTypes[id] || (tupleTypes[id] = createNewTupleType(elementTypes));
function createTupleType(elementTypes: Type[], thisType?: Type) {
const id = getTypeListId(elementTypes) + "," + (thisType ? thisType.id : 0);
return tupleTypes[id] || (tupleTypes[id] = createNewTupleType(elementTypes, thisType));
}
function createNewTupleType(elementTypes: Type[]) {
function createNewTupleType(elementTypes: Type[], thisType?: Type) {
const propagatedFlags = getPropagatingFlagsOfTypes(elementTypes, /*excludeKinds*/ 0);
const type = <TupleType>createObjectType(TypeFlags.Tuple | propagatedFlags);
type.elementTypes = elementTypes;
type.thisType = thisType;
return type;
}
@ -7837,14 +7845,17 @@ namespace ts {
}
function isDiscriminantProperty(type: Type, name: string) {
if (type && type.flags & TypeFlags.Union) {
const prop = getPropertyOfType(type, name);
if (prop && prop.flags & SymbolFlags.SyntheticProperty) {
if ((<TransientSymbol>prop).isDiscriminantProperty === undefined) {
(<TransientSymbol>prop).isDiscriminantProperty = !(<TransientSymbol>prop).hasCommonType &&
isUnitUnionType(getTypeOfSymbol(prop));
if (type) {
const nonNullType = getNonNullableType(type);
if (nonNullType.flags & TypeFlags.Union) {
const prop = getPropertyOfType(nonNullType, name);
if (prop && prop.flags & SymbolFlags.SyntheticProperty) {
if ((<TransientSymbol>prop).isDiscriminantProperty === undefined) {
(<TransientSymbol>prop).isDiscriminantProperty = !(<TransientSymbol>prop).hasCommonType &&
isUnitUnionType(getTypeOfSymbol(prop));
}
return (<TransientSymbol>prop).isDiscriminantProperty;
}
return (<TransientSymbol>prop).isDiscriminantProperty;
}
}
return false;
@ -16379,7 +16390,7 @@ namespace ts {
const implementedTypeNodes = getClassImplementsHeritageClauseElements(node);
if (implementedTypeNodes) {
for (const typeRefNode of implementedTypeNodes) {
if (!isSupportedExpressionWithTypeArguments(typeRefNode)) {
if (!isEntityNameExpression(typeRefNode.expression)) {
error(typeRefNode.expression, Diagnostics.A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments);
}
checkTypeReferenceNode(typeRefNode);
@ -16621,7 +16632,7 @@ namespace ts {
checkObjectTypeForDuplicateDeclarations(node);
}
forEach(getInterfaceBaseTypeNodes(node), heritageElement => {
if (!isSupportedExpressionWithTypeArguments(heritageElement)) {
if (!isEntityNameExpression(heritageElement.expression)) {
error(heritageElement.expression, Diagnostics.An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments);
}
checkTypeReferenceNode(heritageElement);
@ -17086,20 +17097,21 @@ namespace ts {
}
}
function getFirstIdentifier(node: EntityName | Expression): Identifier {
while (true) {
if (node.kind === SyntaxKind.QualifiedName) {
node = (<QualifiedName>node).left;
}
else if (node.kind === SyntaxKind.PropertyAccessExpression) {
node = (<PropertyAccessExpression>node).expression;
}
else {
break;
}
function getFirstIdentifier(node: EntityNameOrEntityNameExpression): Identifier {
switch (node.kind) {
case SyntaxKind.Identifier:
return <Identifier>node;
case SyntaxKind.QualifiedName:
do {
node = (<QualifiedName>node).left;
} while (node.kind !== SyntaxKind.Identifier);
return <Identifier>node;
case SyntaxKind.PropertyAccessExpression:
do {
node = (<PropertyAccessEntityNameExpression>node).expression;
} while (node.kind !== SyntaxKind.Identifier);
return <Identifier>node;
}
Debug.assert(node.kind === SyntaxKind.Identifier);
return <Identifier>node;
}
function checkExternalImportOrExportDeclaration(node: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration): boolean {
@ -17798,7 +17810,7 @@ namespace ts {
return getLeftSideOfImportEqualsOrExportAssignment(node) !== undefined;
}
function getSymbolOfEntityNameOrPropertyAccessExpression(entityName: EntityName | PropertyAccessExpression): Symbol {
function getSymbolOfEntityNameOrPropertyAccessExpression(entityName: EntityName | PropertyAccessExpression): Symbol | undefined {
if (isDeclarationName(entityName)) {
return getSymbolOfNode(entityName.parent);
}
@ -17817,22 +17829,20 @@ namespace ts {
}
}
if (entityName.parent.kind === SyntaxKind.ExportAssignment) {
return resolveEntityName(<Identifier>entityName,
if (entityName.parent.kind === SyntaxKind.ExportAssignment && isEntityNameExpression(<Identifier | PropertyAccessExpression>entityName)) {
return resolveEntityName(<EntityNameExpression>entityName,
/*all meanings*/ SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias);
}
if (entityName.kind !== SyntaxKind.PropertyAccessExpression) {
if (isInRightSideOfImportOrExportAssignment(<EntityName>entityName)) {
// Since we already checked for ExportAssignment, this really could only be an Import
const importEqualsDeclaration = <ImportEqualsDeclaration>getAncestor(entityName, SyntaxKind.ImportEqualsDeclaration);
Debug.assert(importEqualsDeclaration !== undefined);
return getSymbolOfPartOfRightHandSideOfImportEquals(<EntityName>entityName, importEqualsDeclaration, /*dontResolveAlias*/ true);
}
if (entityName.kind !== SyntaxKind.PropertyAccessExpression && isInRightSideOfImportOrExportAssignment(<EntityName>entityName)) {
// Since we already checked for ExportAssignment, this really could only be an Import
const importEqualsDeclaration = <ImportEqualsDeclaration>getAncestor(entityName, SyntaxKind.ImportEqualsDeclaration);
Debug.assert(importEqualsDeclaration !== undefined);
return getSymbolOfPartOfRightHandSideOfImportEquals(<EntityName>entityName, importEqualsDeclaration, /*dontResolveAlias*/ true);
}
if (isRightSideOfQualifiedNameOrPropertyAccess(entityName)) {
entityName = <QualifiedName | PropertyAccessExpression>entityName.parent;
entityName = <QualifiedName | PropertyAccessEntityNameExpression>entityName.parent;
}
if (isHeritageClauseElementIdentifier(<EntityName>entityName)) {
@ -18545,7 +18555,7 @@ namespace ts {
};
// defined here to avoid outer scope pollution
function getTypeReferenceDirectivesForEntityName(node: EntityName | PropertyAccessExpression): string[] {
function getTypeReferenceDirectivesForEntityName(node: EntityNameOrEntityNameExpression): string[] {
// program does not have any files with type reference directives - bail out
if (!fileToDirective) {
return undefined;

View File

@ -81,7 +81,7 @@ namespace ts {
* returns a truthy value, then returns that value.
* If no such value is found, the callback is applied to each element of array and undefined is returned.
*/
export function forEach<T, U>(array: T[], callback: (element: T, index: number) => U): U {
export function forEach<T, U>(array: T[] | undefined, callback: (element: T, index: number) => U | undefined): U | undefined {
if (array) {
for (let i = 0, len = array.length; i < len; i++) {
const result = callback(array[i], i);
@ -93,6 +93,17 @@ namespace ts {
return undefined;
}
/** Like `forEach`, but assumes existence of array and fails if no truthy value is found. */
export function find<T, U>(array: T[], callback: (element: T, index: number) => U | undefined): U {
for (let i = 0, len = array.length; i < len; i++) {
const result = callback(array[i], i);
if (result) {
return result;
}
}
Debug.fail();
}
export function contains<T>(array: T[], value: T): boolean {
if (array) {
for (const v of array) {

View File

@ -441,7 +441,7 @@ namespace ts {
}
}
function emitEntityName(entityName: EntityName | PropertyAccessExpression) {
function emitEntityName(entityName: EntityNameOrEntityNameExpression) {
const visibilityResult = resolver.isEntityNameVisible(entityName,
// Aliases can be written asynchronously so use correct enclosing declaration
entityName.parent.kind === SyntaxKind.ImportEqualsDeclaration ? entityName.parent : enclosingDeclaration);
@ -452,9 +452,9 @@ namespace ts {
}
function emitExpressionWithTypeArguments(node: ExpressionWithTypeArguments) {
if (isSupportedExpressionWithTypeArguments(node)) {
if (isEntityNameExpression(node.expression)) {
Debug.assert(node.expression.kind === SyntaxKind.Identifier || node.expression.kind === SyntaxKind.PropertyAccessExpression);
emitEntityName(<Identifier | PropertyAccessExpression>node.expression);
emitEntityName(node.expression);
if (node.typeArguments) {
write("<");
emitCommaList(node.typeArguments, emitType);
@ -1019,7 +1019,7 @@ namespace ts {
}
function emitTypeOfTypeReference(node: ExpressionWithTypeArguments) {
if (isSupportedExpressionWithTypeArguments(node)) {
if (isEntityNameExpression(node.expression)) {
emitTypeWithNewGetSymbolAccessibilityDiagnostic(node, getHeritageClauseVisibilityError);
}
else if (!isImplementsList && node.expression.kind === SyntaxKind.NullKeyword) {

View File

@ -982,13 +982,19 @@ namespace ts {
multiLine?: boolean;
}
export type EntityNameExpression = Identifier | PropertyAccessEntityNameExpression;
export type EntityNameOrEntityNameExpression = EntityName | EntityNameExpression;
// @kind(SyntaxKind.PropertyAccessExpression)
export interface PropertyAccessExpression extends MemberExpression, Declaration {
expression: LeftHandSideExpression;
name: Identifier;
}
export type IdentifierOrPropertyAccess = Identifier | PropertyAccessExpression;
/** Brand for a PropertyAccessExpression which, like a QualifiedName, consists of a sequence of identifiers separated by dots. */
export interface PropertyAccessEntityNameExpression extends PropertyAccessExpression {
_propertyAccessExpressionLikeQualifiedNameBrand?: any;
expression: EntityNameExpression;
}
// @kind(SyntaxKind.ElementAccessExpression)
export interface ElementAccessExpression extends MemberExpression {
@ -2031,7 +2037,7 @@ namespace ts {
writeTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
writeBaseConstructorTypeOfClass(node: ClassLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags): SymbolAccessibilityResult;
isEntityNameVisible(entityName: EntityName | Expression, enclosingDeclaration: Node): SymbolVisibilityResult;
isEntityNameVisible(entityName: EntityNameOrEntityNameExpression, enclosingDeclaration: Node): SymbolVisibilityResult;
// Returns the constant value this property access resolves to, or 'undefined' for a non-constant
getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number;
getReferencedValueDeclaration(reference: Identifier): Declaration;
@ -2040,7 +2046,7 @@ namespace ts {
moduleExportsSomeValue(moduleReferenceExpression: Expression): boolean;
isArgumentsLocalBinding(node: Identifier): boolean;
getExternalModuleFileFromDeclaration(declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration): SourceFile;
getTypeReferenceDirectivesForEntityName(name: EntityName | PropertyAccessExpression): string[];
getTypeReferenceDirectivesForEntityName(name: EntityNameOrEntityNameExpression): string[];
getTypeReferenceDirectivesForSymbol(symbol: Symbol, meaning?: SymbolFlags): string[];
}
@ -2371,6 +2377,7 @@ namespace ts {
export interface TupleType extends ObjectType {
elementTypes: Type[]; // Element types
thisType?: Type; // This-type of tuple (only needed for tuples that are constraints of type parameters)
}
export interface UnionOrIntersectionType extends Type {

View File

@ -1033,14 +1033,14 @@ namespace ts {
&& (<PropertyAccessExpression | ElementAccessExpression>node).expression.kind === SyntaxKind.SuperKeyword;
}
export function getEntityNameFromTypeNode(node: TypeNode): EntityName | Expression {
export function getEntityNameFromTypeNode(node: TypeNode): EntityNameOrEntityNameExpression {
if (node) {
switch (node.kind) {
case SyntaxKind.TypeReference:
return (<TypeReferenceNode>node).typeName;
case SyntaxKind.ExpressionWithTypeArguments:
return (<ExpressionWithTypeArguments>node).expression;
Debug.assert(isEntityNameExpression((<ExpressionWithTypeArguments>node).expression));
return <EntityNameExpression>(<ExpressionWithTypeArguments>node).expression;
case SyntaxKind.Identifier:
case SyntaxKind.QualifiedName:
return (<EntityName><Node>node);
@ -1694,8 +1694,8 @@ namespace ts {
// import * as <symbol> from ...
// import { x as <symbol> } from ...
// export { x as <symbol> } from ...
// export = ...
// export default ...
// export = <EntityNameExpression>
// export default <EntityNameExpression>
export function isAliasSymbolDeclaration(node: Node): boolean {
return node.kind === SyntaxKind.ImportEqualsDeclaration ||
node.kind === SyntaxKind.NamespaceExportDeclaration ||
@ -1703,7 +1703,11 @@ namespace ts {
node.kind === SyntaxKind.NamespaceImport ||
node.kind === SyntaxKind.ImportSpecifier ||
node.kind === SyntaxKind.ExportSpecifier ||
node.kind === SyntaxKind.ExportAssignment && (<ExportAssignment>node).expression.kind === SyntaxKind.Identifier;
node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(<ExportAssignment>node);
}
export function exportAssignmentIsAlias(node: ExportAssignment): boolean {
return isEntityNameExpression(node.expression);
}
export function getClassExtendsHeritageClauseElement(node: ClassLikeDeclaration | InterfaceDeclaration) {
@ -2681,22 +2685,9 @@ namespace ts {
isClassLike(node.parent.parent);
}
// Returns false if this heritage clause element's expression contains something unsupported
// (i.e. not a name or dotted name).
export function isSupportedExpressionWithTypeArguments(node: ExpressionWithTypeArguments): boolean {
return isSupportedExpressionWithTypeArgumentsRest(node.expression);
}
function isSupportedExpressionWithTypeArgumentsRest(node: Expression): boolean {
if (node.kind === SyntaxKind.Identifier) {
return true;
}
else if (isPropertyAccessExpression(node)) {
return isSupportedExpressionWithTypeArgumentsRest(node.expression);
}
else {
return false;
}
export function isEntityNameExpression(node: Expression): node is EntityNameExpression {
return node.kind === SyntaxKind.Identifier ||
node.kind === SyntaxKind.PropertyAccessExpression && isEntityNameExpression((<PropertyAccessExpression>node).expression);
}
export function isRightSideOfQualifiedNameOrPropertyAccess(node: Node) {

View File

@ -750,7 +750,7 @@ namespace Harness {
export function readDirectory(path: string, extension?: string[], exclude?: string[], include?: string[]) {
const fs = new Utils.VirtualFileSystem(path, useCaseSensitiveFileNames());
for (const file in listFiles(path)) {
for (const file of listFiles(path)) {
fs.addFile(file);
}
return ts.matchFiles(path, extension, exclude, include, useCaseSensitiveFileNames(), getCurrentDirectory(), path => {

View File

@ -106,7 +106,7 @@ namespace ts.server {
describe("onMessage", () => {
it("should not throw when commands are executed with invalid arguments", () => {
let i = 0;
for (name in CommandNames) {
for (const name in CommandNames) {
if (!Object.prototype.hasOwnProperty.call(CommandNames, name)) {
continue;
}

View File

@ -63,6 +63,26 @@ interface ArrayConstructor {
from<T>(iterable: Iterable<T>): Array<T>;
}
interface ReadonlyArray<T> {
/** Iterator */
[Symbol.iterator](): IterableIterator<T>;
/**
* Returns an array of key, value pairs for every entry in the array
*/
entries(): IterableIterator<[number, T]>;
/**
* Returns an list of keys in the array
*/
keys(): IterableIterator<number>;
/**
* Returns an list of values in the array
*/
values(): IterableIterator<T>;
}
interface IArguments {
/** Iterator */
[Symbol.iterator](): IterableIterator<any>;

View File

@ -0,0 +1,44 @@
//// [discriminantsAndNullOrUndefined.ts]
// Repro from #10228
interface A { kind: 'A'; }
interface B { kind: 'B'; }
type C = A | B | undefined;
function never(_: never): never {
throw new Error();
}
function useA(_: A): void { }
function useB(_: B): void { }
declare var c: C;
if (c !== undefined) {
switch (c.kind) {
case 'A': useA(c); break;
case 'B': useB(c); break;
default: never(c);
}
}
//// [discriminantsAndNullOrUndefined.js]
// Repro from #10228
function never(_) {
throw new Error();
}
function useA(_) { }
function useB(_) { }
if (c !== undefined) {
switch (c.kind) {
case 'A':
useA(c);
break;
case 'B':
useB(c);
break;
default: never(c);
}
}

View File

@ -0,0 +1,61 @@
=== tests/cases/compiler/discriminantsAndNullOrUndefined.ts ===
// Repro from #10228
interface A { kind: 'A'; }
>A : Symbol(A, Decl(discriminantsAndNullOrUndefined.ts, 0, 0))
>kind : Symbol(A.kind, Decl(discriminantsAndNullOrUndefined.ts, 3, 13))
interface B { kind: 'B'; }
>B : Symbol(B, Decl(discriminantsAndNullOrUndefined.ts, 3, 26))
>kind : Symbol(B.kind, Decl(discriminantsAndNullOrUndefined.ts, 4, 13))
type C = A | B | undefined;
>C : Symbol(C, Decl(discriminantsAndNullOrUndefined.ts, 4, 26))
>A : Symbol(A, Decl(discriminantsAndNullOrUndefined.ts, 0, 0))
>B : Symbol(B, Decl(discriminantsAndNullOrUndefined.ts, 3, 26))
function never(_: never): never {
>never : Symbol(never, Decl(discriminantsAndNullOrUndefined.ts, 6, 27))
>_ : Symbol(_, Decl(discriminantsAndNullOrUndefined.ts, 8, 15))
throw new Error();
>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
}
function useA(_: A): void { }
>useA : Symbol(useA, Decl(discriminantsAndNullOrUndefined.ts, 10, 1))
>_ : Symbol(_, Decl(discriminantsAndNullOrUndefined.ts, 12, 14))
>A : Symbol(A, Decl(discriminantsAndNullOrUndefined.ts, 0, 0))
function useB(_: B): void { }
>useB : Symbol(useB, Decl(discriminantsAndNullOrUndefined.ts, 12, 29))
>_ : Symbol(_, Decl(discriminantsAndNullOrUndefined.ts, 13, 14))
>B : Symbol(B, Decl(discriminantsAndNullOrUndefined.ts, 3, 26))
declare var c: C;
>c : Symbol(c, Decl(discriminantsAndNullOrUndefined.ts, 15, 11))
>C : Symbol(C, Decl(discriminantsAndNullOrUndefined.ts, 4, 26))
if (c !== undefined) {
>c : Symbol(c, Decl(discriminantsAndNullOrUndefined.ts, 15, 11))
>undefined : Symbol(undefined)
switch (c.kind) {
>c.kind : Symbol(kind, Decl(discriminantsAndNullOrUndefined.ts, 3, 13), Decl(discriminantsAndNullOrUndefined.ts, 4, 13))
>c : Symbol(c, Decl(discriminantsAndNullOrUndefined.ts, 15, 11))
>kind : Symbol(kind, Decl(discriminantsAndNullOrUndefined.ts, 3, 13), Decl(discriminantsAndNullOrUndefined.ts, 4, 13))
case 'A': useA(c); break;
>useA : Symbol(useA, Decl(discriminantsAndNullOrUndefined.ts, 10, 1))
>c : Symbol(c, Decl(discriminantsAndNullOrUndefined.ts, 15, 11))
case 'B': useB(c); break;
>useB : Symbol(useB, Decl(discriminantsAndNullOrUndefined.ts, 12, 29))
>c : Symbol(c, Decl(discriminantsAndNullOrUndefined.ts, 15, 11))
default: never(c);
>never : Symbol(never, Decl(discriminantsAndNullOrUndefined.ts, 6, 27))
>c : Symbol(c, Decl(discriminantsAndNullOrUndefined.ts, 15, 11))
}
}

View File

@ -0,0 +1,68 @@
=== tests/cases/compiler/discriminantsAndNullOrUndefined.ts ===
// Repro from #10228
interface A { kind: 'A'; }
>A : A
>kind : "A"
interface B { kind: 'B'; }
>B : B
>kind : "B"
type C = A | B | undefined;
>C : C
>A : A
>B : B
function never(_: never): never {
>never : (_: never) => never
>_ : never
throw new Error();
>new Error() : Error
>Error : ErrorConstructor
}
function useA(_: A): void { }
>useA : (_: A) => void
>_ : A
>A : A
function useB(_: B): void { }
>useB : (_: B) => void
>_ : B
>B : B
declare var c: C;
>c : C
>C : C
if (c !== undefined) {
>c !== undefined : boolean
>c : C
>undefined : undefined
switch (c.kind) {
>c.kind : "A" | "B"
>c : A | B
>kind : "A" | "B"
case 'A': useA(c); break;
>'A' : "A"
>useA(c) : void
>useA : (_: A) => void
>c : A
case 'B': useB(c); break;
>'B' : "B"
>useB(c) : void
>useB : (_: B) => void
>c : B
default: never(c);
>never(c) : never
>never : (_: never) => never
>c : never
}
}

View File

@ -0,0 +1,76 @@
//// [tests/cases/compiler/exportDefaultProperty.ts] ////
//// [declarations.d.ts]
// This test is just like exportEqualsProperty, but with `export default`.
declare namespace foo.bar {
export type X = number;
export const X: number;
}
declare module "foobar" {
export default foo.bar;
}
declare module "foobarx" {
export default foo.bar.X;
}
//// [a.ts]
namespace A {
export class B { constructor(b: number) {} }
export namespace B { export const b: number = 0; }
}
export default A.B;
//// [b.ts]
export default "foo".length;
//// [index.ts]
/// <reference path="declarations.d.ts" />
import fooBar from "foobar";
import X = fooBar.X;
import X2 from "foobarx";
const x: X = X;
const x2: X2 = X2;
import B from "./a";
const b: B = new B(B.b);
import fooLength from "./b";
fooLength + 1;
//// [a.js]
"use strict";
var A;
(function (A) {
var B = (function () {
function B(b) {
}
return B;
}());
A.B = B;
var B;
(function (B) {
B.b = 0;
})(B = A.B || (A.B = {}));
})(A || (A = {}));
exports.__esModule = true;
exports["default"] = A.B;
//// [b.js]
"use strict";
exports.__esModule = true;
exports["default"] = "foo".length;
//// [index.js]
"use strict";
/// <reference path="declarations.d.ts" />
var foobar_1 = require("foobar");
var X = foobar_1["default"].X;
var foobarx_1 = require("foobarx");
var x = X;
var x2 = foobarx_1["default"];
var a_1 = require("./a");
var b = new a_1["default"](a_1["default"].b);
var b_1 = require("./b");
b_1["default"] + 1;

View File

@ -0,0 +1,92 @@
=== tests/cases/compiler/index.ts ===
/// <reference path="declarations.d.ts" />
import fooBar from "foobar";
>fooBar : Symbol(fooBar, Decl(index.ts, 1, 6))
import X = fooBar.X;
>X : Symbol(X, Decl(index.ts, 1, 28))
>fooBar : Symbol(fooBar, Decl(index.ts, 1, 6))
>X : Symbol(fooBar.X, Decl(declarations.d.ts, 2, 27), Decl(declarations.d.ts, 4, 16))
import X2 from "foobarx";
>X2 : Symbol(X2, Decl(index.ts, 3, 6))
const x: X = X;
>x : Symbol(x, Decl(index.ts, 4, 5))
>X : Symbol(X, Decl(index.ts, 1, 28))
>X : Symbol(X, Decl(index.ts, 1, 28))
const x2: X2 = X2;
>x2 : Symbol(x2, Decl(index.ts, 5, 5))
>X2 : Symbol(X2, Decl(index.ts, 3, 6))
>X2 : Symbol(X2, Decl(index.ts, 3, 6))
import B from "./a";
>B : Symbol(B, Decl(index.ts, 7, 6))
const b: B = new B(B.b);
>b : Symbol(b, Decl(index.ts, 8, 5))
>B : Symbol(B, Decl(index.ts, 7, 6))
>B : Symbol(B, Decl(index.ts, 7, 6))
>B.b : Symbol(B.b, Decl(a.ts, 2, 37))
>B : Symbol(B, Decl(index.ts, 7, 6))
>b : Symbol(B.b, Decl(a.ts, 2, 37))
import fooLength from "./b";
>fooLength : Symbol(fooLength, Decl(index.ts, 10, 6))
fooLength + 1;
>fooLength : Symbol(fooLength, Decl(index.ts, 10, 6))
=== tests/cases/compiler/declarations.d.ts ===
// This test is just like exportEqualsProperty, but with `export default`.
declare namespace foo.bar {
>foo : Symbol(foo, Decl(declarations.d.ts, 0, 0))
>bar : Symbol(bar, Decl(declarations.d.ts, 2, 22))
export type X = number;
>X : Symbol(X, Decl(declarations.d.ts, 2, 27), Decl(declarations.d.ts, 4, 16))
export const X: number;
>X : Symbol(X, Decl(declarations.d.ts, 2, 27), Decl(declarations.d.ts, 4, 16))
}
declare module "foobar" {
export default foo.bar;
>foo.bar : Symbol(default, Decl(declarations.d.ts, 2, 22))
>foo : Symbol(foo, Decl(declarations.d.ts, 0, 0))
>bar : Symbol(default, Decl(declarations.d.ts, 2, 22))
}
declare module "foobarx" {
export default foo.bar.X;
>foo.bar.X : Symbol(default, Decl(declarations.d.ts, 2, 27), Decl(declarations.d.ts, 4, 16))
>foo.bar : Symbol(foo.bar, Decl(declarations.d.ts, 2, 22))
>foo : Symbol(foo, Decl(declarations.d.ts, 0, 0))
>bar : Symbol(foo.bar, Decl(declarations.d.ts, 2, 22))
>X : Symbol(default, Decl(declarations.d.ts, 2, 27), Decl(declarations.d.ts, 4, 16))
}
=== tests/cases/compiler/a.ts ===
namespace A {
>A : Symbol(A, Decl(a.ts, 0, 0))
export class B { constructor(b: number) {} }
>B : Symbol(B, Decl(a.ts, 0, 13), Decl(a.ts, 1, 48))
>b : Symbol(b, Decl(a.ts, 1, 33))
export namespace B { export const b: number = 0; }
>B : Symbol(B, Decl(a.ts, 0, 13), Decl(a.ts, 1, 48))
>b : Symbol(b, Decl(a.ts, 2, 37))
}
export default A.B;
>A.B : Symbol(default, Decl(a.ts, 0, 13), Decl(a.ts, 1, 48))
>A : Symbol(A, Decl(a.ts, 0, 0))
>B : Symbol(default, Decl(a.ts, 0, 13), Decl(a.ts, 1, 48))
=== tests/cases/compiler/b.ts ===
export default "foo".length;
>"foo".length : Symbol(String.length, Decl(lib.d.ts, --, --))
>length : Symbol(String.length, Decl(lib.d.ts, --, --))

View File

@ -0,0 +1,97 @@
=== tests/cases/compiler/index.ts ===
/// <reference path="declarations.d.ts" />
import fooBar from "foobar";
>fooBar : typeof fooBar
import X = fooBar.X;
>X : number
>fooBar : typeof fooBar
>X : number
import X2 from "foobarx";
>X2 : number
const x: X = X;
>x : number
>X : number
>X : number
const x2: X2 = X2;
>x2 : number
>X2 : number
>X2 : number
import B from "./a";
>B : typeof B
const b: B = new B(B.b);
>b : B
>B : B
>new B(B.b) : B
>B : typeof B
>B.b : number
>B : typeof B
>b : number
import fooLength from "./b";
>fooLength : number
fooLength + 1;
>fooLength + 1 : number
>fooLength : number
>1 : number
=== tests/cases/compiler/declarations.d.ts ===
// This test is just like exportEqualsProperty, but with `export default`.
declare namespace foo.bar {
>foo : typeof foo
>bar : typeof bar
export type X = number;
>X : number
export const X: number;
>X : number
}
declare module "foobar" {
export default foo.bar;
>foo.bar : typeof default
>foo : typeof foo
>bar : typeof default
}
declare module "foobarx" {
export default foo.bar.X;
>foo.bar.X : number
>foo.bar : typeof foo.bar
>foo : typeof foo
>bar : typeof foo.bar
>X : number
}
=== tests/cases/compiler/a.ts ===
namespace A {
>A : typeof A
export class B { constructor(b: number) {} }
>B : B
>b : number
export namespace B { export const b: number = 0; }
>B : typeof B
>b : number
>0 : number
}
export default A.B;
>A.B : typeof default
>A : typeof A
>B : typeof default
=== tests/cases/compiler/b.ts ===
export default "foo".length;
>"foo".length : number
>"foo" : string
>length : number

View File

@ -0,0 +1,72 @@
//// [tests/cases/compiler/exportEqualsProperty.ts] ////
//// [declarations.d.ts]
// This test is just like exportDefaultProperty, but with `export =`.
declare namespace foo.bar {
export type X = number;
export const X: number;
}
declare module "foobar" {
export = foo.bar;
}
declare module "foobarx" {
export = foo.bar.X;
}
//// [a.ts]
namespace A {
export class B { constructor(b: number) {} }
export namespace B { export const b: number = 0; }
}
export = A.B;
//// [b.ts]
export = "foo".length;
//// [index.ts]
/// <reference path="declarations.d.ts" />
import { X } from "foobar";
import X2 = require("foobarx");
const x: X = X;
const x2: X2 = X2;
import B = require("./a");
const b: B = new B(B.b);
import fooLength = require("./b");
fooLength + 1;
//// [a.js]
"use strict";
var A;
(function (A) {
var B = (function () {
function B(b) {
}
return B;
}());
A.B = B;
var B;
(function (B) {
B.b = 0;
})(B = A.B || (A.B = {}));
})(A || (A = {}));
module.exports = A.B;
//// [b.js]
"use strict";
module.exports = "foo".length;
//// [index.js]
"use strict";
/// <reference path="declarations.d.ts" />
var foobar_1 = require("foobar");
var X2 = require("foobarx");
var x = foobar_1.X;
var x2 = X2;
var B = require("./a");
var b = new B(B.b);
var fooLength = require("./b");
fooLength + 1;

View File

@ -0,0 +1,87 @@
=== tests/cases/compiler/index.ts ===
/// <reference path="declarations.d.ts" />
import { X } from "foobar";
>X : Symbol(X, Decl(index.ts, 1, 8))
import X2 = require("foobarx");
>X2 : Symbol(X2, Decl(index.ts, 1, 27))
const x: X = X;
>x : Symbol(x, Decl(index.ts, 3, 5))
>X : Symbol(X, Decl(index.ts, 1, 8))
>X : Symbol(X, Decl(index.ts, 1, 8))
const x2: X2 = X2;
>x2 : Symbol(x2, Decl(index.ts, 4, 5))
>X2 : Symbol(X2, Decl(index.ts, 1, 27))
>X2 : Symbol(X2, Decl(index.ts, 1, 27))
import B = require("./a");
>B : Symbol(B, Decl(index.ts, 4, 18))
const b: B = new B(B.b);
>b : Symbol(b, Decl(index.ts, 7, 5))
>B : Symbol(B, Decl(index.ts, 4, 18))
>B : Symbol(B, Decl(index.ts, 4, 18))
>B.b : Symbol(B.b, Decl(a.ts, 2, 37))
>B : Symbol(B, Decl(index.ts, 4, 18))
>b : Symbol(B.b, Decl(a.ts, 2, 37))
import fooLength = require("./b");
>fooLength : Symbol(fooLength, Decl(index.ts, 7, 24))
fooLength + 1;
>fooLength : Symbol(fooLength, Decl(index.ts, 7, 24))
=== tests/cases/compiler/declarations.d.ts ===
// This test is just like exportDefaultProperty, but with `export =`.
declare namespace foo.bar {
>foo : Symbol(foo, Decl(declarations.d.ts, 0, 0))
>bar : Symbol(bar, Decl(declarations.d.ts, 2, 22))
export type X = number;
>X : Symbol(X, Decl(declarations.d.ts, 2, 27), Decl(declarations.d.ts, 4, 16))
export const X: number;
>X : Symbol(X, Decl(declarations.d.ts, 2, 27), Decl(declarations.d.ts, 4, 16))
}
declare module "foobar" {
export = foo.bar;
>foo.bar : Symbol(foo.bar, Decl(declarations.d.ts, 2, 22))
>foo : Symbol(foo, Decl(declarations.d.ts, 0, 0))
>bar : Symbol(foo.bar, Decl(declarations.d.ts, 2, 22))
}
declare module "foobarx" {
export = foo.bar.X;
>foo.bar.X : Symbol(foo.bar.X, Decl(declarations.d.ts, 2, 27), Decl(declarations.d.ts, 4, 16))
>foo.bar : Symbol(foo.bar, Decl(declarations.d.ts, 2, 22))
>foo : Symbol(foo, Decl(declarations.d.ts, 0, 0))
>bar : Symbol(foo.bar, Decl(declarations.d.ts, 2, 22))
>X : Symbol(foo.bar.X, Decl(declarations.d.ts, 2, 27), Decl(declarations.d.ts, 4, 16))
}
=== tests/cases/compiler/a.ts ===
namespace A {
>A : Symbol(A, Decl(a.ts, 0, 0))
export class B { constructor(b: number) {} }
>B : Symbol(B, Decl(a.ts, 0, 13), Decl(a.ts, 1, 48))
>b : Symbol(b, Decl(a.ts, 1, 33))
export namespace B { export const b: number = 0; }
>B : Symbol(B, Decl(a.ts, 0, 13), Decl(a.ts, 1, 48))
>b : Symbol(b, Decl(a.ts, 2, 37))
}
export = A.B;
>A.B : Symbol(A.B, Decl(a.ts, 0, 13), Decl(a.ts, 1, 48))
>A : Symbol(A, Decl(a.ts, 0, 0))
>B : Symbol(A.B, Decl(a.ts, 0, 13), Decl(a.ts, 1, 48))
=== tests/cases/compiler/b.ts ===
export = "foo".length;
>"foo".length : Symbol(String.length, Decl(lib.d.ts, --, --))
>length : Symbol(String.length, Decl(lib.d.ts, --, --))

View File

@ -0,0 +1,92 @@
=== tests/cases/compiler/index.ts ===
/// <reference path="declarations.d.ts" />
import { X } from "foobar";
>X : number
import X2 = require("foobarx");
>X2 : number
const x: X = X;
>x : number
>X : number
>X : number
const x2: X2 = X2;
>x2 : number
>X2 : number
>X2 : number
import B = require("./a");
>B : typeof B
const b: B = new B(B.b);
>b : B
>B : B
>new B(B.b) : B
>B : typeof B
>B.b : number
>B : typeof B
>b : number
import fooLength = require("./b");
>fooLength : number
fooLength + 1;
>fooLength + 1 : number
>fooLength : number
>1 : number
=== tests/cases/compiler/declarations.d.ts ===
// This test is just like exportDefaultProperty, but with `export =`.
declare namespace foo.bar {
>foo : typeof foo
>bar : typeof bar
export type X = number;
>X : number
export const X: number;
>X : number
}
declare module "foobar" {
export = foo.bar;
>foo.bar : typeof foo.bar
>foo : typeof foo
>bar : typeof foo.bar
}
declare module "foobarx" {
export = foo.bar.X;
>foo.bar.X : number
>foo.bar : typeof foo.bar
>foo : typeof foo
>bar : typeof foo.bar
>X : number
}
=== tests/cases/compiler/a.ts ===
namespace A {
>A : typeof A
export class B { constructor(b: number) {} }
>B : B
>b : number
export namespace B { export const b: number = 0; }
>B : typeof B
>b : number
>0 : number
}
export = A.B;
>A.B : typeof A.B
>A : typeof A
>B : typeof A.B
=== tests/cases/compiler/b.ts ===
export = "foo".length;
>"foo".length : number
>"foo" : string
>length : number

View File

@ -0,0 +1,29 @@
//// [thisInTupleTypeParameterConstraints.ts]
/// <reference no-default-lib="true"/>
interface Boolean {}
interface IArguments {}
interface Function {}
interface Number {}
interface RegExp {}
interface Object {}
interface String {}
interface Array<T> {
// 4 methods will run out of memory if this-types are not instantiated
// correctly for tuple types that are type parameter constraints
map<U>(arg: this): void;
reduceRight<U>(arg: this): void;
reduce<U>(arg: this): void;
reduce2<U>(arg: this): void;
}
declare function f<T extends [(x: number) => number]>(a: T): void;
let x: [(x: number) => number];
f(x);
//// [thisInTupleTypeParameterConstraints.js]
/// <reference no-default-lib="true"/>
var x;
f(x);

View File

@ -0,0 +1,66 @@
=== tests/cases/compiler/thisInTupleTypeParameterConstraints.ts ===
/// <reference no-default-lib="true"/>
interface Boolean {}
>Boolean : Symbol(Boolean, Decl(thisInTupleTypeParameterConstraints.ts, 0, 0))
interface IArguments {}
>IArguments : Symbol(IArguments, Decl(thisInTupleTypeParameterConstraints.ts, 2, 20))
interface Function {}
>Function : Symbol(Function, Decl(thisInTupleTypeParameterConstraints.ts, 3, 23))
interface Number {}
>Number : Symbol(Number, Decl(thisInTupleTypeParameterConstraints.ts, 4, 21))
interface RegExp {}
>RegExp : Symbol(RegExp, Decl(thisInTupleTypeParameterConstraints.ts, 5, 19))
interface Object {}
>Object : Symbol(Object, Decl(thisInTupleTypeParameterConstraints.ts, 6, 19))
interface String {}
>String : Symbol(String, Decl(thisInTupleTypeParameterConstraints.ts, 7, 19))
interface Array<T> {
>Array : Symbol(Array, Decl(thisInTupleTypeParameterConstraints.ts, 8, 19))
>T : Symbol(T, Decl(thisInTupleTypeParameterConstraints.ts, 10, 16))
// 4 methods will run out of memory if this-types are not instantiated
// correctly for tuple types that are type parameter constraints
map<U>(arg: this): void;
>map : Symbol(Array.map, Decl(thisInTupleTypeParameterConstraints.ts, 10, 20))
>U : Symbol(U, Decl(thisInTupleTypeParameterConstraints.ts, 13, 8))
>arg : Symbol(arg, Decl(thisInTupleTypeParameterConstraints.ts, 13, 11))
reduceRight<U>(arg: this): void;
>reduceRight : Symbol(Array.reduceRight, Decl(thisInTupleTypeParameterConstraints.ts, 13, 28))
>U : Symbol(U, Decl(thisInTupleTypeParameterConstraints.ts, 14, 16))
>arg : Symbol(arg, Decl(thisInTupleTypeParameterConstraints.ts, 14, 19))
reduce<U>(arg: this): void;
>reduce : Symbol(Array.reduce, Decl(thisInTupleTypeParameterConstraints.ts, 14, 36))
>U : Symbol(U, Decl(thisInTupleTypeParameterConstraints.ts, 15, 11))
>arg : Symbol(arg, Decl(thisInTupleTypeParameterConstraints.ts, 15, 14))
reduce2<U>(arg: this): void;
>reduce2 : Symbol(Array.reduce2, Decl(thisInTupleTypeParameterConstraints.ts, 15, 31))
>U : Symbol(U, Decl(thisInTupleTypeParameterConstraints.ts, 16, 12))
>arg : Symbol(arg, Decl(thisInTupleTypeParameterConstraints.ts, 16, 15))
}
declare function f<T extends [(x: number) => number]>(a: T): void;
>f : Symbol(f, Decl(thisInTupleTypeParameterConstraints.ts, 17, 1))
>T : Symbol(T, Decl(thisInTupleTypeParameterConstraints.ts, 19, 19))
>x : Symbol(x, Decl(thisInTupleTypeParameterConstraints.ts, 19, 31))
>a : Symbol(a, Decl(thisInTupleTypeParameterConstraints.ts, 19, 54))
>T : Symbol(T, Decl(thisInTupleTypeParameterConstraints.ts, 19, 19))
let x: [(x: number) => number];
>x : Symbol(x, Decl(thisInTupleTypeParameterConstraints.ts, 20, 3))
>x : Symbol(x, Decl(thisInTupleTypeParameterConstraints.ts, 20, 9))
f(x);
>f : Symbol(f, Decl(thisInTupleTypeParameterConstraints.ts, 17, 1))
>x : Symbol(x, Decl(thisInTupleTypeParameterConstraints.ts, 20, 3))

View File

@ -0,0 +1,67 @@
=== tests/cases/compiler/thisInTupleTypeParameterConstraints.ts ===
/// <reference no-default-lib="true"/>
interface Boolean {}
>Boolean : Boolean
interface IArguments {}
>IArguments : IArguments
interface Function {}
>Function : Function
interface Number {}
>Number : Number
interface RegExp {}
>RegExp : RegExp
interface Object {}
>Object : Object
interface String {}
>String : String
interface Array<T> {
>Array : T[]
>T : T
// 4 methods will run out of memory if this-types are not instantiated
// correctly for tuple types that are type parameter constraints
map<U>(arg: this): void;
>map : <U>(arg: this) => void
>U : U
>arg : this
reduceRight<U>(arg: this): void;
>reduceRight : <U>(arg: this) => void
>U : U
>arg : this
reduce<U>(arg: this): void;
>reduce : <U>(arg: this) => void
>U : U
>arg : this
reduce2<U>(arg: this): void;
>reduce2 : <U>(arg: this) => void
>U : U
>arg : this
}
declare function f<T extends [(x: number) => number]>(a: T): void;
>f : <T extends [(x: number) => number]>(a: T) => void
>T : T
>x : number
>a : T
>T : T
let x: [(x: number) => number];
>x : [(x: number) => number]
>x : number
f(x);
>f(x) : void
>f : <T extends [(x: number) => number]>(a: T) => void
>x : [(x: number) => number]

View File

@ -0,0 +1,25 @@
// @strictNullChecks: true
// Repro from #10228
interface A { kind: 'A'; }
interface B { kind: 'B'; }
type C = A | B | undefined;
function never(_: never): never {
throw new Error();
}
function useA(_: A): void { }
function useB(_: B): void { }
declare var c: C;
if (c !== undefined) {
switch (c.kind) {
case 'A': useA(c); break;
case 'B': useB(c); break;
default: never(c);
}
}

View File

@ -0,0 +1,39 @@
// This test is just like exportEqualsProperty, but with `export default`.
// @Filename: declarations.d.ts
declare namespace foo.bar {
export type X = number;
export const X: number;
}
declare module "foobar" {
export default foo.bar;
}
declare module "foobarx" {
export default foo.bar.X;
}
// @Filename: a.ts
namespace A {
export class B { constructor(b: number) {} }
export namespace B { export const b: number = 0; }
}
export default A.B;
// @Filename: b.ts
export default "foo".length;
// @Filename: index.ts
/// <reference path="declarations.d.ts" />
import fooBar from "foobar";
import X = fooBar.X;
import X2 from "foobarx";
const x: X = X;
const x2: X2 = X2;
import B from "./a";
const b: B = new B(B.b);
import fooLength from "./b";
fooLength + 1;

View File

@ -0,0 +1,38 @@
// This test is just like exportDefaultProperty, but with `export =`.
// @Filename: declarations.d.ts
declare namespace foo.bar {
export type X = number;
export const X: number;
}
declare module "foobar" {
export = foo.bar;
}
declare module "foobarx" {
export = foo.bar.X;
}
// @Filename: a.ts
namespace A {
export class B { constructor(b: number) {} }
export namespace B { export const b: number = 0; }
}
export = A.B;
// @Filename: b.ts
export = "foo".length;
// @Filename: index.ts
/// <reference path="declarations.d.ts" />
import { X } from "foobar";
import X2 = require("foobarx");
const x: X = X;
const x2: X2 = X2;
import B = require("./a");
const b: B = new B(B.b);
import fooLength = require("./b");
fooLength + 1;

View File

@ -0,0 +1,22 @@
/// <reference no-default-lib="true"/>
interface Boolean {}
interface IArguments {}
interface Function {}
interface Number {}
interface RegExp {}
interface Object {}
interface String {}
interface Array<T> {
// 4 methods will run out of memory if this-types are not instantiated
// correctly for tuple types that are type parameter constraints
map<U>(arg: this): void;
reduceRight<U>(arg: this): void;
reduce<U>(arg: this): void;
reduce2<U>(arg: this): void;
}
declare function f<T extends [(x: number) => number]>(a: T): void;
let x: [(x: number) => number];
f(x);