Skip to content

Commit c583c32

Browse files
committed
Merge branch 'master' into weakType
2 parents e570775 + f489f5a commit c583c32

File tree

82 files changed

+1284
-420
lines changed

Some content is hidden

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

82 files changed

+1284
-420
lines changed

src/compiler/checker.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1642,6 +1642,12 @@ namespace ts {
16421642
return;
16431643
}
16441644

1645+
if (startsWith(moduleReference, "@types/")) {
1646+
const diag = Diagnostics.Cannot_import_type_declaration_files_Consider_importing_0_instead_of_1;
1647+
const withoutAtTypePrefix = removePrefix(moduleReference, "@types/");
1648+
error(errorNode, diag, withoutAtTypePrefix, moduleReference);
1649+
}
1650+
16451651
const ambientModule = tryFindAmbientModule(moduleName, /*withAugmentations*/ true);
16461652
if (ambientModule) {
16471653
return ambientModule;
@@ -4846,14 +4852,15 @@ namespace ts {
48464852
return;
48474853
}
48484854
const baseTypeNode = getBaseTypeNodeOfClass(type);
4855+
const typeArgs = typeArgumentsFromTypeReferenceNode(baseTypeNode);
48494856
let baseType: Type;
48504857
const originalBaseType = baseConstructorType && baseConstructorType.symbol ? getDeclaredTypeOfSymbol(baseConstructorType.symbol) : undefined;
48514858
if (baseConstructorType.symbol && baseConstructorType.symbol.flags & SymbolFlags.Class &&
48524859
areAllOuterTypeParametersApplied(originalBaseType)) {
48534860
// When base constructor type is a class with no captured type arguments we know that the constructors all have the same type parameters as the
48544861
// class and all return the instance type of the class. There is no need for further checks and we can apply the
48554862
// type arguments in the same manner as a type reference to get the same error reporting experience.
4856-
baseType = getTypeFromClassOrInterfaceReference(baseTypeNode, baseConstructorType.symbol, typeArgumentsFromTypeReferenceNode(baseTypeNode));
4863+
baseType = getTypeFromClassOrInterfaceReference(baseTypeNode, baseConstructorType.symbol, typeArgs);
48574864
}
48584865
else if (baseConstructorType.flags & TypeFlags.Any) {
48594866
baseType = baseConstructorType;
@@ -7640,11 +7647,11 @@ namespace ts {
76407647
if (members.has(leftProp.name)) {
76417648
const rightProp = members.get(leftProp.name);
76427649
const rightType = getTypeOfSymbol(rightProp);
7643-
if (maybeTypeOfKind(rightType, TypeFlags.Undefined) || rightProp.flags & SymbolFlags.Optional) {
7650+
if (rightProp.flags & SymbolFlags.Optional) {
76447651
const declarations: Declaration[] = concatenate(leftProp.declarations, rightProp.declarations);
76457652
const flags = SymbolFlags.Property | (leftProp.flags & SymbolFlags.Optional);
76467653
const result = createSymbol(flags, leftProp.name);
7647-
result.type = getUnionType([getTypeOfSymbol(leftProp), getTypeWithFacts(rightType, TypeFacts.NEUndefined)]);
7654+
result.type = getUnionType([getTypeOfSymbol(leftProp), rightType]);
76487655
result.leftSpread = leftProp;
76497656
result.rightSpread = rightProp;
76507657
result.declarations = declarations;

src/compiler/core.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1764,6 +1764,11 @@ namespace ts {
17641764
return str.lastIndexOf(prefix, 0) === 0;
17651765
}
17661766

1767+
/* @internal */
1768+
export function removePrefix(str: string, prefix: string): string {
1769+
return startsWith(str, prefix) ? str.substr(prefix.length) : str;
1770+
}
1771+
17671772
/* @internal */
17681773
export function endsWith(str: string, suffix: string): boolean {
17691774
const expectedPos = str.length - suffix.length;

src/compiler/diagnosticMessages.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3065,6 +3065,10 @@
30653065
"category": "Message",
30663066
"code": 6136
30673067
},
3068+
"Cannot import type declaration files. Consider importing '{0}' instead of '{1}'.": {
3069+
"category": "Error",
3070+
"code": 6137
3071+
},
30683072
"Property '{0}' is declared but never used.": {
30693073
"category": "Error",
30703074
"code": 6138
@@ -3584,6 +3588,15 @@
35843588
"code": 90022
35853589
},
35863590

3591+
"Convert function to an ES2015 class": {
3592+
"category": "Message",
3593+
"code": 95001
3594+
},
3595+
"Convert function '{0}' to class": {
3596+
"category": "Message",
3597+
"code": 95002
3598+
},
3599+
35873600
"Octal literal types must use ES2015 syntax. Use the syntax '{0}'.": {
35883601
"category": "Error",
35893602
"code": 8017

src/compiler/emitter.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,9 @@ namespace ts {
200200
onSetSourceFile,
201201
substituteNode,
202202
onBeforeEmitNodeArray,
203-
onAfterEmitNodeArray
203+
onAfterEmitNodeArray,
204+
onBeforeEmitToken,
205+
onAfterEmitToken
204206
} = handlers;
205207

206208
const newLine = getNewLineCharacter(printerOptions);
@@ -406,7 +408,7 @@ namespace ts {
406408
// Strict mode reserved words
407409
// Contextual keywords
408410
if (isKeyword(kind)) {
409-
writeTokenText(kind);
411+
writeTokenNode(node);
410412
return;
411413
}
412414

@@ -645,7 +647,7 @@ namespace ts {
645647
}
646648

647649
if (isToken(node)) {
648-
writeTokenText(kind);
650+
writeTokenNode(node);
649651
return;
650652
}
651653
}
@@ -672,7 +674,7 @@ namespace ts {
672674
case SyntaxKind.SuperKeyword:
673675
case SyntaxKind.TrueKeyword:
674676
case SyntaxKind.ThisKeyword:
675-
writeTokenText(kind);
677+
writeTokenNode(node);
676678
return;
677679

678680
// Expressions
@@ -1260,7 +1262,7 @@ namespace ts {
12601262
const operand = node.operand;
12611263
return operand.kind === SyntaxKind.PrefixUnaryExpression
12621264
&& ((node.operator === SyntaxKind.PlusToken && ((<PrefixUnaryExpression>operand).operator === SyntaxKind.PlusToken || (<PrefixUnaryExpression>operand).operator === SyntaxKind.PlusPlusToken))
1263-
|| (node.operator === SyntaxKind.MinusToken && ((<PrefixUnaryExpression>operand).operator === SyntaxKind.MinusToken || (<PrefixUnaryExpression>operand).operator === SyntaxKind.MinusMinusToken)));
1265+
|| (node.operator === SyntaxKind.MinusToken && ((<PrefixUnaryExpression>operand).operator === SyntaxKind.MinusToken || (<PrefixUnaryExpression>operand).operator === SyntaxKind.MinusMinusToken)));
12641266
}
12651267

12661268
function emitPostfixUnaryExpression(node: PostfixUnaryExpression) {
@@ -1275,7 +1277,7 @@ namespace ts {
12751277

12761278
emitExpression(node.left);
12771279
increaseIndentIf(indentBeforeOperator, isCommaOperator ? " " : undefined);
1278-
writeTokenText(node.operatorToken.kind);
1280+
writeTokenNode(node.operatorToken);
12791281
increaseIndentIf(indentAfterOperator, " ");
12801282
emitExpression(node.right);
12811283
decreaseIndentIf(indentBeforeOperator, indentAfterOperator);
@@ -2455,6 +2457,16 @@ namespace ts {
24552457
: writeTokenText(token, pos);
24562458
}
24572459

2460+
function writeTokenNode(node: Node) {
2461+
if (onBeforeEmitToken) {
2462+
onBeforeEmitToken(node);
2463+
}
2464+
writeTokenText(node.kind);
2465+
if (onAfterEmitToken) {
2466+
onAfterEmitToken(node);
2467+
}
2468+
}
2469+
24582470
function writeTokenText(token: SyntaxKind, pos?: number) {
24592471
const tokenString = tokenToString(token);
24602472
write(tokenString);
@@ -2928,9 +2940,9 @@ namespace ts {
29282940

29292941
// Flags enum to track count of temp variables and a few dedicated names
29302942
const enum TempFlags {
2931-
Auto = 0x00000000, // No preferred name
2943+
Auto = 0x00000000, // No preferred name
29322944
CountMask = 0x0FFFFFFF, // Temp variable counter
2933-
_i = 0x10000000, // Use/preference flag for '_i'
2945+
_i = 0x10000000, // Use/preference flag for '_i'
29342946
}
29352947

29362948
const enum ListFormat {

src/compiler/factory.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -984,10 +984,10 @@ namespace ts {
984984
return node;
985985
}
986986

987-
export function updateBinary(node: BinaryExpression, left: Expression, right: Expression) {
987+
export function updateBinary(node: BinaryExpression, left: Expression, right: Expression, operator?: BinaryOperator | BinaryOperatorToken) {
988988
return node.left !== left
989989
|| node.right !== right
990-
? updateNode(createBinary(left, node.operatorToken, right), node)
990+
? updateNode(createBinary(left, operator || node.operatorToken, right), node)
991991
: node;
992992
}
993993

src/compiler/program.ts

Lines changed: 45 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,8 @@ namespace ts {
529529
getFileProcessingDiagnostics: () => fileProcessingDiagnostics,
530530
getResolvedTypeReferenceDirectives: () => resolvedTypeReferenceDirectives,
531531
isSourceFileFromExternalLibrary,
532-
dropDiagnosticsProducingTypeChecker
532+
dropDiagnosticsProducingTypeChecker,
533+
getSourceFileFromReference,
533534
};
534535

535536
verifyCompilerOptions();
@@ -1442,48 +1443,60 @@ namespace ts {
14421443
}
14431444
}
14441445

1445-
function processSourceFile(fileName: string, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number) {
1446-
let diagnosticArgument: string[];
1447-
let diagnostic: DiagnosticMessage;
1446+
/** This should have similar behavior to 'processSourceFile' without diagnostics or mutation. */
1447+
function getSourceFileFromReference(referencingFile: SourceFile, ref: FileReference): SourceFile | undefined {
1448+
return getSourceFileFromReferenceWorker(resolveTripleslashReference(ref.fileName, referencingFile.fileName), fileName => filesByName.get(toPath(fileName, currentDirectory, getCanonicalFileName)));
1449+
}
1450+
1451+
function getSourceFileFromReferenceWorker(
1452+
fileName: string,
1453+
getSourceFile: (fileName: string) => SourceFile | undefined,
1454+
fail?: (diagnostic: DiagnosticMessage, ...argument: string[]) => void,
1455+
refFile?: SourceFile): SourceFile | undefined {
1456+
14481457
if (hasExtension(fileName)) {
14491458
if (!options.allowNonTsExtensions && !forEach(supportedExtensions, extension => fileExtensionIs(host.getCanonicalFileName(fileName), extension))) {
1450-
diagnostic = Diagnostics.File_0_has_unsupported_extension_The_only_supported_extensions_are_1;
1451-
diagnosticArgument = [fileName, "'" + supportedExtensions.join("', '") + "'"];
1452-
}
1453-
else if (!findSourceFile(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, refFile, refPos, refEnd)) {
1454-
diagnostic = Diagnostics.File_0_not_found;
1455-
diagnosticArgument = [fileName];
1459+
if (fail) fail(Diagnostics.File_0_has_unsupported_extension_The_only_supported_extensions_are_1, fileName, "'" + supportedExtensions.join("', '") + "'");
1460+
return undefined;
14561461
}
1457-
else if (refFile && host.getCanonicalFileName(fileName) === host.getCanonicalFileName(refFile.fileName)) {
1458-
diagnostic = Diagnostics.A_file_cannot_have_a_reference_to_itself;
1459-
diagnosticArgument = [fileName];
1460-
}
1461-
}
1462-
else {
1463-
const nonTsFile: SourceFile = options.allowNonTsExtensions && findSourceFile(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, refFile, refPos, refEnd);
1464-
if (!nonTsFile) {
1465-
if (options.allowNonTsExtensions) {
1466-
diagnostic = Diagnostics.File_0_not_found;
1467-
diagnosticArgument = [fileName];
1462+
1463+
const sourceFile = getSourceFile(fileName);
1464+
if (fail) {
1465+
if (!sourceFile) {
1466+
fail(Diagnostics.File_0_not_found, fileName);
14681467
}
1469-
else if (!forEach(supportedExtensions, extension => findSourceFile(fileName + extension, toPath(fileName + extension, currentDirectory, getCanonicalFileName), isDefaultLib, refFile, refPos, refEnd))) {
1470-
diagnostic = Diagnostics.File_0_not_found;
1471-
fileName += ".ts";
1472-
diagnosticArgument = [fileName];
1468+
else if (refFile && host.getCanonicalFileName(fileName) === host.getCanonicalFileName(refFile.fileName)) {
1469+
fail(Diagnostics.A_file_cannot_have_a_reference_to_itself, fileName);
14731470
}
14741471
}
1475-
}
1472+
return sourceFile;
1473+
} else {
1474+
const sourceFileNoExtension = options.allowNonTsExtensions && getSourceFile(fileName);
1475+
if (sourceFileNoExtension) return sourceFileNoExtension;
14761476

1477-
if (diagnostic) {
1478-
if (refFile !== undefined && refEnd !== undefined && refPos !== undefined) {
1479-
fileProcessingDiagnostics.add(createFileDiagnostic(refFile, refPos, refEnd - refPos, diagnostic, ...diagnosticArgument));
1480-
}
1481-
else {
1482-
fileProcessingDiagnostics.add(createCompilerDiagnostic(diagnostic, ...diagnosticArgument));
1477+
if (fail && options.allowNonTsExtensions) {
1478+
fail(Diagnostics.File_0_not_found, fileName);
1479+
return undefined;
14831480
}
1481+
1482+
const sourceFileWithAddedExtension = forEach(supportedExtensions, extension => getSourceFile(fileName + extension));
1483+
if (fail && !sourceFileWithAddedExtension) fail(Diagnostics.File_0_not_found, fileName + ".ts");
1484+
return sourceFileWithAddedExtension;
14841485
}
14851486
}
14861487

1488+
/** This has side effects through `findSourceFile`. */
1489+
function processSourceFile(fileName: string, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number): void {
1490+
getSourceFileFromReferenceWorker(fileName,
1491+
fileName => findSourceFile(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, refFile, refPos, refEnd),
1492+
(diagnostic, ...args) => {
1493+
fileProcessingDiagnostics.add(refFile !== undefined && refEnd !== undefined && refPos !== undefined
1494+
? createFileDiagnostic(refFile, refPos, refEnd - refPos, diagnostic, ...args)
1495+
: createCompilerDiagnostic(diagnostic, ...args));
1496+
},
1497+
refFile);
1498+
}
1499+
14871500
function reportFileNamesDifferOnlyInCasingError(fileName: string, existingFileName: string, refFile: SourceFile, refPos: number, refEnd: number): void {
14881501
if (refFile !== undefined && refPos !== undefined && refEnd !== undefined) {
14891502
fileProcessingDiagnostics.add(createFileDiagnostic(refFile, refPos, refEnd - refPos,

src/compiler/types.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2425,6 +2425,8 @@ namespace ts {
24252425
/* @internal */ isSourceFileFromExternalLibrary(file: SourceFile): boolean;
24262426
// For testing purposes only.
24272427
/* @internal */ structureIsReused?: StructureIsReused;
2428+
2429+
/* @internal */ getSourceFileFromReference(referencingFile: SourceFile, ref: FileReference): SourceFile | undefined;
24282430
}
24292431

24302432
/* @internal */
@@ -3413,7 +3415,7 @@ namespace ts {
34133415
export enum DiagnosticCategory {
34143416
Warning,
34153417
Error,
3416-
Message,
3418+
Message
34173419
}
34183420

34193421
export enum ModuleResolutionKind {
@@ -4271,6 +4273,8 @@ namespace ts {
42714273
/*@internal*/ onSetSourceFile?: (node: SourceFile) => void;
42724274
/*@internal*/ onBeforeEmitNodeArray?: (nodes: NodeArray<any>) => void;
42734275
/*@internal*/ onAfterEmitNodeArray?: (nodes: NodeArray<any>) => void;
4276+
/*@internal*/ onBeforeEmitToken?: (node: Node) => void;
4277+
/*@internal*/ onAfterEmitToken?: (node: Node) => void;
42744278
}
42754279

42764280
export interface PrinterOptions {

src/compiler/utilities.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1918,21 +1918,19 @@ namespace ts {
19181918
const isNoDefaultLibRegEx = /^(\/\/\/\s*<reference\s+no-default-lib\s*=\s*)('|")(.+?)\2\s*\/>/gim;
19191919
if (simpleReferenceRegEx.test(comment)) {
19201920
if (isNoDefaultLibRegEx.test(comment)) {
1921-
return {
1922-
isNoDefaultLib: true
1923-
};
1921+
return { isNoDefaultLib: true };
19241922
}
19251923
else {
19261924
const refMatchResult = fullTripleSlashReferencePathRegEx.exec(comment);
19271925
const refLibResult = !refMatchResult && fullTripleSlashReferenceTypeReferenceDirectiveRegEx.exec(comment);
1928-
if (refMatchResult || refLibResult) {
1929-
const start = commentRange.pos;
1930-
const end = commentRange.end;
1926+
const match = refMatchResult || refLibResult;
1927+
if (match) {
1928+
const pos = commentRange.pos + match[1].length + match[2].length;
19311929
return {
19321930
fileReference: {
1933-
pos: start,
1934-
end: end,
1935-
fileName: (refMatchResult || refLibResult)[3]
1931+
pos,
1932+
end: pos + match[3].length,
1933+
fileName: match[3]
19361934
},
19371935
isNoDefaultLib: false,
19381936
isTypeReferenceDirective: !!refLibResult

src/compiler/visitor.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,8 @@ namespace ts {
516516
case SyntaxKind.BinaryExpression:
517517
return updateBinary(<BinaryExpression>node,
518518
visitNode((<BinaryExpression>node).left, visitor, isExpression),
519-
visitNode((<BinaryExpression>node).right, visitor, isExpression));
519+
visitNode((<BinaryExpression>node).right, visitor, isExpression),
520+
visitNode((<BinaryExpression>node).operatorToken, visitor, isToken));
520521

521522
case SyntaxKind.ConditionalExpression:
522523
return updateConditional(<ConditionalExpression>node,

0 commit comments

Comments
 (0)