Skip to content

Commit f398893

Browse files
authored
Merge pull request #12478 from Microsoft/mergeMaster11232016
Merge master11232016
2 parents 1be2cd2 + 730a687 commit f398893

20 files changed

+2483
-2717
lines changed

src/compiler/checker.ts

Lines changed: 53 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,7 @@ namespace ts {
922922
if (!errorLocation ||
923923
!checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg) &&
924924
!checkAndReportErrorForExtendingInterface(errorLocation) &&
925+
!checkAndReportErrorForUsingTypeAsNamespace(errorLocation, name, meaning) &&
925926
!checkAndReportErrorForUsingTypeAsValue(errorLocation, name, meaning)) {
926927
error(errorLocation, nameNotFoundMessage, typeof nameArg === "string" ? nameArg : declarationNameToString(nameArg));
927928
}
@@ -1032,6 +1033,18 @@ namespace ts {
10321033
}
10331034
}
10341035

1036+
function checkAndReportErrorForUsingTypeAsNamespace(errorLocation: Node, name: string, meaning: SymbolFlags): boolean {
1037+
if (meaning === SymbolFlags.Namespace) {
1038+
const symbol = resolveSymbol(resolveName(errorLocation, name, SymbolFlags.Type & ~SymbolFlags.Value, /*nameNotFoundMessage*/undefined, /*nameArg*/ undefined));
1039+
if (symbol) {
1040+
error(errorLocation, Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_namespace_here, name);
1041+
return true;
1042+
}
1043+
}
1044+
1045+
return false;
1046+
}
1047+
10351048
function checkAndReportErrorForUsingTypeAsValue(errorLocation: Node, name: string, meaning: SymbolFlags): boolean {
10361049
if (meaning & (SymbolFlags.Value & ~SymbolFlags.NamespaceModule)) {
10371050
const symbol = resolveSymbol(resolveName(errorLocation, name, SymbolFlags.Type & ~SymbolFlags.Value, /*nameNotFoundMessage*/undefined, /*nameArg*/ undefined));
@@ -8975,7 +8988,7 @@ namespace ts {
89758988

89768989
function getTypeWithDefault(type: Type, defaultExpression: Expression) {
89778990
if (defaultExpression) {
8978-
const defaultType = checkExpression(defaultExpression);
8991+
const defaultType = getTypeOfExpression(defaultExpression);
89798992
return getUnionType([getTypeWithFacts(type, TypeFacts.NEUndefined), defaultType]);
89808993
}
89818994
return type;
@@ -9002,7 +9015,7 @@ namespace ts {
90029015
function getAssignedTypeOfBinaryExpression(node: BinaryExpression): Type {
90039016
return node.parent.kind === SyntaxKind.ArrayLiteralExpression || node.parent.kind === SyntaxKind.PropertyAssignment ?
90049017
getTypeWithDefault(getAssignedType(node), node.right) :
9005-
checkExpression(node.right);
9018+
getTypeOfExpression(node.right);
90069019
}
90079020

90089021
function getAssignedTypeOfArrayLiteralElement(node: ArrayLiteralExpression, element: Expression): Type {
@@ -9060,7 +9073,7 @@ namespace ts {
90609073
// from its initializer, we'll already have cached the type. Otherwise we compute it now
90619074
// without caching such that transient types are reflected.
90629075
const links = getNodeLinks(node);
9063-
return links.resolvedType || checkExpression(node);
9076+
return links.resolvedType || getTypeOfExpression(node);
90649077
}
90659078

90669079
function getInitialTypeOfVariableDeclaration(node: VariableDeclaration) {
@@ -9120,7 +9133,7 @@ namespace ts {
91209133

91219134
function getTypeOfSwitchClause(clause: CaseClause | DefaultClause) {
91229135
if (clause.kind === SyntaxKind.CaseClause) {
9123-
const caseType = getRegularTypeOfLiteralType(checkExpression((<CaseClause>clause).expression));
9136+
const caseType = getRegularTypeOfLiteralType(getTypeOfExpression((<CaseClause>clause).expression));
91249137
return isUnitType(caseType) ? caseType : undefined;
91259138
}
91269139
return neverType;
@@ -9225,7 +9238,7 @@ namespace ts {
92259238
// we defer subtype reduction until the evolving array type is finalized into a manifest
92269239
// array type.
92279240
function addEvolvingArrayElementType(evolvingArrayType: EvolvingArrayType, node: Expression): EvolvingArrayType {
9228-
const elementType = getBaseTypeOfLiteralType(checkExpression(node));
9241+
const elementType = getBaseTypeOfLiteralType(getTypeOfExpression(node));
92299242
return isTypeSubsetOf(elementType, evolvingArrayType.elementType) ? evolvingArrayType : getEvolvingArrayType(getUnionType([evolvingArrayType.elementType, elementType]));
92309243
}
92319244

@@ -9286,7 +9299,7 @@ namespace ts {
92869299
(<BinaryExpression>parent.parent).operatorToken.kind === SyntaxKind.EqualsToken &&
92879300
(<BinaryExpression>parent.parent).left === parent &&
92889301
!isAssignmentTarget(parent.parent) &&
9289-
isTypeAnyOrAllConstituentTypesHaveKind(checkExpression((<ElementAccessExpression>parent).argumentExpression), TypeFlags.NumberLike | TypeFlags.Undefined);
9302+
isTypeAnyOrAllConstituentTypesHaveKind(getTypeOfExpression((<ElementAccessExpression>parent).argumentExpression), TypeFlags.NumberLike | TypeFlags.Undefined);
92909303
return isLengthPushOrUnshift || isElementAssignment;
92919304
}
92929305

@@ -9448,7 +9461,7 @@ namespace ts {
94489461
}
94499462
}
94509463
else {
9451-
const indexType = checkExpression((<ElementAccessExpression>(<BinaryExpression>node).left).argumentExpression);
9464+
const indexType = getTypeOfExpression((<ElementAccessExpression>(<BinaryExpression>node).left).argumentExpression);
94529465
if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, TypeFlags.NumberLike | TypeFlags.Undefined)) {
94539466
evolvedType = addEvolvingArrayElementType(evolvedType, (<BinaryExpression>node).right);
94549467
}
@@ -9673,7 +9686,7 @@ namespace ts {
96739686
if (operator === SyntaxKind.ExclamationEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken) {
96749687
assumeTrue = !assumeTrue;
96759688
}
9676-
const valueType = checkExpression(value);
9689+
const valueType = getTypeOfExpression(value);
96779690
if (valueType.flags & TypeFlags.Nullable) {
96789691
if (!strictNullChecks) {
96799692
return type;
@@ -9760,7 +9773,7 @@ namespace ts {
97609773
}
97619774

97629775
// Check that right operand is a function type with a prototype property
9763-
const rightType = checkExpression(expr.right);
9776+
const rightType = getTypeOfExpression(expr.right);
97649777
if (!isTypeSubtypeOf(rightType, globalFunctionType)) {
97659778
return type;
97669779
}
@@ -9901,7 +9914,7 @@ namespace ts {
99019914
location = location.parent;
99029915
}
99039916
if (isPartOfExpression(location) && !isAssignmentTarget(location)) {
9904-
const type = checkExpression(<Expression>location);
9917+
const type = getTypeOfExpression(<Expression>location);
99059918
if (getExportSymbolOfValueSymbolIfExported(getNodeLinks(location).resolvedSymbol) === symbol) {
99069919
return type;
99079920
}
@@ -10769,15 +10782,15 @@ namespace ts {
1076910782

1077010783
// In an assignment expression, the right operand is contextually typed by the type of the left operand.
1077110784
if (node === binaryExpression.right) {
10772-
return checkExpression(binaryExpression.left);
10785+
return getTypeOfExpression(binaryExpression.left);
1077310786
}
1077410787
}
1077510788
else if (operator === SyntaxKind.BarBarToken) {
1077610789
// When an || expression has a contextual type, the operands are contextually typed by that type. When an ||
1077710790
// expression has no contextual type, the right operand is contextually typed by the type of the left operand.
1077810791
let type = getContextualType(binaryExpression);
1077910792
if (!type && node === binaryExpression.right) {
10780-
type = checkExpression(binaryExpression.left);
10793+
type = getTypeOfExpression(binaryExpression.left);
1078110794
}
1078210795
return type;
1078310796
}
@@ -12148,7 +12161,7 @@ namespace ts {
1214812161
if (node.kind === SyntaxKind.ForInStatement &&
1214912162
child === (<ForInStatement>node).statement &&
1215012163
getForInVariableSymbol(<ForInStatement>node) === symbol &&
12151-
hasNumericPropertyNames(checkExpression((<ForInStatement>node).expression))) {
12164+
hasNumericPropertyNames(getTypeOfExpression((<ForInStatement>node).expression))) {
1215212165
return true;
1215312166
}
1215412167
child = node;
@@ -13784,7 +13797,7 @@ namespace ts {
1378413797
if (!node.possiblyExhaustive) {
1378513798
return false;
1378613799
}
13787-
const type = checkExpression(node.expression);
13800+
const type = getTypeOfExpression(node.expression);
1378813801
if (!isLiteralType(type)) {
1378913802
return false;
1379013803
}
@@ -14876,6 +14889,24 @@ namespace ts {
1487614889
return type;
1487714890
}
1487814891

14892+
// Returns the type of an expression. Unlike checkExpression, this function is simply concerned
14893+
// with computing the type and may not fully check all contained sub-expressions for errors.
14894+
function getTypeOfExpression(node: Expression) {
14895+
// Optimize for the common case of a call to a function with a single non-generic call
14896+
// signature where we can just fetch the return type without checking the arguments.
14897+
if (node.kind === SyntaxKind.CallExpression && (<CallExpression>node).expression.kind !== SyntaxKind.SuperKeyword) {
14898+
const funcType = checkNonNullExpression((<CallExpression>node).expression);
14899+
const signature = getSingleCallSignature(funcType);
14900+
if (signature && !signature.typeParameters) {
14901+
return getReturnTypeOfSignature(signature);
14902+
}
14903+
}
14904+
// Otherwise simply call checkExpression. Ideally, the entire family of checkXXX functions
14905+
// should have a parameter that indicates whether full error checking is required such that
14906+
// we can perform the optimizations locally.
14907+
return checkExpression(node);
14908+
}
14909+
1487914910
// Checks an expression and returns its type. The contextualMapper parameter serves two purposes: When
1488014911
// contextualMapper is not undefined and not equal to the identityMapper function object it indicates that the
1488114912
// expression is being inferentially typed (section 4.15.2 in spec) and provides the type mapper to use in
@@ -18258,7 +18289,7 @@ namespace ts {
1825818289
}
1825918290
}
1826018291

18261-
enumType = checkExpression(expression);
18292+
enumType = getTypeOfExpression(expression);
1826218293
// allow references to constant members of other enums
1826318294
if (!(enumType.symbol && (enumType.symbol.flags & SymbolFlags.Enum))) {
1826418295
return undefined;
@@ -19428,7 +19459,7 @@ namespace ts {
1942819459
// fallthrough
1942919460

1943019461
case SyntaxKind.SuperKeyword:
19431-
const type = isPartOfExpression(node) ? checkExpression(<Expression>node) : getTypeFromTypeNode(<TypeNode>node);
19462+
const type = isPartOfExpression(node) ? getTypeOfExpression(<Expression>node) : getTypeFromTypeNode(<TypeNode>node);
1943219463
return type.symbol;
1943319464

1943419465
case SyntaxKind.ThisType:
@@ -19458,7 +19489,7 @@ namespace ts {
1945819489
case SyntaxKind.NumericLiteral:
1945919490
// index access
1946019491
if (node.parent.kind === SyntaxKind.ElementAccessExpression && (<ElementAccessExpression>node.parent).argumentExpression === node) {
19461-
const objectType = checkExpression((<ElementAccessExpression>node.parent).expression);
19492+
const objectType = getTypeOfExpression((<ElementAccessExpression>node.parent).expression);
1946219493
if (objectType === unknownType) return undefined;
1946319494
const apparentType = getApparentType(objectType);
1946419495
if (apparentType === unknownType) return undefined;
@@ -19497,7 +19528,7 @@ namespace ts {
1949719528
}
1949819529

1949919530
if (isPartOfExpression(node)) {
19500-
return getTypeOfExpression(<Expression>node);
19531+
return getRegularTypeOfExpression(<Expression>node);
1950119532
}
1950219533

1950319534
if (isExpressionWithTypeArgumentsInClassExtendsClause(node)) {
@@ -19559,7 +19590,7 @@ namespace ts {
1955919590
// If this is from "for" initializer
1956019591
// for ({a } = elems[0];.....) { }
1956119592
if (expr.parent.kind === SyntaxKind.BinaryExpression) {
19562-
const iteratedType = checkExpression((<BinaryExpression>expr.parent).right);
19593+
const iteratedType = getTypeOfExpression((<BinaryExpression>expr.parent).right);
1956319594
return checkDestructuringAssignment(expr, iteratedType || unknownType);
1956419595
}
1956519596
// If this is from nested object binding pattern
@@ -19589,11 +19620,11 @@ namespace ts {
1958919620
return typeOfObjectLiteral && getPropertyOfType(typeOfObjectLiteral, location.text);
1959019621
}
1959119622

19592-
function getTypeOfExpression(expr: Expression): Type {
19623+
function getRegularTypeOfExpression(expr: Expression): Type {
1959319624
if (isRightSideOfQualifiedNameOrPropertyAccess(expr)) {
1959419625
expr = <Expression>expr.parent;
1959519626
}
19596-
return getRegularTypeOfLiteralType(checkExpression(expr));
19627+
return getRegularTypeOfLiteralType(getTypeOfExpression(expr));
1959719628
}
1959819629

1959919630
/**
@@ -20020,7 +20051,7 @@ namespace ts {
2002020051
}
2002120052

2002220053
function writeTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter) {
20023-
const type = getWidenedType(getTypeOfExpression(expr));
20054+
const type = getWidenedType(getRegularTypeOfExpression(expr));
2002420055
getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags);
2002520056
}
2002620057

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1995,6 +1995,10 @@
19951995
"category": "Error",
19961996
"code": 2701
19971997
},
1998+
"'{0}' only refers to a type, but is being used as a namespace here.": {
1999+
"category": "Error",
2000+
"code": 2702
2001+
},
19982002

19992003
"Import declaration '{0}' is using private name '{1}'.": {
20002004
"category": "Error",

src/compiler/emitter.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ namespace ts {
143143

144144
// Write the source map
145145
if (compilerOptions.sourceMap && !compilerOptions.inlineSourceMap) {
146-
writeFile(host, emitterDiagnostics, sourceMapFilePath, sourceMap.getText(), /*writeByteOrderMark*/ false);
146+
writeFile(host, emitterDiagnostics, sourceMapFilePath, sourceMap.getText(), /*writeByteOrderMark*/ false, sourceFiles);
147147
}
148148

149149
// Record source map data for the test harness.
@@ -152,7 +152,7 @@ namespace ts {
152152
}
153153

154154
// Write the output file
155-
writeFile(host, emitterDiagnostics, jsFilePath, writer.getText(), compilerOptions.emitBOM);
155+
writeFile(host, emitterDiagnostics, jsFilePath, writer.getText(), compilerOptions.emitBOM, sourceFiles);
156156

157157
// Reset state
158158
sourceMap.reset();

0 commit comments

Comments
 (0)