Skip to content

Commit 0cb9fd6

Browse files
Merge branch 'master' into promisesAndUnderscores
2 parents b2378ca + 577ee49 commit 0cb9fd6

File tree

69 files changed

+12798
-10428
lines changed

Some content is hidden

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

69 files changed

+12798
-10428
lines changed

src/compiler/binder.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2465,7 +2465,7 @@ namespace ts {
24652465
node.left.parent = node;
24662466
node.right.parent = node;
24672467
const lhs = node.left as PropertyAccessEntityNameExpression;
2468-
bindPropertyAssignment(lhs, lhs, /*isPrototypeProperty*/ false);
2468+
bindPropertyAssignment(lhs.expression, lhs, /*isPrototypeProperty*/ false);
24692469
}
24702470

24712471
/**
@@ -2522,7 +2522,7 @@ namespace ts {
25222522
const isToplevel = isBinaryExpression(propertyAccess.parent)
25232523
? getParentOfBinaryExpression(propertyAccess.parent).parent.kind === SyntaxKind.SourceFile
25242524
: propertyAccess.parent.parent.kind === SyntaxKind.SourceFile;
2525-
if (!isPrototypeProperty && (!namespaceSymbol || !(namespaceSymbol.flags & SymbolFlags.Namespace)) && isToplevel) {
2525+
if (isToplevel && !isPrototypeProperty && (!namespaceSymbol || !(namespaceSymbol.flags & SymbolFlags.Namespace))) {
25262526
// make symbols or add declarations for intermediate containers
25272527
const flags = SymbolFlags.Module | SymbolFlags.Assignment;
25282528
const excludeFlags = SymbolFlags.ValueModuleExcludes & ~SymbolFlags.Assignment;

src/compiler/builderState.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ namespace ts.BuilderState {
8888
function getReferencedFileFromImportedModuleSymbol(symbol: Symbol) {
8989
if (symbol.declarations && symbol.declarations[0]) {
9090
const declarationSourceFile = getSourceFileOfNode(symbol.declarations[0]);
91-
return declarationSourceFile && declarationSourceFile.path;
91+
return declarationSourceFile && (declarationSourceFile.resolvedPath || declarationSourceFile.path);
9292
}
9393
}
9494

@@ -100,6 +100,13 @@ namespace ts.BuilderState {
100100
return symbol && getReferencedFileFromImportedModuleSymbol(symbol);
101101
}
102102

103+
/**
104+
* Gets the path to reference file from file name, it could be resolvedPath if present otherwise path
105+
*/
106+
function getReferencedFileFromFileName(program: Program, fileName: string, sourceFileDirectory: Path, getCanonicalFileName: GetCanonicalFileName): Path {
107+
return toPath(program.getProjectReferenceRedirect(fileName) || fileName, sourceFileDirectory, getCanonicalFileName);
108+
}
109+
103110
/**
104111
* Gets the referenced files for a file from the program with values for the keys as referenced file's path to be true
105112
*/
@@ -123,7 +130,7 @@ namespace ts.BuilderState {
123130
// Handle triple slash references
124131
if (sourceFile.referencedFiles && sourceFile.referencedFiles.length > 0) {
125132
for (const referencedFile of sourceFile.referencedFiles) {
126-
const referencedPath = toPath(referencedFile.fileName, sourceFileDirectory, getCanonicalFileName);
133+
const referencedPath = getReferencedFileFromFileName(program, referencedFile.fileName, sourceFileDirectory, getCanonicalFileName);
127134
addReferencedFile(referencedPath);
128135
}
129136
}
@@ -136,7 +143,7 @@ namespace ts.BuilderState {
136143
}
137144

138145
const fileName = resolvedTypeReferenceDirective.resolvedFileName!; // TODO: GH#18217
139-
const typeFilePath = toPath(fileName, sourceFileDirectory, getCanonicalFileName);
146+
const typeFilePath = getReferencedFileFromFileName(program, fileName, sourceFileDirectory, getCanonicalFileName);
140147
addReferencedFile(typeFilePath);
141148
});
142149
}

src/compiler/checker.ts

Lines changed: 49 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -640,14 +640,15 @@ namespace ts {
640640
const identityRelation = createMap<RelationComparisonResult>();
641641
const enumRelation = createMap<RelationComparisonResult>();
642642

643-
type TypeSystemEntity = Symbol | Type | Signature;
643+
type TypeSystemEntity = Node | Symbol | Type | Signature;
644644

645645
const enum TypeSystemPropertyName {
646646
Type,
647647
ResolvedBaseConstructorType,
648648
DeclaredType,
649649
ResolvedReturnType,
650650
ImmediateBaseConstraint,
651+
EnumTagType,
651652
}
652653

653654
const enum CheckMode {
@@ -3470,8 +3471,8 @@ namespace ts {
34703471
const arity = getTypeReferenceArity(type);
34713472
const tupleConstituentNodes = mapToTypeNodes(typeArguments.slice(0, arity), context);
34723473
const hasRestElement = (<TupleType>type.target).hasRestElement;
3473-
if (tupleConstituentNodes && tupleConstituentNodes.length > 0) {
3474-
for (let i = (<TupleType>type.target).minLength; i < arity; i++) {
3474+
if (tupleConstituentNodes) {
3475+
for (let i = (<TupleType>type.target).minLength; i < Math.min(arity, tupleConstituentNodes.length); i++) {
34753476
tupleConstituentNodes[i] = hasRestElement && i === arity - 1 ?
34763477
createRestTypeNode(createArrayTypeNode(tupleConstituentNodes[i])) :
34773478
createOptionalTypeNode(tupleConstituentNodes[i]);
@@ -4475,6 +4476,8 @@ namespace ts {
44754476
switch (propertyName) {
44764477
case TypeSystemPropertyName.Type:
44774478
return !!getSymbolLinks(<Symbol>target).type;
4479+
case TypeSystemPropertyName.EnumTagType:
4480+
return !!(getNodeLinks(target as JSDocEnumTag).resolvedEnumType);
44784481
case TypeSystemPropertyName.DeclaredType:
44794482
return !!getSymbolLinks(<Symbol>target).declaredType;
44804483
case TypeSystemPropertyName.ResolvedBaseConstructorType:
@@ -8252,9 +8255,18 @@ namespace ts {
82528255
}
82538256

82548257
// JS are 'string' or 'number', not an enum type.
8255-
const enumTag = symbol.valueDeclaration && getJSDocEnumTag(symbol.valueDeclaration);
8258+
const enumTag = isInJSFile(node) && symbol.valueDeclaration && getJSDocEnumTag(symbol.valueDeclaration);
82568259
if (enumTag) {
8257-
return enumTag.typeExpression ? getTypeFromTypeNode(enumTag.typeExpression) : errorType;
8260+
const links = getNodeLinks(enumTag);
8261+
if (!pushTypeResolution(enumTag, TypeSystemPropertyName.EnumTagType)) {
8262+
return errorType;
8263+
}
8264+
let type = enumTag.typeExpression ? getTypeFromTypeNode(enumTag.typeExpression) : errorType;
8265+
if (!popTypeResolution()) {
8266+
type = errorType;
8267+
error(node, Diagnostics.Enum_type_0_circularly_references_itself, symbolToString(symbol));
8268+
}
8269+
return (links.resolvedEnumType = type);
82588270
}
82598271

82608272
// Get type from reference to named type that cannot be generic (enum or type parameter)
@@ -13373,7 +13385,7 @@ namespace ts {
1337313385
let propagationType: Type;
1337413386
inferFromTypes(originalSource, originalTarget);
1337513387

13376-
function inferFromTypes(source: Type, target: Type) {
13388+
function inferFromTypes(source: Type, target: Type): void {
1337713389
if (!couldContainTypeVariables(target)) {
1337813390
return;
1337913391
}
@@ -13508,6 +13520,9 @@ namespace ts {
1350813520
inferFromTypes(getTrueTypeFromConditionalType(<ConditionalType>source), getTrueTypeFromConditionalType(<ConditionalType>target));
1350913521
inferFromTypes(getFalseTypeFromConditionalType(<ConditionalType>source), getFalseTypeFromConditionalType(<ConditionalType>target));
1351013522
}
13523+
else if (target.flags & TypeFlags.Conditional) {
13524+
inferFromTypes(source, getUnionType([getTrueTypeFromConditionalType(<ConditionalType>target), getFalseTypeFromConditionalType(<ConditionalType>target)]));
13525+
}
1351113526
else if (target.flags & TypeFlags.UnionOrIntersection) {
1351213527
const targetTypes = (<UnionOrIntersectionType>target).types;
1351313528
let typeVariableCount = 0;
@@ -13541,7 +13556,14 @@ namespace ts {
1354113556
}
1354213557
else {
1354313558
if (!(priority & InferencePriority.NoConstraints && source.flags & (TypeFlags.Intersection | TypeFlags.Instantiable))) {
13544-
source = getApparentType(source);
13559+
const apparentSource = getApparentType(source);
13560+
// getApparentType can return _any_ type, since an indexed access or conditional may simplify to any other type.
13561+
// If that occurs and it doesn't simplify to an object or intersection, we'll need to restart `inferFromTypes`
13562+
// with the simplified source.
13563+
if (apparentSource !== source && !(apparentSource.flags & (TypeFlags.Object | TypeFlags.Intersection))) {
13564+
return inferFromTypes(apparentSource, target);
13565+
}
13566+
source = apparentSource;
1354513567
}
1354613568
if (source.flags & (TypeFlags.Object | TypeFlags.Intersection)) {
1354713569
const key = source.id + "," + target.id;
@@ -13747,7 +13769,7 @@ namespace ts {
1374713769

1374813770
function hasPrimitiveConstraint(type: TypeParameter): boolean {
1374913771
const constraint = getConstraintOfTypeParameter(type);
13750-
return !!constraint && maybeTypeOfKind(constraint, TypeFlags.Primitive | TypeFlags.Index);
13772+
return !!constraint && maybeTypeOfKind(constraint.flags & TypeFlags.Conditional ? getDefaultConstraintOfConditionalType(constraint as ConditionalType) : constraint, TypeFlags.Primitive | TypeFlags.Index);
1375113773
}
1375213774

1375313775
function isObjectLiteralType(type: Type) {
@@ -14734,6 +14756,14 @@ namespace ts {
1473414756
// reference 'x.y.z', we may be at an assignment to 'x.y' or 'x'. In that case,
1473514757
// return the declared type.
1473614758
if (containsMatchingReference(reference, node)) {
14759+
// A matching dotted name might also be an expando property on a function *expression*,
14760+
// in which case we continue control flow analysis back to the function's declaration
14761+
if (isVariableDeclaration(node) && (isInJSFile(node) || isVarConst(node))) {
14762+
const init = getDeclaredExpandoInitializer(node);
14763+
if (init && (init.kind === SyntaxKind.FunctionExpression || init.kind === SyntaxKind.ArrowFunction)) {
14764+
return getTypeAtFlowNode(flow.antecedent);
14765+
}
14766+
}
1473714767
return declaredType;
1473814768
}
1473914769
// Assignment doesn't affect reference
@@ -18208,7 +18238,7 @@ namespace ts {
1820818238
// Referencing abstract properties within their own constructors is not allowed
1820918239
if ((flags & ModifierFlags.Abstract) && isThisProperty(node) && symbolHasNonMethodDeclaration(prop)) {
1821018240
const declaringClassDeclaration = getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop)!);
18211-
if (declaringClassDeclaration && isNodeUsedDuringClassInitialization(node, declaringClassDeclaration)) {
18241+
if (declaringClassDeclaration && isNodeUsedDuringClassInitialization(node)) {
1821218242
error(errorNode, Diagnostics.Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor, symbolToString(prop), getTextOfIdentifierOrLiteral(declaringClassDeclaration.name!)); // TODO: GH#18217
1821318243
return false;
1821418244
}
@@ -18395,6 +18425,9 @@ namespace ts {
1839518425
}
1839618426
}
1839718427
}
18428+
else if (strictNullChecks && prop && prop.valueDeclaration && isPropertyAccessExpression(prop.valueDeclaration) && getAssignmentDeclarationPropertyAccessKind(prop.valueDeclaration)) {
18429+
assumeUninitialized = true;
18430+
}
1839818431
const flowType = getFlowTypeOfReference(node, propType, assumeUninitialized ? getOptionalType(propType) : propType);
1839918432
if (assumeUninitialized && !(getFalsyFlags(propType) & TypeFlags.Undefined) && getFalsyFlags(flowType) & TypeFlags.Undefined) {
1840018433
error(right, Diagnostics.Property_0_is_used_before_being_assigned, symbolToString(prop!)); // TODO: GH#18217
@@ -20192,18 +20225,15 @@ namespace ts {
2019220225
assigned || inferred;
2019320226
}
2019420227

20195-
function getAssignedClassType(symbol: Symbol) {
20228+
function getAssignedClassType(symbol: Symbol): Type | undefined {
2019620229
const decl = symbol.valueDeclaration;
2019720230
const assignmentSymbol = decl && decl.parent &&
2019820231
(isFunctionDeclaration(decl) && getSymbolOfNode(decl) ||
2019920232
isBinaryExpression(decl.parent) && getSymbolOfNode(decl.parent.left) ||
2020020233
isVariableDeclaration(decl.parent) && getSymbolOfNode(decl.parent));
20201-
if (assignmentSymbol) {
20202-
const prototype = forEach(assignmentSymbol.declarations, getAssignedJSPrototype);
20203-
if (prototype) {
20204-
return checkExpression(prototype);
20205-
}
20206-
}
20234+
const prototype = assignmentSymbol && assignmentSymbol.exports && assignmentSymbol.exports.get("prototype" as __String);
20235+
const init = prototype && getAssignedJSPrototype(prototype.valueDeclaration);
20236+
return init ? checkExpression(init) : undefined;
2020720237
}
2020820238

2020920239
function getAssignedJSPrototype(node: Node) {
@@ -27419,12 +27449,12 @@ namespace ts {
2741927449
return result;
2742027450
}
2742127451

27422-
function isNodeUsedDuringClassInitialization(node: Node, classDeclaration: ClassLikeDeclaration) {
27452+
function isNodeUsedDuringClassInitialization(node: Node) {
2742327453
return !!findAncestor(node, element => {
27424-
if ((isConstructorDeclaration(element) && nodeIsPresent(element.body) || isPropertyDeclaration(element)) && element.parent === classDeclaration) {
27454+
if (isConstructorDeclaration(element) && nodeIsPresent(element.body) || isPropertyDeclaration(element)) {
2742527455
return true;
2742627456
}
27427-
else if (element === classDeclaration || isFunctionLikeDeclaration(element)) {
27457+
else if (isClassLike(element) || isFunctionLikeDeclaration(element)) {
2742827458
return "quit";
2742927459
}
2743027460

0 commit comments

Comments
 (0)