8000 merge with origin/master · johnangularjs/TypeScript@ae7d687 · GitHub
[go: up one dir, main page]

Skip to content

Commit ae7d687

Browse files
committed
merge with origin/master
2 parents 314b162 + 0163675 commit ae7d687

File tree

58 files changed

+2634
-771
lines changed

Some content is hidden

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

58 files changed

+2634
-771
lines changed

Jakefile.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -924,7 +924,8 @@ function lintFileAsync(options, path, cb) {
924924
var lintTargets = compilerSources
925925
.concat(harnessCoreSources)
926926
.concat(serverCoreSources)
927-
.concat(scriptSources);
927+
.concat(scriptSources)
928+
.concat([path.join(servicesDirectory, "services.ts")]);
928929

929930
desc("Runs tslint on the compiler sources");
930931
task("lint", ["build-rules"], function() {

src/compiler/checker.ts

Lines changed: 123 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3507,7 +3507,7 @@ namespace ts {
35073507

35083508
function findMatchingSignature(signatureList: Signature[], signature: Signature, partialMatch: boolean, ignoreReturnTypes: boolean): Signature {
35093509
for (const s of signatureList) {
3510-
if (compareSignatures(s, signature, partialMatch, ignoreReturnTypes, compareTypes)) {
3510+
if (compareSignaturesIdentical(s, signature, partialMatch, ignoreReturnTypes, compareTypesIdentical)) {
35113511
return s;
35123512
}
35133513
}
@@ -3768,11 +3768,14 @@ namespace ts {
37683768
function createUnionOrIntersectionProperty(containingType: UnionOrIntersectionType, name: string): Symbol {
37693769
const types = containingType.types;
37703770
let props: Symbol[];
3771+
// Flags we want to propagate to the result if they exist in all source symbols
3772+
let commonFlags = (containingType.flags & TypeFlags.Intersection) ? SymbolFlags.Optional : SymbolFlags.None;
37713773
for (const current of types) {
37723774
const type = getApparentType(current);
37733775
if (type !== unknownType) {
37743776
const prop = getPropertyOfType(type, name);
37753777
if (prop && !(getDeclarationFlagsFromSymbol(prop) & (NodeFlags.Private | NodeFlags.Protected))) {
3778+
commonFlags &= prop.flags;
37763779
if (!props) {
37773780
props = [prop];
37783781
}
@@ -3800,7 +3803,12 @@ namespace ts {
38003803
}
38013804
propTypes.push(getTypeOfSymbol(prop));
38023805
}
3803-
const result = <TransientSymbol>createSymbol(SymbolFlags.Property | SymbolFlags.Transient | SymbolFlags.SyntheticProperty, name);
3806+
const result = <TransientSymbol>createSymbol(
3807+
SymbolFlags.Property |
3808+
SymbolFlags.Transient |
3809+
SymbolFlags.SyntheticProperty |
3810+
commonFlags,
3811+
name);
38043812
result.containingType = containingType;
38053813
result.declarations = declarations;
38063814
result.type = containingType.flags & TypeFlags.Union ? getUnionType(propTypes) : getIntersectionType(propTypes);
@@ -4959,7 +4967,7 @@ namespace ts {
49594967
return checkTypeRelatedTo(source, target, identityRelation, /*errorNode*/ undefined);
49604968
}
49614969

4962-
function compareTypes(source: Type, target: Type): Ternary {
4970+
function compareTypesIdentical(source: Type, target: Type): Ternary {
49634971
return checkTypeRelatedTo(source, target, identityRelation, /*errorNode*/ undefined) ? Ternary.True : Ternary.False;
49644972
}
49654973

@@ -4979,10 +4987,96 @@ namespace ts {
49794987
return checkTypeRelatedTo(source, target, assignableRelation, errorNode, headMessage, containingMessageChain);
49804988
}
49814989

4982-
function isSignatureAssignableTo(source: Signature, target: Signature): boolean {
4983-
const sourceType = getOrCreateTypeFromSignature(source);
4984-
const targetType = getOrCreateTypeFromSignature(target);
4985-
return checkTypeRelatedTo(sourceType, targetType, assignableRelation, /*errorNode*/ undefined);
4990+
/**
4991+
* See signatureRelatedTo, compareSignaturesIdentical
4992+
*/
4993+
function isSignatureAssignableTo(source: Signature, target: Signature, ignoreReturnTypes: boolean): boolean {
4994+
// TODO (drosen): De-duplicate code between related functions.
4995+
if (source === target) {
4996+
return true;
4997+
}
4998+
if (!target.hasRestParameter && source.minArgumentCount > target.parameters.length) {
4999+
return false;
5000+
}
5001+
5002+
// Spec 1.0 Section 3.8.3 & 3.8.4:
5003+
// M and N (the signatures) are instantiated using type Any as the type argument for all type parameters declared by M and N
5004+
source = getErasedSignature(source);
5005+
target = getErasedSignature(target);
5006+
5007+
const sourceMax = getNumNonRestParameters(source);
5008+
const targetMax = getNumNonRestParameters(target);
5009+
const checkCount = getNumParametersToCheckForSignatureRelatability(source, sourceMax, target, targetMax);
5010+
for (let i = 0; i < checkCount; i++) {
5011+
const s = i < sourceMax ? getTypeOfSymbol(source.parameters[i]) : getRestTypeOfSignature(source);
5012+
const t = i < targetMax ? getTypeOfSymbol(target.parameters[i]) : getRestTypeOfSignature(target);
5013+
const related = isTypeAssignableTo(t, s) || isTypeAssignableTo(s, t);
5014+
if (!related) {
5015+
return false;
5016+
}
5017+
}
5018+
5019+
if (!ignoreReturnTypes) {
5020+
const targetReturnType = getReturnTypeOfSignature(target);
5021+
if (targetReturnType === voidType) {
5022+
return true;
5023+
}
5024+
const sourceReturnType = getReturnTypeOfSignature(source);
5025+
5026+
// The following block preserves behavior forbidding boolean returning functions from being assignable to type guard returning functions
5027+
if (targetReturnType.flags & TypeFlags.PredicateType && (targetReturnType as PredicateType).predicate.kind === TypePredicateKind.Identifier) {
5028+
if (!(sourceReturnType.flags & TypeFlags.PredicateType)) {
5029+
return false;
5030+
}
5031+
}
5032+
5033+
return isTypeAssignableTo(sourceReturnType, targetReturnType);
5034+
}
5035+
5036+
return true;
5037+
}
5038+
5039+
function isImplementationCompatibleWithOverload(implementation: Signature, overload: Signature): boolean {
5040+
const erasedSource = getErasedSignature(implementation);
5041+
const erasedTarget = getErasedSignature(overload);
5042+
5043+
// First see if the return types are compatible in either direction.
5044+
const sourceReturnType = getReturnTypeOfSignature(erasedSource);
5045+
const targetReturnType = getReturnTypeOfSignature(erasedTarget);
5046+
if (targetReturnType === voidType
5047+
|| checkTypeRelatedTo(targetReturnType, sourceReturnType, assignableRelation, /*errorNode*/ undefined)
5048+
|| checkTypeRelatedTo(sourceReturnType, targetReturnType, assignableRelation, /*errorNode*/ undefined)) {
5049+
5050+
return isSignatureAssignableTo(erasedSource, erasedTarget, /*ignoreReturnTypes*/ true);
5051+
}
5052+
5053+
return false;
5054+
}
5055+
5056+
function getNumNonRestParameters(signature: Signature) {
5057+
const numParams = signature.parameters.length;
5058+
return signature.hasRestParameter ?
5059+
numParams - 1 :
5060+
numParams;
5061+
}
5062+
5063+
function getNumParametersToCheckForSignatureRelatability(source: Signature, sourceNonRestParamCount: number, target: Signature, targetNonRestParamCount: number) {
5064+
if (source.hasRestParameter === target.hasRestParameter) {
5065+
if (source.hasRestParameter) {
5066+
// If both have rest parameters, get the max and add 1 to
5067+
// compensate for the rest parameter.
5068+
return Math.max(sourceNonRestParamCount, targetNonRestParamCount) + 1;
5069+
}
5070+
else {
5071+
return Math.min(sourceNonRestParamCount, targetNonRestParamCount);
5072+
}
5073+
}
5074+
else {
5075+
// Return the count for whichever signature doesn't have rest parameters.
5076+
return source.hasRestParameter ?
5077+
targetNonRestParamCount :
5078+
sourceNonRestParamCount;
5079+
}
49865080
}
49875081

49885082
/**
@@ -5574,7 +5668,7 @@ namespace ts {
55745668
shouldElaborateErrors = false;
55755669
}
55765670
}
5577-
// don't elaborate the primitive apparent types (like Number)
5671+
// don't elaborate the primitive apparent types (like Number)
55785672
// because the actual primitives will have already been reported.
55795673
if (shouldElaborateErrors && !isPrimitiveApparentType(source)) {
55805674
reportError(Diagnostics.Type_0_provides_no_match_for_the_signature_1,
@@ -5621,7 +5715,11 @@ namespace ts {
56215715
}
56225716
}
56235717

5718+
/**
5719+
* See signatureAssignableTo, signatureAssignableTo
5720+
*/
56245721
function signatureRelatedTo(source: Signature, target: Signature, reportErrors: boolean): Ternary {
5722+
// TODO (drosen): De-duplicate code between related functions.
56255723
if (source === target) {
56265724
return Ternary.True;
56275725
}
@@ -5673,10 +5771,12 @@ namespace ts {
56735771
}
56745772

56755773
const targetReturnType = getReturnTypeOfSignature(target);
5676-
if (targetReturnType === voidType) return result;
5774+
if (targetReturnType === voidType) {
5775+
return result;
5776+
}
56775777
const sourceReturnType = getReturnTypeOfSignature(source);
56785778

5679-
// The follow block preserves old behavior forbidding boolean returning functions from being assignable to type guard returning functions
5779+
// The following block preserves behavior forbidding boolean returning functions from being assignable to type guard returning functions
56805780
if (targetReturnType.flags & TypeFlags.PredicateType && (targetReturnType as PredicateType).predicate.kind === TypePredicateKind.Identifier) {
56815781
if (!(sourceReturnType.flags & TypeFlags.PredicateType)) {
56825782
if (reportErrors) {
@@ -5697,7 +5797,7 @@ namespace ts {
56975797
}
56985798
let result = Ternary.True;
56995799
for (let i = 0, len = sourceSignatures.length; i < len; ++i) {
5700-
const related = compareSignatures(sourceSignatures[i], targetSignatures[i], /*partialMatch*/ false, /*ignoreReturnTypes*/ false, isRelatedTo);
5800+
const related = compareSignaturesIdentical(sourceSignatures[i], targetSignatures[i], /*partialMatch*/ false, /*ignoreReturnTypes*/ false, isRelatedTo);
57015801
if (!related) {
57025802
return Ternary.False;
57035803
}
@@ -5830,7 +5930,7 @@ namespace ts {
58305930
}
58315931

58325932
function isPropertyIdenticalTo(sourceProp: Symbol, targetProp: Symbol): boolean {
5833-
return compareProperties(sourceProp, targetProp, compareTypes) !== Ternary.False;
5933+
return compareProperties(sourceProp, targetProp, compareTypesIdentical) !== Ternary.False;
58345934
}
58355935

58365936
function compareProperties(sourceProp: Symbol, targetProp: Symbol, compareTypes: (source: Type, target: Type) => Ternary): Ternary {
@@ -5877,7 +5977,11 @@ namespace ts {
58775977
return false;
58785978
}
58795979

5880-
function compareSignatures(source: Signature, target: Signature, partialMatch: boolean, ignoreReturnTypes: boolean, compareTypes: (s: Type, t: Type) => Ternary): Ternary {
5980+
/**
5981+
* See signatureRelatedTo, compareSignaturesIdentical
5982+
*/
5983+
function compareSignaturesIdentical(source: Signature, target: Signature, partialMatch: boolean, ignoreReturnTypes: boolean, compareTypes: (s: Type, t: Type) => Ternary): Ternary {
5984+
// TODO (drosen): De-duplicate code between related functions.
58815985
if (source === target) {
58825986
return Ternary.True;
58835987
}
@@ -7605,7 +7709,7 @@ namespace ts {
76057709
// This signature will contribute to contextual union signature
76067710
signatureList = [signature];
76077711
}
7608-
else if (!compareSignatures(signatureList[0], signature, /*partialMatch*/ false, /*ignoreReturnTypes*/ true, compareTypes)) {
7712+
else if (!compareSignaturesIdentical(signatureList[0], signature, /*partialMatch*/ false, /*ignoreReturnTypes*/ true, compareTypesIdentical)) {
76097713
// Signatures aren't identical, do not use
76107714
return undefined;
76117715
}
@@ -8280,9 +8384,9 @@ namespace ts {
82808384
// Props is of type 'any' or unknown
82818385
return links.resolvedJsxType = attributesType;
82828386
}
8283-
else if (!(attributesType.flags & TypeFlags.ObjectType)) {
8284-
// Props is not an object type
8285-
error(node.tagName, Diagnostics.JSX_element_attributes_type_0_must_be_an_object_type, typeToString(attributesType));
8387+
else if (attributesType.flags & TypeFlags.Union) {
8388+
// Props cannot be a union type
8389+
error(node.tagName, Diagnostics.JSX_element_attributes_type_0_may_not_be_a_union_type, typeToString(attributesType));
82868390
return links.resolvedJsxType = anyType;
82878391
}
82888392
else {
@@ -11626,7 +11730,7 @@ namespace ts {
1162611730
}
1162711731

1162811732
for (const otherSignature of signaturesToCheck) {
11629-
if (!otherSignature.hasStringLiterals && isSignatureAssignableTo(signature, otherSignature)) {
11733+
if (!otherSignature.hasStringLiterals && isSignatureAssignableTo(signature, otherSignature, /*ignoreReturnTypes*/ false)) {
1163011734
return;
1163111735
}
1163211736
}
@@ -11873,7 +11977,7 @@ namespace ts {
1187311977
//
1187411978
// The implementation is completely unrelated to the specialized signature, yet we do not check this.
1187511979
for (const signature of signatures) {
11876-
if (!signature.hasStringLiterals && !isSignatureAssignableTo(bodySignature, signature)) {
11980+
if (!signature.hasStringLiterals && !isImplementationCompatibleWithOverload(bodySignature, signature)) {
1187711981
error(signature.declaration, Diagnostics.Overload_signature_is_not_compatible_with_function_implementation);
1187811982
break;
1187911983
}

src/compiler/diagnosticMessages.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1691,7 +1691,7 @@
16911691
"category": "Error",
16921692
"code": 2528
16931693
},
1694-
"JSX element attributes type '{0}' must be an object type.": {
1694+
"JSX element attributes type '{0}' may not be a union type.": {
16951695
"category": "Error",
16961696
"code": 2600
16971697
},

0 commit comments

Comments
 (0)
0