Skip to content

Commit ee7b93c

Browse files
committed
Merge branch 'master' into contextualThisType
2 parents c87c124 + fc9bcc1 commit ee7b93c

File tree

292 files changed

+2544
-1376
lines changed

Some content is hidden

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

292 files changed

+2544
-1376
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,4 @@ internal/
5757
!tests/cases/projects/NodeModulesSearch/**/*
5858
!tests/baselines/reference/project/nodeModules*/**/*
5959
.idea
60+
yarn.lock

Gulpfile.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,6 @@ declare module "gulp-typescript" {
2121
import * as insert from "gulp-insert";
2222
import * as sourcemaps from "gulp-sourcemaps";
2323
import Q = require("q");
24-
declare global {
25-
// `del` further depends on `Promise` (and is also not included), so we just, patch the global scope's Promise to Q's (which we already include in our deps because gulp depends on it)
26-
type Promise<T> = Q.Promise<T>;
27-
}
2824
import del = require("del");
2925
import mkdirP = require("mkdirp");
3026
import minimist = require("minimist");

Jakefile.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,7 @@ var watchGuardFile = path.join(builtLocalDirectory, "watchGuard.js");
587587
compileFile(watchGuardFile, watchGuardSources, [builtLocalDirectory].concat(watchGuardSources), /*prefixes*/ [copyright], /*useBuiltCompiler*/ true, { outDir: builtLocalDirectory, noOutFile: false });
588588

589589
var serverFile = path.join(builtLocalDirectory, "tsserver.js");
590-
compileFile(serverFile, serverSources, [builtLocalDirectory, copyright, cancellationTokenFile, typingsInstallerFile, watchGuardFile].concat(serverSources), /*prefixes*/ [copyright], /*useBuiltCompiler*/ true, { types: ["node"], preserveConstEnums: true });
590+
compileFile(serverFile, serverSources, [builtLocalDirectory, copyright, cancellationTokenFile, typingsInstallerFile, watchGuardFile].concat(serverSources).concat(servicesSources), /*prefixes*/ [copyright], /*useBuiltCompiler*/ true, { types: ["node"], preserveConstEnums: true });
591591
var tsserverLibraryFile = path.join(builtLocalDirectory, "tsserverlibrary.js");
592592
var tsserverLibraryDefinitionFile = path.join(builtLocalDirectory, "tsserverlibrary.d.ts");
593593
compileFile(

src/compiler/binder.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,12 @@ namespace ts {
670670
case SyntaxKind.CallExpression:
671671
bindCallExpressionFlow(<CallExpression>node);
672672
break;
673+
case SyntaxKind.JSDocComment:
674+
bindJSDocComment(<JSDoc>node);
675+
break;
676+
case SyntaxKind.JSDocTypedefTag:
677+
bindJSDocTypedefTag(<JSDocTypedefTag>node);
678+
break;
673679
default:
674680
bindEachChild(node);
675681
break;
@@ -1335,6 +1341,26 @@ namespace ts {
13351341
}
13361342
}
13371343

1344+
function bindJSDocComment(node: JSDoc) {
1345+
forEachChild(node, n => {
1346+
if (n.kind !== SyntaxKind.JSDocTypedefTag) {
1347+
bind(n);
1348+
}
1349+
});
1350+
}
1351+
1352+
function bindJSDocTypedefTag(node: JSDocTypedefTag) {
1353+
forEachChild(node, n => {
1354+
// if the node has a fullName "A.B.C", that means symbol "C" was already bound
1355+
// when we visit "fullName"; so when we visit the name "C" as the next child of
1356+
// the jsDocTypedefTag, we should skip binding it.
1357+
if (node.fullName && n === node.name && node.fullName.kind !== SyntaxKind.Identifier) {
1358+
return;
1359+
}
1360+
bind(n);
1361+
});
1362+
}
1363+
13381364
function bindCallExpressionFlow(node: CallExpression) {
13391365
// If the target of the call expression is a function expression or arrow function we have
13401366
// an immediately invoked function expression (IIFE). Initialize the flowNode property to
@@ -1874,6 +1900,18 @@ namespace ts {
18741900
}
18751901
node.parent = parent;
18761902
const saveInStrictMode = inStrictMode;
1903+
1904+
// Even though in the AST the jsdoc @typedef node belongs to the current node,
1905+
// its symbol might be in the same scope with the current node's symbol. Consider:
1906+
//
1907+
// /** @typedef {string | number} MyType */
1908+
// function foo();
1909+
//
1910+
// Here the current node is "foo", which is a container, but the scope of "MyType" should
1911+
// not be inside "foo". Therefore we always bind @typedef before bind the parent node,
1912+
// and skip binding this tag later when binding all the other jsdoc tags.
1913+
bindJSDocTypedefTagIfAny(node);
1914+
18771915
// First we bind declaration nodes to a symbol if possible. We'll both create a symbol
18781916
// and then potentially add the symbol to an appropriate symbol table. Possible
18791917
// destination symbol tables are:
@@ -1908,6 +1946,27 @@ namespace ts {
19081946
inStrictMode = saveInStrictMode;
19091947
}
19101948

1949+
function bindJSDocTypedefTagIfAny(node: Node) {
1950+
if (!node.jsDoc) {
1951+
return;
1952+
}
1953+
1954+
for (const jsDoc of node.jsDoc) {
1955+
if (!jsDoc.tags) {
1956+
continue;
1957+
}
1958+
1959+
for (const tag of jsDoc.tags) {
1960+
if (tag.kind === SyntaxKind.JSDocTypedefTag) {
1961+
const savedParent = parent;
1962+
parent = jsDoc;
1963+
bind(tag);
1964+
parent = savedParent;
1965+
}
1966+
}
1967+
}
1968+
}
1969+
19111970
function updateStrictModeStatementList(statements: NodeArray<Statement>) {
19121971
if (!inStrictMode) {
19131972
for (const statement of statements) {

src/compiler/checker.ts

Lines changed: 51 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3959,7 +3959,7 @@ namespace ts {
39593959
}
39603960
if (type.flags & TypeFlags.TypeVariable) {
39613961
const constraint = getBaseConstraintOfType(<TypeVariable>type);
3962-
return isValidBaseType(constraint) && isMixinConstructorType(constraint);
3962+
return constraint && isValidBaseType(constraint) && isMixinConstructorType(constraint);
39633963
}
39643964
return false;
39653965
}
@@ -5904,15 +5904,52 @@ namespace ts {
59045904
return getTypeFromNonGenericTypeReference(node, symbol);
59055905
}
59065906

5907+
function getPrimitiveTypeFromJSDocTypeReference(node: JSDocTypeReference): Type {
5908+
if (isIdentifier(node.name)) {
5909+
switch (node.name.text) {
5910+
case "String":
5911+
return stringType;
5912+
case "Number":
5913+
return numberType;
5914+
case "Boolean":
5915+
return booleanType;
5916+
case "Void":
5917+
return voidType;
5918+
case "Undefined":
5919+
return undefinedType;
5920+
case "Null":
5921+
return nullType;
5922+
case "Object":
5923+
return anyType;
5924+
case "Function":
5925+
return anyFunctionType;
5926+
case "Array":
5927+
case "array":
5928+
return !node.typeArguments || !node.typeArguments.length ? createArrayType(anyType) : undefined;
5929+
case "Promise":
5930+
case "promise":
5931+
return !node.typeArguments || !node.typeArguments.length ? createPromiseType(anyType) : undefined;
5932+
}
5933+
}
5934+
}
5935+
5936+
function getTypeFromJSDocNullableTypeNode(node: JSDocNullableType) {
5937+
const type = getTypeFromTypeNode(node.type);
5938+
return strictNullChecks ? getUnionType([type, nullType]) : type;
5939+
}
5940+
59075941
function getTypeFromTypeReference(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference): Type {
59085942
const links = getNodeLinks(node);
59095943
if (!links.resolvedType) {
59105944
let symbol: Symbol;
59115945
let type: Type;
59125946
if (node.kind === SyntaxKind.JSDocTypeReference) {
5913-
const typeReferenceName = getTypeReferenceName(node);
5914-
symbol = resolveTypeReferenceName(typeReferenceName);
5915-
type = getTypeReferenceType(node, symbol);
5947+
type = getPrimitiveTypeFromJSDocTypeReference(<JSDocTypeReference>node);
5948+
if (!type) {
5949+
const typeReferenceName = getTypeReferenceName(node);
5950+
symbol = resolveTypeReferenceName(typeReferenceName);
5951+
type = getTypeReferenceType(node, symbol);
5952+
}
59165953
}
59175954
else {
59185955
// We only support expressions that are simple qualified names. For other expressions this produces undefined.
@@ -6824,12 +6861,6 @@ namespace ts {
68246861
return neverType;
68256862
case SyntaxKind.ObjectKeyword:
68266863
return nonPrimitiveType;
6827-
case SyntaxKind.JSDocNullKeyword:
6828-
return nullType;
6829-
case SyntaxKind.JSDocUndefinedKeyword:
6830-
return undefinedType;
6831-
case SyntaxKind.JSDocNeverKeyword:
6832-
return neverType;
68336864
case SyntaxKind.ThisType:
68346865
case SyntaxKind.ThisKeyword:
68356866
return getTypeFromThisTypeNode(node);
@@ -6856,8 +6887,9 @@ namespace ts {
68566887
return getTypeFromUnionTypeNode(<UnionTypeNode>node);
68576888
case SyntaxKind.IntersectionType:
68586889
return getTypeFromIntersectionTypeNode(<IntersectionTypeNode>node);
6859-
case SyntaxKind.ParenthesizedType:
68606890
case SyntaxKind.JSDocNullableType:
6891+
return getTypeFromJSDocNullableTypeNode(<JSDocNullableType>node);
6892+
case SyntaxKind.ParenthesizedType:
68616893
case SyntaxKind.JSDocNonNullableType:
68626894
case SyntaxKind.JSDocConstructorType:
68636895
case SyntaxKind.JSDocThisType:
@@ -12814,11 +12846,6 @@ namespace ts {
1281412846
// Props is of type 'any' or unknown
1281512847
return attributesType;
1281612848
}
12817-
else if (attributesType.flags & TypeFlags.Union) {
12818-
// Props cannot be a union type
12819-
error(openingLikeElement.tagName, Diagnostics.JSX_element_attributes_type_0_may_not_be_a_union_type, typeToString(attributesType));
12820-
return anyType;
12821-
}
1282212849
else {
1282312850
// Normal case -- add in IntrinsicClassElements<T> and IntrinsicElements
1282412851
let apparentAttributesType = attributesType;
@@ -15962,12 +15989,16 @@ namespace ts {
1596215989
checkAssignmentOperator(rightType);
1596315990
return getRegularTypeOfObjectLiteral(rightType);
1596415991
case SyntaxKind.CommaToken:
15965-
if (!compilerOptions.allowUnreachableCode && isSideEffectFree(left)) {
15992+
if (!compilerOptions.allowUnreachableCode && isSideEffectFree(left) && !isEvalNode(right)) {
1596615993
error(left, Diagnostics.Left_side_of_comma_operator_is_unused_and_has_no_side_effects);
1596715994
}
1596815995
return rightType;
1596915996
}
1597015997

15998+
function isEvalNode(node: Expression) {
15999+
return node.kind === SyntaxKind.Identifier && (node as Identifier).text === "eval";
16000+
}
16001+
1597116002
// Return true if there was no error, false if there was an error.
1597216003
function checkForDisallowedESSymbolOperand(operator: SyntaxKind): boolean {
1597316004
const offendingSymbolOperand =
@@ -20958,7 +20989,9 @@ namespace ts {
2095820989
return getSymbolOfNode(entityName.parent);
2095920990
}
2096020991

20961-
if (isInJavaScriptFile(entityName) && entityName.parent.kind === SyntaxKind.PropertyAccessExpression) {
20992+
if (isInJavaScriptFile(entityName) &&
20993+
entityName.parent.kind === SyntaxKind.PropertyAccessExpression &&
20994+
entityName.parent === (entityName.parent.parent as BinaryExpression).left) {
2096220995
// Check if this is a special property assignment
2096320996
const specialPropertyAssignmentSymbol = getSpecialPropertyAssignmentSymbolFromEntityName(entityName);
2096420997
if (specialPropertyAssignmentSymbol) {

0 commit comments

Comments
 (0)