diff --git a/Jakefile.js b/Jakefile.js
index 15ad9c7be52..7d28fd8e396 100644
--- a/Jakefile.js
+++ b/Jakefile.js
@@ -653,7 +653,10 @@ compileFile(word2mdJs,
[word2mdTs],
[word2mdTs],
[],
- /*useBuiltCompiler*/ false);
+ /*useBuiltCompiler*/ false,
+ {
+ lib: "scripthost,es5"
+ });
// The generated spec.md; built for the 'generate-spec' task
file(specMd, [word2mdJs, specWord], function () {
diff --git a/scripts/processDiagnosticMessages.ts b/scripts/processDiagnosticMessages.ts
index 20085022c04..dd66564b134 100644
--- a/scripts/processDiagnosticMessages.ts
+++ b/scripts/processDiagnosticMessages.ts
@@ -1,4 +1,5 @@
///
+///
interface DiagnosticDetails {
category: string;
@@ -9,57 +10,55 @@ interface DiagnosticDetails {
type InputDiagnosticMessageTable = ts.Map;
function main(): void {
- var sys = ts.sys;
+ const sys = ts.sys;
if (sys.args.length < 1) {
- sys.write("Usage:" + sys.newLine)
+ sys.write("Usage:" + sys.newLine);
sys.write("\tnode processDiagnosticMessages.js " + sys.newLine);
return;
}
function writeFile(fileName: string, contents: string) {
- // TODO: Fix path joining
- var inputDirectory = inputFilePath.substr(0,inputFilePath.lastIndexOf("/"));
- var fileOutputPath = inputDirectory + "/" + fileName;
+ const inputDirectory = ts.getDirectoryPath(inputFilePath);
+ const fileOutputPath = ts.combinePaths(inputDirectory, fileName);
sys.writeFile(fileOutputPath, contents);
}
- var inputFilePath = sys.args[0].replace(/\\/g, "/");
- var inputStr = sys.readFile(inputFilePath);
+ const inputFilePath = sys.args[0].replace(/\\/g, "/");
+ const inputStr = sys.readFile(inputFilePath);
- var diagnosticMessagesJson: { [key: string]: DiagnosticDetails } = JSON.parse(inputStr);
- // Check that there are no duplicates.
- const seenNames = ts.createMap();
- for (const name of Object.keys(diagnosticMessagesJson)) {
- if (seenNames.has(name))
- throw new Error(`Name ${name} appears twice`);
- seenNames.set(name, true);
- }
+ const diagnosticMessagesJson: { [key: string]: DiagnosticDetails } = JSON.parse(inputStr);
const diagnosticMessages: InputDiagnosticMessageTable = ts.createMapFromTemplate(diagnosticMessagesJson);
- var infoFileOutput = buildInfoFileOutput(diagnosticMessages);
+ const outputFilesDir = ts.getDirectoryPath(inputFilePath);
+ const thisFilePathRel = ts.getRelativePathToDirectoryOrUrl(outputFilesDir, sys.getExecutingFilePath(),
+ sys.getCurrentDirectory(), ts.createGetCanonicalFileName(sys.useCaseSensitiveFileNames), /* isAbsolutePathAnUrl */ false);
+
+ const infoFileOutput = buildInfoFileOutput(diagnosticMessages, "./diagnosticInformationMap.generated.ts", thisFilePathRel);
checkForUniqueCodes(diagnosticMessages);
writeFile("diagnosticInformationMap.generated.ts", infoFileOutput);
- var messageOutput = buildDiagnosticMessageOutput(diagnosticMessages);
+ const messageOutput = buildDiagnosticMessageOutput(diagnosticMessages);
writeFile("diagnosticMessages.generated.json", messageOutput);
}
function checkForUniqueCodes(diagnosticTable: InputDiagnosticMessageTable) {
const allCodes: { [key: number]: true | undefined } = [];
diagnosticTable.forEach(({ code }) => {
- if (allCodes[code])
+ if (allCodes[code]) {
throw new Error(`Diagnostic code ${code} appears more than once.`);
+ }
allCodes[code] = true;
});
}
-function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable): string {
- var result =
- '// \r\n' +
- '/// \r\n' +
- '/* @internal */\r\n' +
- 'namespace ts {\r\n' +
+function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable, inputFilePathRel: string, thisFilePathRel: string): string {
+ let result =
+ "// \r\n" +
+ "// generated from '" + inputFilePathRel + "' by '" + thisFilePathRel + "'\r\n" +
+ "/// \r\n" +
+ "/* @internal */\r\n" +
+ "namespace ts {\r\n" +
" function diag(code: number, category: DiagnosticCategory, key: string, message: string): DiagnosticMessage {\r\n" +
" return { code, category, key, message };\r\n" +
" }\r\n" +
@@ -70,20 +69,20 @@ function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable): string
result += ` ${propName}: diag(${code}, DiagnosticCategory.${category}, "${createKey(propName, code)}", ${JSON.stringify(name)}),\r\n`;
});
- result += ' };\r\n}';
+ result += " };\r\n}";
return result;
}
function buildDiagnosticMessageOutput(messageTable: InputDiagnosticMessageTable): string {
- let result = '{';
+ let result = "{";
messageTable.forEach(({ code }, name) => {
const propName = convertPropertyName(name);
result += `\r\n "${createKey(propName, code)}" : "${name.replace(/[\"]/g, '\\"')}",`;
});
// Shave trailing comma, then add newline and ending brace
- result = result.slice(0, result.length - 1) + '\r\n}';
+ result = result.slice(0, result.length - 1) + "\r\n}";
// Assert that we generated valid JSON
JSON.parse(result);
@@ -91,15 +90,15 @@ function buildDiagnosticMessageOutput(messageTable: InputDiagnosticMessageTable)
return result;
}
-function createKey(name: string, code: number) : string {
- return name.slice(0, 100) + '_' + code;
+function createKey(name: string, code: number): string {
+ return name.slice(0, 100) + "_" + code;
}
function convertPropertyName(origName: string): string {
- var result = origName.split("").map(char => {
- if (char === '*') { return "_Asterisk"; }
- if (char === '/') { return "_Slash"; }
- if (char === ':') { return "_Colon"; }
+ let result = origName.split("").map(char => {
+ if (char === "*") { return "_Asterisk"; }
+ if (char === "/") { return "_Slash"; }
+ if (char === ":") { return "_Colon"; }
return /\w/.test(char) ? char : "_";
}).join("");
@@ -107,7 +106,7 @@ function convertPropertyName(origName: string): string {
result = result.replace(/_+/g, "_");
// remove any leading underscore, unless it is followed by a number.
- result = result.replace(/^_([^\d])/, "$1")
+ result = result.replace(/^_([^\d])/, "$1");
// get rid of all trailing underscores.
result = result.replace(/_$/, "");
diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts
index cf8b3eefde8..a0146740678 100644
--- a/src/compiler/binder.ts
+++ b/src/compiler/binder.ts
@@ -1570,7 +1570,7 @@ namespace ts {
else {
let pattern: Pattern | undefined;
if (node.name.kind === SyntaxKind.StringLiteral) {
- const text = (node.name).text;
+ const { text } = node.name;
if (hasZeroOrOneAsteriskCharacter(text)) {
pattern = tryParsePattern(text);
}
@@ -1589,22 +1589,13 @@ namespace ts {
else {
const state = declareModuleSymbol(node);
if (state !== ModuleInstanceState.NonInstantiated) {
- if (node.symbol.flags & (SymbolFlags.Function | SymbolFlags.Class | SymbolFlags.RegularEnum)) {
- // if module was already merged with some function, class or non-const enum
- // treat is a non-const-enum-only
- node.symbol.constEnumOnlyModule = false;
- }
- else {
- const currentModuleIsConstEnumOnly = state === ModuleInstanceState.ConstEnumOnly;
- if (node.symbol.constEnumOnlyModule === undefined) {
- // non-merged case - use the current state
- node.symbol.constEnumOnlyModule = currentModuleIsConstEnumOnly;
- }
- else {
- // merged case: module is const enum only if all its pieces are non-instantiated or const enum
- node.symbol.constEnumOnlyModule = node.symbol.constEnumOnlyModule && currentModuleIsConstEnumOnly;
- }
- }
+ const { symbol } = node;
+ // if module was already merged with some function, class or non-const enum, treat it as non-const-enum-only
+ symbol.constEnumOnlyModule = (!(symbol.flags & (SymbolFlags.Function | SymbolFlags.Class | SymbolFlags.RegularEnum)))
+ // Current must be `const enum` only
+ && state === ModuleInstanceState.ConstEnumOnly
+ // Can't have been set to 'false' in a previous merged symbol. ('undefined' OK)
+ && symbol.constEnumOnlyModule !== false;
}
}
}
@@ -2205,15 +2196,14 @@ namespace ts {
bindAnonymousDeclaration(node, SymbolFlags.Alias, getDeclarationName(node));
}
else {
- // An export default clause with an expression exports a value
- // We want to exclude both class and function here, this is necessary to issue an error when there are both
- // default export-assignment and default export function and class declaration.
- const flags = node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(node)
+ const flags = node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(node)
// An export default clause with an EntityNameExpression exports all meanings of that identifier
? SymbolFlags.Alias
// An export default clause with any other expression exports a value
: SymbolFlags.Property;
- declareSymbol(container.symbol.exports, container.symbol, node, flags, SymbolFlags.Property | SymbolFlags.AliasExcludes | SymbolFlags.Class | SymbolFlags.Function);
+ // If there is an `export default x;` alias declaration, can't `export default` anything else.
+ // (In contrast, you can still have `export default function f() {}` and `export default interface I {}`.)
+ declareSymbol(container.symbol.exports, container.symbol, node, flags, SymbolFlags.All);
}
}
diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index 8fa4429f7fd..981380c70de 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -2161,7 +2161,6 @@ namespace ts {
return forEachEntry(symbols, symbolFromSymbolTable => {
if (symbolFromSymbolTable.flags & SymbolFlags.Alias
&& symbolFromSymbolTable.escapedName !== "export="
- && !getDeclarationOfKind(symbolFromSymbolTable, SyntaxKind.ExportSpecifier)
&& !(isUMDExportSymbol(symbolFromSymbolTable) && enclosingDeclaration && isExternalModule(getSourceFileOfNode(enclosingDeclaration)))
// If `!useOnlyExternalAliasing`, we can use any type of alias to get the name
&& (!useOnlyExternalAliasing || some(symbolFromSymbolTable.declarations, isExternalModuleImportEqualsDeclaration))) {
@@ -7310,6 +7309,9 @@ namespace ts {
property.type = typeParameter;
properties.push(property);
}
+ const lengthSymbol = createSymbol(SymbolFlags.Property, "length" as __String);
+ lengthSymbol.type = getLiteralType(arity);
+ properties.push(lengthSymbol);
const type = createObjectType(ObjectFlags.Tuple | ObjectFlags.Reference);
type.typeParameters = typeParameters;
type.outerTypeParameters = undefined;
@@ -8905,7 +8907,9 @@ namespace ts {
if (target.flags & TypeFlags.StringOrNumberLiteral && target.flags & TypeFlags.FreshLiteral) {
target = (target).regularType;
}
- if (source === target || relation !== identityRelation && isSimpleTypeRelatedTo(source, target, relation)) {
+ if (source === target ||
+ relation === comparableRelation && !(target.flags & TypeFlags.Never) && isSimpleTypeRelatedTo(target, source, relation) ||
+ relation !== identityRelation && isSimpleTypeRelatedTo(source, target, relation)) {
return true;
}
if (source.flags & TypeFlags.Object && target.flags & TypeFlags.Object) {
@@ -9048,7 +9052,8 @@ namespace ts {
return isIdenticalTo(source, target);
}
- if (isSimpleTypeRelatedTo(source, target, relation, reportErrors ? reportError : undefined)) return Ternary.True;
+ if (relation === comparableRelation && !(target.flags & TypeFlags.Never) && isSimpleTypeRelatedTo(target, source, relation) ||
+ isSimpleTypeRelatedTo(source, target, relation, reportErrors ? reportError : undefined)) return Ternary.True;
if (isObjectLiteralType(source) && source.flags & TypeFlags.FreshLiteral) {
if (hasExcessProperties(source, target, reportErrors)) {
@@ -10896,22 +10901,25 @@ namespace ts {
// it as an inference candidate. Hopefully, a better candidate will come along that does
// not contain anyFunctionType when we come back to this argument for its second round
// of inference. Also, we exclude inferences for silentNeverType (which is used as a wildcard
- // when constructing types from type parameters that had no inference candidates) and
- // implicitNeverType (which is used as the element type for empty array literals).
- if (source.flags & TypeFlags.ContainsAnyFunctionType || source === silentNeverType || source === implicitNeverType) {
+ // when constructing types from type parameters that had no inference candidates).
+ if (source.flags & TypeFlags.ContainsAnyFunctionType || source === silentNeverType) {
return;
}
const inference = getInferenceInfoForType(target);
if (inference) {
if (!inference.isFixed) {
- if (!inference.candidates || priority < inference.priority) {
+ // We give lowest priority to inferences of implicitNeverType (which is used as the
+ // element type for empty array literals). Thus, inferences from empty array literals
+ // only matter when no other inferences are made.
+ const p = priority | (source === implicitNeverType ? InferencePriority.NeverType : 0);
+ if (!inference.candidates || p < inference.priority) {
inference.candidates = [source];
- inference.priority = priority;
+ inference.priority = p;
}
- else if (priority === inference.priority) {
+ else if (p === inference.priority) {
inference.candidates.push(source);
}
- if (!(priority & InferencePriority.ReturnType) && target.flags & TypeFlags.TypeParameter && !isTypeParameterAtTopLevel(originalTarget, target)) {
+ if (!(p & InferencePriority.ReturnType) && target.flags & TypeFlags.TypeParameter && !isTypeParameterAtTopLevel(originalTarget, target)) {
inference.topLevel = false;
}
}
@@ -15159,12 +15167,11 @@ namespace ts {
if (flags & ModifierFlags.Static) {
return true;
}
- // An instance property must be accessed through an instance of the enclosing class
- if (type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType) {
+ if (type.flags & TypeFlags.TypeParameter) {
// get the original type -- represented as the type constraint of the 'this' type
- type = getConstraintOfTypeParameter(type);
+ type = (type as TypeParameter).isThisType ? getConstraintOfTypeParameter(type) : getBaseConstraintOfType(type);
}
- if (!(getObjectFlags(getTargetType(type)) & ObjectFlags.ClassOrInterface && hasBaseType(type, enclosingClass))) {
+ if (!type || !hasBaseType(type, enclosingClass)) {
error(errorNode, Diagnostics.Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1, symbolToString(prop), typeToString(enclosingClass));
return false;
}
@@ -15221,7 +15228,7 @@ namespace ts {
if (indexInfo.isReadonly && (isAssignmentTarget(node) || isDeleteTarget(node))) {
error(node, Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(apparentType));
}
- return indexInfo.type;
+ return getFlowTypeOfPropertyAccess(node, /*prop*/ undefined, indexInfo.type, getAssignmentTargetKind(node));
}
if (right.escapedText && !checkAndReportErrorForExtendingInterface(node)) {
reportNonexistentProperty(right, type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType ? apparentType : type);
@@ -15246,16 +15253,21 @@ namespace ts {
return unknownType;
}
}
+ return getFlowTypeOfPropertyAccess(node, prop, propType, assignmentKind);
+ }
- // Only compute control flow type if this is a property access expression that isn't an
- // assignment target, and the referenced property was declared as a variable, property,
- // accessor, or optional method.
- if (node.kind !== SyntaxKind.PropertyAccessExpression || assignmentKind === AssignmentKind.Definite ||
- !(prop.flags & (SymbolFlags.Variable | SymbolFlags.Property | SymbolFlags.Accessor)) &&
- !(prop.flags & SymbolFlags.Method && propType.flags & TypeFlags.Union)) {
- return propType;
+ /**
+ * Only compute control flow type if this is a property access expression that isn't an
+ * assignment target, and the referenced property was declared as a variable, property,
+ * accessor, or optional method.
+ */
+ function getFlowTypeOfPropertyAccess(node: PropertyAccessExpression | QualifiedName, prop: Symbol | undefined, type: Type, assignmentKind: AssignmentKind) {
+ if (node.kind !== SyntaxKind.PropertyAccessExpression ||
+ assignmentKind === AssignmentKind.Definite ||
+ prop && !(prop.flags & (SymbolFlags.Variable | SymbolFlags.Property | SymbolFlags.Accessor)) && !(prop.flags & SymbolFlags.Method && type.flags & TypeFlags.Union)) {
+ return type;
}
- const flowType = getFlowTypeOfReference(node, propType);
+ const flowType = getFlowTypeOfReference(node, type);
return assignmentKind ? getBaseTypeOfLiteralType(flowType) : flowType;
}
@@ -16726,7 +16738,7 @@ namespace ts {
// only the class declaration node will have the Abstract flag set.
const valueDecl = expressionType.symbol && getClassLikeDeclarationOfSymbol(expressionType.symbol);
if (valueDecl && hasModifier(valueDecl, ModifierFlags.Abstract)) {
- error(node, Diagnostics.Cannot_create_an_instance_of_the_abstract_class_0, declarationNameToString(getNameOfDeclaration(valueDecl)));
+ error(node, Diagnostics.Cannot_create_an_instance_of_an_abstract_class);
return resolveErrorCall(node);
}
@@ -20256,6 +20268,10 @@ namespace ts {
case SyntaxKind.Parameter:
markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(node));
+ const containingSignature = (node as ParameterDeclaration).parent;
+ for (const parameter of containingSignature.parameters) {
+ markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter));
+ }
break;
}
}
@@ -22402,7 +22418,7 @@ namespace ts {
const declaration = memberSymbol.valueDeclaration;
if (declaration !== member) {
if (isBlockScopedNameDeclaredBeforeUse(declaration, member)) {
- return getNodeLinks(declaration).enumMemberValue;
+ return getEnumMemberValue(declaration as EnumMember);
}
error(expr, Diagnostics.A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums);
return 0;
diff --git a/src/compiler/comments.ts b/src/compiler/comments.ts
index 025a4f36d26..1fec1e9562f 100644
--- a/src/compiler/comments.ts
+++ b/src/compiler/comments.ts
@@ -260,7 +260,7 @@ namespace ts {
}
}
- function emitLeadingComment(commentPos: number, commentEnd: number, _kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) {
+ function emitLeadingComment(commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) {
if (!hasWrittenComment) {
emitNewLineBeforeLeadingCommentOfPosition(currentLineMap, writer, rangePos, commentPos);
hasWrittenComment = true;
@@ -274,7 +274,7 @@ namespace ts {
if (hasTrailingNewLine) {
writer.writeLine();
}
- else {
+ else if (kind === SyntaxKind.MultiLineCommentTrivia) {
writer.write(" ");
}
}
diff --git a/src/compiler/core.ts b/src/compiler/core.ts
index 64d6455e67a..6616378dd41 100644
--- a/src/compiler/core.ts
+++ b/src/compiler/core.ts
@@ -68,13 +68,13 @@ namespace ts {
}
// The global Map object. This may not be available, so we must test for it.
- declare const Map: { new(): Map } | undefined;
+ declare const Map: { new (): Map } | undefined;
// Internet Explorer's Map doesn't support iteration, so don't use it.
// tslint:disable-next-line no-in-operator variable-name
const MapCtr = typeof Map !== "undefined" && "entries" in Map.prototype ? Map : shimMap();
// Keep the class inside a function so it doesn't get compiled if it's not used.
- function shimMap(): { new(): Map } {
+ function shimMap(): { new (): Map } {
class MapIterator {
private data: MapLike;
@@ -97,7 +97,7 @@ namespace ts {
}
}
- return class implements Map {
+ return class implements Map {
private data = createDictionaryObject();
public size = 0;
@@ -2635,6 +2635,17 @@ namespace ts {
return (removeFileExtension(path) + newExtension);
}
+ /**
+ * Takes a string like "jquery-min.4.2.3" and returns "jquery"
+ */
+ export function removeMinAndVersionNumbers(fileName: string) {
+ // Match a "." or "-" followed by a version number or 'min' at the end of the name
+ const trailingMinOrVersion = /[.-]((min)|(\d+(\.\d+)*))$/;
+
+ // The "min" or version may both be present, in either order, so try applying the above twice.
+ return fileName.replace(trailingMinOrVersion, "").replace(trailingMinOrVersion, "");
+ }
+
export interface ObjectAllocator {
getNodeConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Node;
getTokenConstructor(): new (kind: TKind, pos?: number, end?: number) => Token;
@@ -2835,7 +2846,7 @@ namespace ts {
return findBestPatternMatch(patterns, _ => _, candidate);
}
- export function patternText({prefix, suffix}: Pattern): string {
+ export function patternText({ prefix, suffix }: Pattern): string {
return `${prefix}*${suffix}`;
}
@@ -2865,7 +2876,7 @@ namespace ts {
return matchedValue;
}
- function isPatternMatch({prefix, suffix}: Pattern, candidate: string) {
+ function isPatternMatch({ prefix, suffix }: Pattern, candidate: string) {
return candidate.length >= prefix.length + suffix.length &&
startsWith(candidate, prefix) &&
endsWith(candidate, suffix);
diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts
index 48b97b048e9..3276e68b2ac 100644
--- a/src/compiler/declarationEmitter.ts
+++ b/src/compiler/declarationEmitter.ts
@@ -1429,45 +1429,40 @@ namespace ts {
function getAccessorDeclarationTypeVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic {
let diagnosticMessage: DiagnosticMessage;
if (accessorWithTypeAnnotation.kind === SyntaxKind.SetAccessor) {
- // Setters have to have type named and cannot infer it so, the type should always be named
- if (hasModifier(accessorWithTypeAnnotation.parent, ModifierFlags.Static)) {
+ // Getters can infer the return type from the returned expression, but setters cannot, so the
+ // "_from_external_module_1_but_cannot_be_named" case cannot occur.
+ if (hasModifier(accessorWithTypeAnnotation, ModifierFlags.Static)) {
diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
- Diagnostics.Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
- Diagnostics.Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_private_name_1;
+ Diagnostics.Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
+ Diagnostics.Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_private_name_1;
}
else {
diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
- Diagnostics.Parameter_0_of_public_property_setter_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
- Diagnostics.Parameter_0_of_public_property_setter_from_exported_class_has_or_is_using_private_name_1;
+ Diagnostics.Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
+ Diagnostics.Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_private_name_1;
}
- return {
- diagnosticMessage,
- errorNode: accessorWithTypeAnnotation.parameters[0],
- // TODO(jfreeman): Investigate why we are passing node.name instead of node.parameters[0].name
- typeName: accessorWithTypeAnnotation.name
- };
}
else {
if (hasModifier(accessorWithTypeAnnotation, ModifierFlags.Static)) {
diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
- Diagnostics.Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named :
- Diagnostics.Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_name_0_from_private_module_1 :
- Diagnostics.Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_private_name_0;
+ Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
+ Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
+ Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_private_name_1;
}
else {
diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
- Diagnostics.Return_type_of_public_property_getter_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named :
- Diagnostics.Return_type_of_public_property_getter_from_exported_class_has_or_is_using_name_0_from_private_module_1 :
- Diagnostics.Return_type_of_public_property_getter_from_exported_class_has_or_is_using_private_name_0;
+ Diagnostics.Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
+ Diagnostics.Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
+ Diagnostics.Return_type_of_public_getter_0_from_exported_class_has_or_is_using_private_name_1;
}
- return {
- diagnosticMessage,
- errorNode: accessorWithTypeAnnotation.name,
- typeName: undefined
- };
}
+ return {
+ diagnosticMessage,
+ errorNode: accessorWithTypeAnnotation.name,
+ typeName: accessorWithTypeAnnotation.name
+ };
}
}
diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json
index 60e3d6c4c4f..964264ff6e8 100644
--- a/src/compiler/diagnosticMessages.json
+++ b/src/compiler/diagnosticMessages.json
@@ -1716,7 +1716,7 @@
"category": "Error",
"code": 2510
},
- "Cannot create an instance of the abstract class '{0}'.": {
+ "Cannot create an instance of an abstract class.": {
"category": "Error",
"code": 2511
},
@@ -2321,43 +2321,43 @@
"category": "Error",
"code": 4033
},
- "Parameter '{0}' of public static property setter from exported class has or is using name '{1}' from private module '{2}'.": {
+ "Parameter type of public static setter '{0}' from exported class has or is using name '{1}' from private module '{2}'.": {
"category": "Error",
"code": 4034
},
- "Parameter '{0}' of public static property setter from exported class has or is using private name '{1}'.": {
+ "Parameter type of public static setter '{0}' from exported class has or is using private name '{1}'.": {
"category": "Error",
"code": 4035
},
- "Parameter '{0}' of public property setter from exported class has or is using name '{1}' from private module '{2}'.": {
+ "Parameter type of public setter '{0}' from exported class has or is using name '{1}' from private module '{2}'.": {
"category": "Error",
"code": 4036
},
- "Parameter '{0}' of public property setter from exported class has or is using private name '{1}'.": {
+ "Parameter type of public setter '{0}' from exported class has or is using private name '{1}'.": {
"category": "Error",
"code": 4037
},
- "Return type of public static property getter from exported class has or is using name '{0}' from external module {1} but cannot be named.": {
+ "Return type of public static getter '{0}' from exported class has or is using name '{1}' from external module {2} but cannot be named.": {
"category": "Error",
"code": 4038
},
- "Return type of public static property getter from exported class has or is using name '{0}' from private module '{1}'.": {
+ "Return type of public static getter '{0}' from exported class has or is using name '{1}' from private module '{2}'.": {
"category": "Error",
"code": 4039
},
- "Return type of public static property getter from exported class has or is using private name '{0}'.": {
+ "Return type of public static getter '{0}' from exported class has or is using private name '{1}'.": {
"category": "Error",
"code": 4040
},
- "Return type of public property getter from exported class has or is using name '{0}' from external module {1} but cannot be named.": {
+ "Return type of public getter '{0}' from exported class has or is using name '{1}' from external module {2} but cannot be named.": {
"category": "Error",
"code": 4041
},
- "Return type of public property getter from exported class has or is using name '{0}' from private module '{1}'.": {
+ "Return type of public getter '{0}' from exported class has or is using name '{1}' from private module '{2}'.": {
"category": "Error",
"code": 4042
},
- "Return type of public property getter from exported class has or is using private name '{0}'.": {
+ "Return type of public getter '{0}' from exported class has or is using private name '{1}'.": {
"category": "Error",
"code": 4043
},
diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts
index 6a56b6da049..e8dfcbc1e94 100644
--- a/src/compiler/factory.ts
+++ b/src/compiler/factory.ts
@@ -4319,7 +4319,7 @@ namespace ts {
const namespaceDeclaration = getNamespaceDeclarationNode(node);
if (namespaceDeclaration && !isDefaultImport(node)) {
const name = namespaceDeclaration.name;
- return isGeneratedIdentifier(name) ? name : createIdentifier(getSourceTextOfNodeFromSourceFile(sourceFile, namespaceDeclaration.name));
+ return isGeneratedIdentifier(name) ? name : createIdentifier(getSourceTextOfNodeFromSourceFile(sourceFile, name) || idText(name));
}
if (node.kind === SyntaxKind.ImportDeclaration && (node).importClause) {
return getGeneratedNameForNode(node);
diff --git a/src/compiler/performance.ts b/src/compiler/performance.ts
index 225b34de9cf..104148ed4ab 100644
--- a/src/compiler/performance.ts
+++ b/src/compiler/performance.ts
@@ -10,7 +10,8 @@ namespace ts {
namespace ts.performance {
declare const onProfilerEvent: { (markName: string): void; profiler: boolean; };
- const profilerEvent: (markName: string) => void = typeof onProfilerEvent === "function" && onProfilerEvent.profiler === true ? onProfilerEvent : noop;
+ // NOTE: cannot use ts.noop as core.ts loads after this
+ const profilerEvent: (markName: string) => void = typeof onProfilerEvent === "function" && onProfilerEvent.profiler === true ? onProfilerEvent : () => { /*empty*/ };
let enabled = false;
let profilerStart = 0;
diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts
index fd8c54a18cc..9fddece11d0 100644
--- a/src/compiler/scanner.ts
+++ b/src/compiler/scanner.ts
@@ -294,7 +294,7 @@ namespace ts {
}
/* @internal */
- export function stringToToken(s: string): SyntaxKind {
+ export function stringToToken(s: string): SyntaxKind | undefined {
return textToToken.get(s);
}
diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts
index f60e50ea365..0c8e2cda0f5 100644
--- a/src/compiler/transformers/module/module.ts
+++ b/src/compiler/transformers/module/module.ts
@@ -57,7 +57,7 @@ namespace ts {
* @param node The SourceFile node.
*/
function transformSourceFile(node: SourceFile) {
- if (node.isDeclarationFile || !(isExternalModule(node) || compilerOptions.isolatedModules || node.transformFlags & TransformFlags.ContainsDynamicImport)) {
+ if (node.isDeclarationFile || !(isEffectiveExternalModule(node, compilerOptions) || node.transformFlags & TransformFlags.ContainsDynamicImport)) {
return node;
}
diff --git a/src/compiler/types.ts b/src/compiler/types.ts
index 1874821727c..3141e3f22d9 100644
--- a/src/compiler/types.ts
+++ b/src/compiler/types.ts
@@ -214,7 +214,7 @@ namespace ts {
UndefinedKeyword,
FromKeyword,
GlobalKeyword,
- OfKeyword, // LastKeyword and LastToken
+ OfKeyword, // LastKeyword and LastToken and LastContextualKeyword
// Parse tree nodes
@@ -431,7 +431,9 @@ namespace ts {
FirstJSDocNode = JSDocTypeExpression,
LastJSDocNode = JSDocPropertyTag,
FirstJSDocTagNode = JSDocTag,
- LastJSDocTagNode = JSDocPropertyTag
+ LastJSDocTagNode = JSDocPropertyTag,
+ /* @internal */ FirstContextualKeyword = AbstractKeyword,
+ /* @internal */ LastContextualKeyword = OfKeyword,
}
export const enum NodeFlags {
@@ -3021,6 +3023,10 @@ namespace ts {
Optional = 1 << 24, // Optional property
Transient = 1 << 25, // Transient symbol (created during type check)
+ /* @internal */
+ All = FunctionScopedVariable | BlockScopedVariable | Property | EnumMember | Function | Class | Interface | ConstEnum | RegularEnum | ValueModule | NamespaceModule | TypeLiteral
+ | ObjectLiteral | Method | Constructor | GetAccessor | SetAccessor | Signature | TypeParameter | TypeAlias | ExportValue | Alias | Prototype | ExportStar | Optional | Transient,
+
Enum = RegularEnum | ConstEnum,
Variable = FunctionScopedVariable | BlockScopedVariable,
Value = Variable | Property | EnumMember | Function | Class | Enum | ValueModule | Method | GetAccessor | SetAccessor,
@@ -3607,6 +3613,7 @@ namespace ts {
NakedTypeVariable = 1 << 1, // Naked type variable in union or intersection type
MappedType = 1 << 2, // Reverse inference for mapped type
ReturnType = 1 << 3, // Inference made from return type of generic function
+ NeverType = 1 << 4, // Inference made from the never type
}
export interface InferenceInfo {
diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts
index 41a5512cb2a..e67635cba04 100644
--- a/src/compiler/utilities.ts
+++ b/src/compiler/utilities.ts
@@ -461,7 +461,7 @@ namespace ts {
}
export function isEffectiveExternalModule(node: SourceFile, compilerOptions: CompilerOptions) {
- return isExternalModule(node) || compilerOptions.isolatedModules;
+ return isExternalModule(node) || compilerOptions.isolatedModules || ((getEmitModuleKind(compilerOptions) === ModuleKind.CommonJS) && !!node.commonJsModuleIndicator);
}
/* @internal */
@@ -1905,6 +1905,14 @@ namespace ts {
return SyntaxKind.FirstKeyword <= token && token <= SyntaxKind.LastKeyword;
}
+ export function isContextualKeyword(token: SyntaxKind): boolean {
+ return SyntaxKind.FirstContextualKeyword <= token && token <= SyntaxKind.LastContextualKeyword;
+ }
+
+ export function isNonContextualKeyword(token: SyntaxKind): boolean {
+ return isKeyword(token) && !isContextualKeyword(token);
+ }
+
export function isTrivia(token: SyntaxKind) {
return SyntaxKind.FirstTriviaToken <= token && token <= SyntaxKind.LastTriviaToken;
}
diff --git a/src/harness/externalCompileRunner.ts b/src/harness/externalCompileRunner.ts
new file mode 100644
index 00000000000..33803752f94
--- /dev/null
+++ b/src/harness/externalCompileRunner.ts
@@ -0,0 +1,142 @@
+///
+///
+const fs = require("fs");
+const path = require("path");
+
+interface ExecResult {
+ stdout: Buffer;
+ stderr: Buffer;
+ status: number;
+}
+
+abstract class ExternalCompileRunnerBase extends RunnerBase {
+ abstract testDir: string;
+ abstract report(result: ExecResult, cwd: string): string;
+ enumerateTestFiles() {
+ return Harness.IO.getDirectories(this.testDir);
+ }
+ /** Setup the runner's tests so that they are ready to be executed by the harness
+ * The first test should be a describe/it block that sets up the harness's compiler instance appropriately
+ */
+ initializeTests(): void {
+ // Read in and evaluate the test list
+ const testList = this.tests && this.tests.length ? this.tests : this.enumerateTestFiles();
+
+ describe(`${this.kind()} code samples`, () => {
+ for (const test of testList) {
+ this.runTest(test);
+ }
+ });
+ }
+ private runTest(directoryName: string) {
+ describe(directoryName, () => {
+ const cp = require("child_process");
+
+ it("should build successfully", () => {
+ const cwd = path.join(__dirname, "../../", this.testDir, directoryName);
+ const timeout = 600000; // 600s = 10 minutes
+ if (fs.existsSync(path.join(cwd, "package.json"))) {
+ if (fs.existsSync(path.join(cwd, "package-lock.json"))) {
+ fs.unlinkSync(path.join(cwd, "package-lock.json"));
+ }
+ const stdio = isWorker ? "pipe" : "inherit";
+ const install = cp.spawnSync(`npm`, ["i"], { cwd, timeout, shell: true, stdio });
+ if (install.status !== 0) throw new Error(`NPM Install for ${directoryName} failed!`);
+ }
+ Harness.Baseline.runBaseline(`${this.kind()}/${directoryName}.log`, () => {
+ return this.report(cp.spawnSync(`node`, [path.join(__dirname, "tsc.js")], { cwd, timeout, shell: true }), cwd);
+ });
+ });
+ });
+ }
+}
+
+class UserCodeRunner extends ExternalCompileRunnerBase {
+ readonly testDir = "tests/cases/user/";
+ kind(): TestRunnerKind {
+ return "user";
+ }
+ report(result: ExecResult) {
+ // tslint:disable-next-line:no-null-keyword
+ return result.status === 0 && !result.stdout.length && !result.stderr.length ? null : `Exit Code: ${result.status}
+Standard output:
+${result.stdout.toString().replace(/\r\n/g, "\n")}
+
+
+Standard error:
+${result.stderr.toString().replace(/\r\n/g, "\n")}`;
+ }
+}
+
+class DefinitelyTypedRunner extends ExternalCompileRunnerBase {
+ readonly testDir = "../DefinitelyTyped/types/";
+ workingDirectory = this.testDir;
+ kind(): TestRunnerKind {
+ return "dt";
+ }
+ report(result: ExecResult, cwd: string) {
+ const stdout = removeExpectedErrors(result.stdout.toString(), cwd);
+ const stderr = result.stderr.toString();
+ // tslint:disable-next-line:no-null-keyword
+ return !stdout.length && !stderr.length ? null : `Exit Code: ${result.status}
+Standard output:
+${stdout.replace(/\r\n/g, "\n")}
+
+
+Standard error:
+${stderr.replace(/\r\n/g, "\n")}`;
+ }
+}
+
+function removeExpectedErrors(errors: string, cwd: string): string {
+ return ts.flatten(splitBy(errors.split("\n"), s => /^\S+/.test(s)).filter(isUnexpectedError(cwd))).join("\n");
+}
+/**
+ * Returns true if the line that caused the error contains '$ExpectError',
+ * or if the line before that one contains '$ExpectError'.
+ * '$ExpectError' is a marker used in Definitely Typed tests,
+ * meaning that the error should not contribute toward our error baslines.
+ */
+function isUnexpectedError(cwd: string) {
+ return (error: string[]) => {
+ ts.Debug.assertGreaterThanOrEqual(error.length, 1);
+ const match = error[0].match(/(.+\.ts)\((\d+),\d+\): error TS/);
+ if (!match) {
+ return true;
+ }
+ const [, errorFile, lineNumberString] = match;
+ const lines = fs.readFileSync(path.join(cwd, errorFile), { encoding: "utf8" }).split("\n");
+ const lineNumber = parseInt(lineNumberString);
+ ts.Debug.assertGreaterThanOrEqual(lineNumber, 0);
+ ts.Debug.assertLessThan(lineNumber, lines.length);
+ const previousLine = lineNumber - 1 > 0 ? lines[lineNumber - 1] : "";
+ return !ts.stringContains(lines[lineNumber], "$ExpectError") && !ts.stringContains(previousLine, "$ExpectError");
+ };
+}
+/**
+ * Split an array into multiple arrays whenever `isStart` returns true.
+ * @example
+ * splitBy([1,2,3,4,5,6], isOdd)
+ * ==> [[1, 2], [3, 4], [5, 6]]
+ * where
+ * const isOdd = n => !!(n % 2)
+ */
+function splitBy(xs: T[], isStart: (x: T) => boolean): T[][] {
+ const result = [];
+ let group: T[] = [];
+ for (const x of xs) {
+ if (isStart(x)) {
+ if (group.length) {
+ result.push(group);
+ }
+ group = [x];
+ }
+ else {
+ group.push(x);
+ }
+ }
+ if (group.length) {
+ result.push(group);
+ }
+ return result;
+}
diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts
index c9aa1c6403d..2687a660ca8 100644
--- a/src/harness/fourslash.ts
+++ b/src/harness/fourslash.ts
@@ -3102,7 +3102,7 @@ Actual: ${stringify(fullActual)}`);
}
}
- const itemsString = items.map(item => stringify({ name: item.name, kind: item.kind })).join(",\n");
+ const itemsString = items.map(item => stringify({ name: item.name, source: item.source, kind: item.kind })).join(",\n");
this.raiseError(`Expected "${stringify({ entryId, text, documentation, kind })}" to be in list [${itemsString}]`);
}
diff --git a/src/harness/harness.ts b/src/harness/harness.ts
index 823b8a34cf2..834bbdab43c 100644
--- a/src/harness/harness.ts
+++ b/src/harness/harness.ts
@@ -2077,8 +2077,8 @@ namespace Harness {
filePath.indexOf("/.ts/") === 0;
}
- export function getDefaultLibraryFile(io: Harness.IO): Harness.Compiler.TestFile {
- const libFile = Harness.userSpecifiedRoot + Harness.libFolder + Harness.Compiler.defaultLibFileName;
+ export function getDefaultLibraryFile(filePath: string, io: Harness.IO): Harness.Compiler.TestFile {
+ const libFile = Harness.userSpecifiedRoot + Harness.libFolder + ts.getBaseFileName(ts.normalizeSlashes(filePath));
return { unitName: libFile, content: io.readFile(libFile) };
}
diff --git a/src/harness/parallel/host.ts b/src/harness/parallel/host.ts
index f37a3b1099e..e278d267e1f 100644
--- a/src/harness/parallel/host.ts
+++ b/src/harness/parallel/host.ts
@@ -77,18 +77,18 @@ namespace Harness.Parallel.Host {
console.log("Discovering runner-based tests...");
const discoverStart = +(new Date());
const { statSync }: { statSync(path: string): { size: number }; } = require("fs");
+ const path: { join: (...args: string[]) => string } = require("path");
for (const runner of runners) {
- const files = runner.enumerateTestFiles();
- for (const file of files) {
+ for (const file of runner.enumerateTestFiles()) {
let size: number;
if (!perfData) {
try {
- size = statSync(file).size;
+ size = statSync(path.join(runner.workingDirectory, file)).size;
}
catch {
// May be a directory
try {
- size = Harness.IO.listFiles(file, /.*/g, { recursive: true }).reduce((acc, elem) => acc + statSync(elem).size, 0);
+ size = Harness.IO.listFiles(path.join(runner.workingDirectory, file), /.*/g, { recursive: true }).reduce((acc, elem) => acc + statSync(elem).size, 0);
}
catch {
// Unknown test kind, just return 0 and let the historical analysis take over after one run
diff --git a/src/harness/runner.ts b/src/harness/runner.ts
index eb0ed4e614b..44ebd4bc519 100644
--- a/src/harness/runner.ts
+++ b/src/harness/runner.ts
@@ -18,7 +18,7 @@
///
///
///
-///
+///
///
///
@@ -62,6 +62,8 @@ function createRunner(kind: TestRunnerKind): RunnerBase {
return new Test262BaselineRunner();
case "user":
return new UserCodeRunner();
+ case "dt":
+ return new DefinitelyTypedRunner();
}
ts.Debug.fail(`Unknown runner kind ${kind}`);
}
@@ -179,6 +181,9 @@ function handleTestConfig() {
case "user":
runners.push(new UserCodeRunner());
break;
+ case "dt":
+ runners.push(new DefinitelyTypedRunner());
+ break;
}
}
}
diff --git a/src/harness/runnerbase.ts b/src/harness/runnerbase.ts
index 14be5e0682a..80532d30b6f 100644
--- a/src/harness/runnerbase.ts
+++ b/src/harness/runnerbase.ts
@@ -1,7 +1,7 @@
///
-type TestRunnerKind = CompilerTestKind | FourslashTestKind | "project" | "rwc" | "test262" | "user";
+type TestRunnerKind = CompilerTestKind | FourslashTestKind | "project" | "rwc" | "test262" | "user" | "dt";
type CompilerTestKind = "conformance" | "compiler";
type FourslashTestKind = "fourslash" | "fourslash-shims" | "fourslash-shims-pp" | "fourslash-server";
@@ -22,6 +22,9 @@ abstract class RunnerBase {
abstract enumerateTestFiles(): string[];
+ /** The working directory where tests are found. Needed for batch testing where the input path will differ from the output path inside baselines */
+ public workingDirectory = "";
+
/** Setup the runner's tests so that they are ready to be executed by the harness
* The first test should be a describe/it block that sets up the harness's compiler instance appropriately
*/
diff --git a/src/harness/rwcRunner.ts b/src/harness/rwcRunner.ts
index 86b4419971d..6b4f31fdd52 100644
--- a/src/harness/rwcRunner.ts
+++ b/src/harness/rwcRunner.ts
@@ -131,13 +131,14 @@ namespace RWC {
}
else {
// set the flag to put default library to the beginning of the list
- inputFiles.unshift(Harness.getDefaultLibraryFile(oldIO));
+ inputFiles.unshift(Harness.getDefaultLibraryFile(fileRead.path, oldIO));
}
}
}
}
// do not use lib since we already read it in above
+ opts.options.lib = undefined;
opts.options.noLib = true;
// Emit the results
diff --git a/src/harness/tsconfig.json b/src/harness/tsconfig.json
index 8e853bbf3b9..ee0032e1218 100644
--- a/src/harness/tsconfig.json
+++ b/src/harness/tsconfig.json
@@ -60,20 +60,11 @@
"../services/jsTyping.ts",
"../services/formatting/formatting.ts",
"../services/formatting/formattingContext.ts",
- "../services/formatting/formattingRequestKind.ts",
"../services/formatting/formattingScanner.ts",
- "../services/formatting/references.ts",
"../services/formatting/rule.ts",
- "../services/formatting/ruleAction.ts",
- "../services/formatting/ruleDescriptor.ts",
- "../services/formatting/ruleFlag.ts",
- "../services/formatting/ruleOperation.ts",
- "../services/formatting/ruleOperationContext.ts",
"../services/formatting/rules.ts",
"../services/formatting/rulesMap.ts",
- "../services/formatting/rulesProvider.ts",
"../services/formatting/smartIndenter.ts",
- "../services/formatting/tokenRange.ts",
"../services/codeFixProvider.ts",
"../services/codefixes/fixes.ts",
"../services/codefixes/helpers.ts",
@@ -102,7 +93,7 @@
"projectsRunner.ts",
"loggedIO.ts",
"rwcRunner.ts",
- "userRunner.ts",
+ "externalCompileRunner.ts",
"test262Runner.ts",
"./parallel/shared.ts",
"./parallel/host.ts",
diff --git a/src/harness/unittests/extractTestHelpers.ts b/src/harness/unittests/extractTestHelpers.ts
index ae3f663aa51..a04f443c3c9 100644
--- a/src/harness/unittests/extractTestHelpers.ts
+++ b/src/harness/unittests/extractTestHelpers.ts
@@ -67,33 +67,27 @@ namespace ts {
}
export const newLineCharacter = "\n";
- export const getRuleProvider = memoize(getRuleProviderInternal);
- function getRuleProviderInternal() {
- const options = {
- indentSize: 4,
- tabSize: 4,
- newLineCharacter,
- convertTabsToSpaces: true,
- indentStyle: ts.IndentStyle.Smart,
- insertSpaceAfterConstructor: false,
- insertSpaceAfterCommaDelimiter: true,
- insertSpaceAfterSemicolonInForStatements: true,
- insertSpaceBeforeAndAfterBinaryOperators: true,
- insertSpaceAfterKeywordsInControlFlowStatements: true,
- insertSpaceAfterFunctionKeywordForAnonymousFunctions: false,
- insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false,
- insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false,
- insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: true,
- insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false,
- insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false,
- insertSpaceBeforeFunctionParenthesis: false,
- placeOpenBraceOnNewLineForFunctions: false,
- placeOpenBraceOnNewLineForControlBlocks: false,
- };
- const rulesProvider = new formatting.RulesProvider();
- rulesProvider.ensureUpToDate(options);
- return rulesProvider;
- }
+ export const testFormatOptions: ts.FormatCodeSettings = {
+ indentSize: 4,
+ tabSize: 4,
+ newLineCharacter,
+ convertTabsToSpaces: true,
+ indentStyle: ts.IndentStyle.Smart,
+ insertSpaceAfterConstructor: false,
+ insertSpaceAfterCommaDelimiter: true,
+ insertSpaceAfterSemicolonInForStatements: true,
+ insertSpaceBeforeAndAfterBinaryOperators: true,
+ insertSpaceAfterKeywordsInControlFlowStatements: true,
+ insertSpaceAfterFunctionKeywordForAnonymousFunctions: false,
+ insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false,
+ insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false,
+ insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: true,
+ insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false,
+ insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false,
+ insertSpaceBeforeFunctionParenthesis: false,
+ placeOpenBraceOnNewLineForFunctions: false,
+ placeOpenBraceOnNewLineForControlBlocks: false,
+ };
const notImplementedHost: LanguageServiceHost = {
getCompilationSettings: notImplemented,
@@ -133,7 +127,7 @@ namespace ts {
startPosition: selectionRange.start,
endPosition: selectionRange.end,
host: notImplementedHost,
- rulesProvider: getRuleProvider()
+ formatContext: formatting.getFormatContext(testFormatOptions),
};
const rangeToExtract = refactor.extractSymbol.getRangeToExtract(sourceFile, createTextSpanFromBounds(selectionRange.start, selectionRange.end));
assert.equal(rangeToExtract.errors, undefined, rangeToExtract.errors && "Range error: " + rangeToExtract.errors[0].messageText);
@@ -197,7 +191,7 @@ namespace ts {
startPosition: selectionRange.start,
endPosition: selectionRange.end,
host: notImplementedHost,
- rulesProvider: getRuleProvider()
+ formatContext: formatting.getFormatContext(testFormatOptions),
};
const rangeToExtract = refactor.extractSymbol.getRangeToExtract(sourceFile, createTextSpanFromBounds(selectionRange.start, selectionRange.end));
assert.isUndefined(rangeToExtract.errors, rangeToExtract.errors && "Range error: " + rangeToExtract.errors[0].messageText);
diff --git a/src/harness/unittests/textChanges.ts b/src/harness/unittests/textChanges.ts
index c37e50a2565..ed571b37399 100644
--- a/src/harness/unittests/textChanges.ts
+++ b/src/harness/unittests/textChanges.ts
@@ -23,60 +23,8 @@ namespace ts {
const printerOptions = { newLine: NewLineKind.LineFeed };
const newLineCharacter = getNewLineCharacter(printerOptions);
- const getRuleProviderDefault = memoize(() => {
- const options = {
- indentSize: 4,
- tabSize: 4,
- newLineCharacter,
- convertTabsToSpaces: true,
- indentStyle: ts.IndentStyle.Smart,
- insertSpaceAfterConstructor: false,
- insertSpaceAfterCommaDelimiter: true,
- insertSpaceAfterSemicolonInForStatements: true,
- insertSpaceBeforeAndAfterBinaryOperators: true,
- insertSpaceAfterKeywordsInControlFlowStatements: true,
- insertSpaceAfterFunctionKeywordForAnonymousFunctions: false,
- insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false,
- insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false,
- insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: true,
- insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false,
- insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false,
- insertSpaceBeforeFunctionParenthesis: false,
- placeOpenBraceOnNewLineForFunctions: false,
- placeOpenBraceOnNewLineForControlBlocks: false,
- };
- const rulesProvider = new formatting.RulesProvider();
- rulesProvider.ensureUpToDate(options);
- return rulesProvider;
- });
- const getRuleProviderNewlineBrace = memoize(() => {
- const options = {
- indentSize: 4,
- tabSize: 4,
- newLineCharacter,
- convertTabsToSpaces: true,
- indentStyle: ts.IndentStyle.Smart,
- insertSpaceAfterConstructor: false,
- insertSpaceAfterCommaDelimiter: true,
- insertSpaceAfterSemicolonInForStatements: true,
- insertSpaceBeforeAndAfterBinaryOperators: true,
- insertSpaceAfterKeywordsInControlFlowStatements: true,
- insertSpaceAfterFunctionKeywordForAnonymousFunctions: false,
- insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false,
- insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false,
- insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: true,
- insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false,
- insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false,
- insertSpaceBeforeFunctionParenthesis: false,
- placeOpenBraceOnNewLineForFunctions: true,
- placeOpenBraceOnNewLineForControlBlocks: false,
- };
- const rulesProvider = new formatting.RulesProvider();
- rulesProvider.ensureUpToDate(options);
- return rulesProvider;
- });
- function getRuleProvider(placeOpenBraceOnNewLineForFunctions: boolean) {
- return placeOpenBraceOnNewLineForFunctions ? getRuleProviderNewlineBrace() : getRuleProviderDefault();
+ function getRuleProvider(placeOpenBraceOnNewLineForFunctions: boolean): formatting.FormatContext {
+ return formatting.getFormatContext(placeOpenBraceOnNewLineForFunctions ? { ...testFormatOptions, placeOpenBraceOnNewLineForFunctions: true } : testFormatOptions);
}
// validate that positions that were recovered from the printed text actually match positions that will be created if the same text is parsed.
@@ -122,9 +70,9 @@ namespace ts {
{
const text = `
-namespace M
+namespace M
{
- namespace M2
+ namespace M2
{
function foo() {
// comment 1
@@ -572,7 +520,7 @@ const x = 1;`;
}
{
const text = `
-const x = 1,
+const x = 1,
y = 2;`;
runSingleFileTest("insertNodeInListAfter6", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1)));
@@ -583,7 +531,7 @@ const x = 1,
}
{
const text = `
-const /*x*/ x = 1,
+const /*x*/ x = 1,
/*y*/ y = 2;`;
runSingleFileTest("insertNodeInListAfter8", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1)));
diff --git a/src/harness/unittests/transform.ts b/src/harness/unittests/transform.ts
index 72f7072535c..a39249bb225 100644
--- a/src/harness/unittests/transform.ts
+++ b/src/harness/unittests/transform.ts
@@ -192,6 +192,38 @@ namespace ts {
};
}
});
+
+ // https://github.com/Microsoft/TypeScript/issues/19618
+ testBaseline("transformAddImportStar", () => {
+ return ts.transpileModule("", {
+ transformers: {
+ before: [transformAddImportStar],
+ },
+ compilerOptions: {
+ target: ts.ScriptTarget.ES5,
+ module: ts.ModuleKind.System,
+ newLine: NewLineKind.CarriageReturnLineFeed,
+ }
+ }).outputText;
+
+ function transformAddImportStar(_context: ts.TransformationContext) {
+ return (sourceFile: ts.SourceFile): ts.SourceFile => {
+ return visitNode(sourceFile);
+ };
+ function visitNode(sf: ts.SourceFile) {
+ // produce `import * as i0 from './comp';
+ const importStar = ts.createImportDeclaration(
+ /*decorators*/ undefined,
+ /*modifiers*/ undefined,
+ /*importClause*/ ts.createImportClause(
+ /*name*/ undefined,
+ ts.createNamespaceImport(ts.createIdentifier("i0"))
+ ),
+ /*moduleSpecifier*/ ts.createLiteral("./comp1"));
+ return ts.updateSourceFileNode(sf, [importStar]);
+ }
+ }
+ });
});
}
diff --git a/src/harness/unittests/tscWatchMode.ts b/src/harness/unittests/tscWatchMode.ts
index fc80a6f39ef..4e2d63cec90 100644
--- a/src/harness/unittests/tscWatchMode.ts
+++ b/src/harness/unittests/tscWatchMode.ts
@@ -1616,6 +1616,36 @@ namespace ts.tscWatch {
return files.slice(0, 2);
}
});
+
+ it("Elides const enums correctly in incremental compilation", () => {
+ const currentDirectory = "/user/someone/projects/myproject";
+ const file1: FileOrFolder = {
+ path: `${currentDirectory}/file1.ts`,
+ content: "export const enum E1 { V = 1 }"
+ };
+ const file2: FileOrFolder = {
+ path: `${currentDirectory}/file2.ts`,
+ content: `import { E1 } from "./file1"; export const enum E2 { V = E1.V }`
+ };
+ const file3: FileOrFolder = {
+ path: `${currentDirectory}/file3.ts`,
+ content: `import { E2 } from "./file2"; const v: E2 = E2.V;`
+ };
+ const strictAndEsModule = `"use strict";\nexports.__esModule = true;\n`;
+ verifyEmittedFileContents("\n", [file3, file2, file1], [
+ `${strictAndEsModule}var v = 1 /* V */;\n`,
+ strictAndEsModule,
+ strictAndEsModule
+ ], modifyFiles);
+
+ function modifyFiles(files: FileOrFolderEmit[], emittedFiles: EmittedFile[]) {
+ files[0].content += `function foo2() { return 2; }`;
+ emittedFiles[0].content += `function foo2() { return 2; }\n`;
+ emittedFiles[1].shouldBeWritten = false;
+ emittedFiles[2].shouldBeWritten = false;
+ return [files[0]];
+ }
+ });
});
describe("tsc-watch module resolution caching", () => {
diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts
index ffee2be26be..ea573726eb8 100644
--- a/src/harness/unittests/tsserverProjectSystem.ts
+++ b/src/harness/unittests/tsserverProjectSystem.ts
@@ -1539,6 +1539,42 @@ namespace ts.projectSystem {
}
});
+ it("removes version numbers correctly", () => {
+ const testData: [string, string][] = [
+ ["jquery-max", "jquery-max"],
+ ["jquery.min", "jquery"],
+ ["jquery-min.4.2.3", "jquery"],
+ ["jquery.min.4.2.1", "jquery"],
+ ["minimum", "minimum"],
+ ["min", "min"],
+ ["min.3.2", "min"],
+ ["jquery", "jquery"]
+ ];
+ for (const t of testData) {
+ assert.equal(removeMinAndVersionNumbers(t[0]), t[1], t[0]);
+ }
+ });
+
+ it("ignores files excluded by a legacy safe type list", () => {
+ const file1 = {
+ path: "/a/b/bliss.js",
+ content: "let x = 5"
+ };
+ const file2 = {
+ path: "/a/b/foo.js",
+ content: ""
+ };
+ const host = createServerHost([file1, file2, customTypesMap]);
+ const projectService = createProjectService(host);
+ try {
+ projectService.openExternalProject({ projectFileName: "project", options: {}, rootFiles: toExternalFiles([file1.path, file2.path]), typeAcquisition: { enable: true } });
+ const proj = projectService.externalProjects[0];
+ assert.deepEqual(proj.getFileNames(), [file2.path]);
+ } finally {
+ projectService.resetSafeList();
+ }
+ });
+
it("open file become a part of configured project if it is referenced from root file", () => {
const file1 = {
path: "/a/b/f1.ts",
diff --git a/src/harness/unittests/typingsInstaller.ts b/src/harness/unittests/typingsInstaller.ts
index 2ae9587b78e..e321fb1c99d 100644
--- a/src/harness/unittests/typingsInstaller.ts
+++ b/src/harness/unittests/typingsInstaller.ts
@@ -1057,11 +1057,12 @@ namespace ts.projectSystem {
const host = createServerHost([app, jquery, chroma]);
const logger = trackingLogger();
const result = JsTyping.discoverTypings(host, logger.log, [app.path, jquery.path, chroma.path], getDirectoryPath(app.path), safeList, emptyMap, { enable: true }, emptyArray);
- assert.deepEqual(logger.finish(), [
+ const finish = logger.finish();
+ assert.deepEqual(finish, [
'Inferred typings from file names: ["jquery","chroma-js"]',
"Inferred typings from unresolved imports: []",
'Result: {"cachedTypingPaths":[],"newTypingNames":["jquery","chroma-js"],"filesToWatch":["/a/b/bower_components","/a/b/node_modules"]}',
- ]);
+ ], finish.join("\r\n"));
assert.deepEqual(result.newTypingNames, ["jquery", "chroma-js"]);
});
diff --git a/src/harness/userRunner.ts b/src/harness/userRunner.ts
deleted file mode 100644
index 9be652aebf8..00000000000
--- a/src/harness/userRunner.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-///
-///
-class UserCodeRunner extends RunnerBase {
- private static readonly testDir = "tests/cases/user/";
- public enumerateTestFiles() {
- return Harness.IO.getDirectories(UserCodeRunner.testDir);
- }
-
- public kind(): TestRunnerKind {
- return "user";
- }
-
- /** Setup the runner's tests so that they are ready to be executed by the harness
- * The first test should be a describe/it block that sets up the harness's compiler instance appropriately
- */
- public initializeTests(): void {
- // Read in and evaluate the test list
- const testList = this.tests && this.tests.length ? this.tests : this.enumerateTestFiles();
-
- describe(`${this.kind()} code samples`, () => {
- for (const test of testList) {
- this.runTest(test);
- }
- });
- }
-
- private runTest(directoryName: string) {
- describe(directoryName, () => {
- const cp = require("child_process");
- const path = require("path");
-
- it("should build successfully", () => {
- const cwd = path.join(__dirname, "../../", UserCodeRunner.testDir, directoryName);
- const timeout = 600000; // 10 minutes
- const stdio = isWorker ? "pipe" : "inherit";
- const install = cp.spawnSync(`npm`, ["i"], { cwd, timeout, shell: true, stdio });
- if (install.status !== 0) throw new Error(`NPM Install for ${directoryName} failed!`);
- Harness.Baseline.runBaseline(`${this.kind()}/${directoryName}.log`, () => {
- const result = cp.spawnSync(`node`, ["../../../../built/local/tsc.js"], { cwd, timeout, shell: true });
- return `Exit Code: ${result.status}
-Standard output:
-${result.stdout.toString().replace(/\r\n/g, "\n")}
-
-
-Standard error:
-${result.stderr.toString().replace(/\r\n/g, "\n")}`;
- });
- });
- });
- }
-}
diff --git a/src/lib/es2015.symbol.wellknown.d.ts b/src/lib/es2015.symbol.wellknown.d.ts
index 268570ff232..23d836c6515 100644
--- a/src/lib/es2015.symbol.wellknown.d.ts
+++ b/src/lib/es2015.symbol.wellknown.d.ts
@@ -150,7 +150,7 @@ interface Promise {
}
interface PromiseConstructor {
- readonly [Symbol.species]: Function;
+ readonly [Symbol.species]: PromiseConstructor;
}
interface RegExp {
@@ -202,7 +202,7 @@ interface RegExp {
}
interface RegExpConstructor {
- [Symbol.species](): RegExpConstructor;
+ readonly [Symbol.species]: RegExpConstructor;
}
interface String {
@@ -283,3 +283,16 @@ interface Float32Array {
interface Float64Array {
readonly [Symbol.toStringTag]: "Float64Array";
}
+
+interface ArrayConstructor {
+ readonly [Symbol.species]: ArrayConstructor;
+}
+interface MapConstructor {
+ readonly [Symbol.species]: MapConstructor;
+}
+interface SetConstructor {
+ readonly [Symbol.species]: SetConstructor;
+}
+interface ArrayBufferConstructor {
+ readonly [Symbol.species]: ArrayBufferConstructor;
+}
\ No newline at end of file
diff --git a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl
index c59e9c20060..292a20a49bf 100644
--- a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl
+++ b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl
@@ -1611,12 +1611,9 @@
- -
+
-
-
-
-
-
+
@@ -3726,6 +3723,24 @@
+ -
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
-
@@ -3957,6 +3972,15 @@
+ -
+
+
+
+
+
+
+
+
-
@@ -5202,24 +5226,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
@@ -5247,24 +5253,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
@@ -5283,6 +5271,30 @@
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
-
@@ -5988,6 +6000,24 @@
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
-
@@ -6015,30 +6045,21 @@
- -
+
-
-
-
-
-
+
- -
+
-
-
-
-
-
+
- -
+
-
-
-
-
-
+
@@ -6069,33 +6090,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
diff --git a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl
index 8dab90a1ba2..3bb9642d207 100644
--- a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl
+++ b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl
@@ -1620,12 +1620,9 @@
- -
+
-
-
-
-
-
+
@@ -3735,6 +3732,24 @@
+ -
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
-
@@ -3966,6 +3981,15 @@
+ -
+
+
+
+
+
+
+
+
-
@@ -5211,24 +5235,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
@@ -5256,24 +5262,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
@@ -5292,6 +5280,30 @@
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
-
@@ -5997,6 +6009,24 @@
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
-
@@ -6024,30 +6054,21 @@
- -
+
-
-
-
-
-
+
- -
+
-
-
-
-
-
+
- -
+
-
-
-
-
-
+
@@ -6078,33 +6099,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
diff --git a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl
index c00e5a2a2e7..d362101e51f 100644
--- a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl
+++ b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl
@@ -1605,12 +1605,9 @@
- -
+
-
-
-
-
-
+
@@ -3714,6 +3711,24 @@
+ -
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
-
@@ -3945,6 +3960,15 @@
+ -
+
+
+
+
+
+
+
+
-
@@ -5190,24 +5214,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
@@ -5235,24 +5241,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
@@ -5271,6 +5259,30 @@
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
-
@@ -5970,6 +5982,24 @@
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
-
@@ -5997,30 +6027,21 @@
- -
+
-
-
-
-
-
+
- -
+
-
-
-
-
-
+
- -
+
-
-
-
-
-
+
@@ -6051,33 +6072,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
diff --git a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl
index 2bf61430d60..803d5940ac2 100644
--- a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl
+++ b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl
@@ -1620,12 +1620,9 @@
- -
+
-
-
-
-
-
+
@@ -3735,6 +3732,24 @@
+ -
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
-
@@ -3966,6 +3981,15 @@
+ -
+
+
+
+
+
+
+
+
-
@@ -5211,24 +5235,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
@@ -5256,24 +5262,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
@@ -5292,6 +5280,30 @@
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
-
@@ -5997,6 +6009,24 @@
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
-
@@ -6024,30 +6054,21 @@
- -
+
-
-
-
-
-
+
- -
+
-
-
-
-
-
+
- -
+
-
-
-
-
-
+
@@ -6078,33 +6099,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
diff --git a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl
index 31f3bfdefd5..2e603f114b6 100644
--- a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl
+++ b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl
@@ -1611,12 +1611,9 @@
- -
+
-
-
-
-
-
+
@@ -3726,6 +3723,24 @@
+ -
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
-
@@ -3957,6 +3972,15 @@
+ -
+
+
+
+
+
+
+
+
-
@@ -5202,24 +5226,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
@@ -5247,24 +5253,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
@@ -5283,6 +5271,30 @@
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
-
@@ -5988,6 +6000,24 @@
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
-
@@ -6015,30 +6045,21 @@
- -
+
-
-
-
-
-
+
- -
+
-
-
-
-
-
+
- -
+
-
-
-
-
-
+
@@ -6069,33 +6090,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
diff --git a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl
index b2ae023f5a4..6ea7ba86fc7 100644
--- a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl
+++ b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl
@@ -1611,12 +1611,9 @@
- -
+
-
-
-
-
-
+
@@ -3726,6 +3723,24 @@
+ -
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
-
@@ -3957,6 +3972,15 @@
+ -
+
+
+
+
+
+
+
+
-
@@ -5202,24 +5226,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
@@ -5247,24 +5253,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
@@ -5283,6 +5271,30 @@
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
-
@@ -5988,6 +6000,24 @@
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
-
@@ -6015,30 +6045,21 @@
- -
+
-
-
-
-
-
+
- -
+
-
-
-
-
-
+
- -
+
-
-
-
-
-
+
@@ -6069,33 +6090,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
diff --git a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl
index 2693d7cce27..80c5f4e15d2 100644
--- a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl
+++ b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl
@@ -1611,12 +1611,9 @@
- -
+
-
-
-
-
-
+
@@ -3726,6 +3723,24 @@
+ -
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
-
@@ -3957,6 +3972,15 @@
+ -
+
+
+
+
+
+
+
+
-
@@ -5202,24 +5226,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
@@ -5247,24 +5253,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
@@ -5283,6 +5271,30 @@
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
-
@@ -5988,6 +6000,24 @@
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
-
@@ -6015,30 +6045,21 @@
- -
+
-
-
-
-
-
+
- -
+
-
-
-
-
-
+
- -
+
-
-
-
-
-
+
@@ -6069,33 +6090,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
diff --git a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl
index b9d115872b6..0badf531a75 100644
--- a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl
+++ b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl
@@ -1598,12 +1598,9 @@
- -
+
-
-
-
-
-
+
@@ -3707,6 +3704,24 @@
+ -
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
-
@@ -3938,6 +3953,15 @@
+ -
+
+
+
+
+
+
+
+
-
@@ -5183,24 +5207,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
@@ -5228,24 +5234,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
@@ -5264,6 +5252,30 @@
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
-
@@ -5963,6 +5975,24 @@
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
-
@@ -5990,30 +6020,21 @@
- -
+
-
-
-
-
-
+
- -
+
-
-
-
-
-
+
- -
+
-
-
-
-
-
+
@@ -6044,33 +6065,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
diff --git a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl
index 1e480ff2a08..7677920dd1d 100644
--- a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl
+++ b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl
@@ -1598,12 +1598,9 @@
- -
+
-
-
-
-
-
+
@@ -3707,6 +3704,24 @@
+ -
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
-
@@ -3938,6 +3953,15 @@
+ -
+
+
+
+
+
+
+
+
-
@@ -5183,24 +5207,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
@@ -5228,24 +5234,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
@@ -5264,6 +5252,30 @@
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
-
@@ -5963,6 +5975,24 @@
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
-
@@ -5990,30 +6020,21 @@
- -
+
-
-
-
-
-
+
- -
+
-
-
-
-
-
+
- -
+
-
-
-
-
-
+
@@ -6044,33 +6065,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
diff --git a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl
index 17236daf66b..b71915fbd67 100644
--- a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl
+++ b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl
@@ -1610,12 +1610,9 @@
- -
+
-
-
-
-
-
+
@@ -2240,6 +2237,15 @@
+ -
+
+
+
+
+
+
+
+
-
@@ -2969,6 +2975,15 @@
+ -
+
+
+
+
+
+
+
+
-
@@ -3707,6 +3722,24 @@
+ -
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
-
@@ -3938,6 +3971,15 @@
+ -
+
+
+
+
+
+
+
+
-
@@ -4211,6 +4253,24 @@
+ -
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
-
@@ -5165,24 +5225,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
@@ -5210,24 +5252,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
@@ -5246,6 +5270,30 @@
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
-
@@ -5951,6 +5999,24 @@
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
-
@@ -5978,30 +6044,21 @@
- -
+
-
-
-
-
-
+
- -
+
-
-
-
-
-
+
- -
+
-
-
-
-
-
+
@@ -6032,33 +6089,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
diff --git a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl
index 0eafa4da0b2..6c92a1c0bd1 100644
--- a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl
+++ b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl
@@ -1604,12 +1604,9 @@
- -
+
-
-
-
-
-
+
@@ -3719,6 +3716,24 @@
+ -
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
-
@@ -3950,6 +3965,15 @@
+ -
+
+
+
+
+
+
+
+
-
@@ -5195,24 +5219,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
@@ -5240,24 +5246,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
@@ -5276,6 +5264,30 @@
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
-
@@ -5981,6 +5993,24 @@
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
-
@@ -6008,30 +6038,21 @@
- -
+
-
-
-
-
-
+
- -
+
-
-
-
-
-
+
- -
+
-
-
-
-
-
+
@@ -6062,33 +6083,6 @@
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts
index 2205f65cbe4..726621a540d 100644
--- a/src/server/editorServices.ts
+++ b/src/server/editorServices.ts
@@ -110,7 +110,7 @@ namespace ts.server {
export interface TypesMapFile {
typesMap: SafeList;
- simpleMap: string[];
+ simpleMap: { [libName: string]: string };
}
/**
@@ -380,6 +380,7 @@ namespace ts.server {
private readonly hostConfiguration: HostConfiguration;
private safelist: SafeList = defaultTypeSafeList;
+ private legacySafelist: { [key: string]: string } = {};
private changedFiles: ScriptInfo[];
private pendingProjectUpdates = createMap();
@@ -432,9 +433,12 @@ namespace ts.server {
this.toCanonicalFileName = createGetCanonicalFileName(this.host.useCaseSensitiveFileNames);
this.throttledOperations = new ThrottledOperations(this.host, this.logger);
- if (opts.typesMapLocation) {
+ if (this.typesMapLocation) {
this.loadTypesMap();
}
+ else {
+ this.logger.info("No types map provided; using the default");
+ }
this.typingsInstaller.attach(this);
@@ -524,10 +528,12 @@ namespace ts.server {
}
// raw is now fixed and ready
this.safelist = raw.typesMap;
+ this.legacySafelist = raw.simpleMap;
}
catch (e) {
this.logger.info(`Error loading types map: ${e}`);
this.safelist = defaultTypeSafeList;
+ this.legacySafelist = {};
}
}
@@ -1418,7 +1424,7 @@ namespace ts.server {
}
}
- private createExternalProject(projectFileName: string, files: protocol.ExternalFile[], options: protocol.ExternalProjectCompilerOptions, typeAcquisition: TypeAcquisition) {
+ private createExternalProject(projectFileName: string, files: protocol.ExternalFile[], options: protocol.ExternalProjectCompilerOptions, typeAcquisition: TypeAcquisition, excludedFiles: NormalizedPath[]) {
const compilerOptions = convertCompilerOptions(options);
const project = new ExternalProject(
projectFileName,
@@ -1427,6 +1433,7 @@ namespace ts.server {
compilerOptions,
/*languageServiceEnabled*/ !this.exceededTotalSizeLimitForNonTsFiles(projectFileName, compilerOptions, files, externalFilePropertyReader),
options.compileOnSave === undefined ? true : options.compileOnSave);
+ project.excludedFiles = excludedFiles;
this.addFilesToNonInferredProjectAndUpdateGraph(project, files, externalFilePropertyReader, typeAcquisition);
this.externalProjects.push(project);
@@ -2197,7 +2204,7 @@ namespace ts.server {
const rule = this.safelist[name];
for (const root of normalizedNames) {
if (rule.match.test(root)) {
- this.logger.info(`Excluding files based on rule ${name}`);
+ this.logger.info(`Excluding files based on rule ${name} matching file '${root}'`);
// If the file matches, collect its types packages and exclude rules
if (rule.types) {
@@ -2256,7 +2263,22 @@ namespace ts.server {
excludedFiles.push(normalizedNames[i]);
}
else {
- filesToKeep.push(proj.rootFiles[i]);
+ let exclude = false;
+ if (typeAcquisition && (typeAcquisition.enable || typeAcquisition.enableAutoDiscovery)) {
+ const baseName = getBaseFileName(normalizedNames[i].toLowerCase());
+ if (fileExtensionIs(baseName, "js")) {
+ const inferredTypingName = removeFileExtension(baseName);
+ const cleanedTypingName = removeMinAndVersionNumbers(inferredTypingName);
+ if (this.legacySafelist[cleanedTypingName]) {
+ this.logger.info(`Excluded '${normalizedNames[i]}' because it matched ${cleanedTypingName} from the legacy safelist`);
+ excludedFiles.push(normalizedNames[i]);
+ exclude = true;
+ }
+ }
+ }
+ if (!exclude) {
+ filesToKeep.push(proj.rootFiles[i]);
+ }
}
}
proj.rootFiles = filesToKeep;
@@ -2364,8 +2386,7 @@ namespace ts.server {
else {
// no config files - remove the item from the collection
this.externalProjectToConfiguredProjectMap.delete(proj.projectFileName);
- const newProj = this.createExternalProject(proj.projectFileName, rootFiles, proj.options, proj.typeAcquisition);
- newProj.excludedFiles = excludedFiles;
+ this.createExternalProject(proj.projectFileName, rootFiles, proj.options, proj.typeAcquisition, excludedFiles);
}
if (!suppressRefreshOfInferredProjects) {
this.ensureProjectStructuresUptoDate(/*refreshInferredProjects*/ true);
diff --git a/src/server/protocol.ts b/src/server/protocol.ts
index f44efa0db21..3761049017d 100644
--- a/src/server/protocol.ts
+++ b/src/server/protocol.ts
@@ -586,6 +586,7 @@ namespace ts.server.protocol {
}
export interface ApplyCodeActionCommandRequestArgs extends FileRequestArgs {
+ /** May also be an array of commands. */
command: {};
}
diff --git a/src/server/session.ts b/src/server/session.ts
index 6c97c3c8bd4..f9a145d16fd 100644
--- a/src/server/session.ts
+++ b/src/server/session.ts
@@ -1571,9 +1571,12 @@ namespace ts.server {
private applyCodeActionCommand(commandName: string, requestSeq: number, args: protocol.ApplyCodeActionCommandRequestArgs): void {
const { file, project } = this.getFileAndProject(args);
const output = (success: boolean, message: string) => this.doOutput({}, commandName, requestSeq, success, message);
- const command = args.command as CodeActionCommand; // They should be sending back the command we sent them.
+ const command = args.command as CodeActionCommand | CodeActionCommand[]; // They should be sending back the command we sent them.
+
project.getLanguageService().applyCodeActionCommand(file, command).then(
- ({ successMessage }) => { output(/*success*/ true, successMessage); },
+ result => {
+ output(/*success*/ true, isArray(result) ? result.map(res => res.successMessage).join(`${this.host.newLine}${this.host.newLine}`) : result.successMessage);
+ },
error => { output(/*success*/ false, error); });
}
diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts
index e0e57801cf8..838e19fa35d 100644
--- a/src/services/codefixes/importFixes.ts
+++ b/src/services/codefixes/importFixes.ts
@@ -166,7 +166,7 @@ namespace ts.codefix {
return {
host: context.host,
newLineCharacter: context.newLineCharacter,
- rulesProvider: context.rulesProvider,
+ formatContext: context.formatContext,
sourceFile: context.sourceFile,
checker,
compilerOptions: context.program.getCompilerOptions(),
@@ -699,9 +699,10 @@ namespace ts.codefix {
const defaultExport = checker.tryGetMemberInModuleExports("default", moduleSymbol);
if (defaultExport) {
const localSymbol = getLocalSymbolForExportDefault(defaultExport);
- if (localSymbol && localSymbol.escapedName === symbolName && checkSymbolHasMeaning(localSymbol, currentTokenMeaning)) {
+ if ((localSymbol && localSymbol.escapedName === symbolName || moduleSymbolToValidIdentifier(moduleSymbol, context.compilerOptions.target) === symbolName)
+ && checkSymbolHasMeaning(localSymbol || defaultExport, currentTokenMeaning)) {
// check if this symbol is already used
- const symbolId = getUniqueSymbolId(localSymbol, checker);
+ const symbolId = getUniqueSymbolId(localSymbol || defaultExport, checker);
symbolIdActionMap.addActions(symbolId, getCodeActionForImport(moduleSymbol, { ...context, kind: ImportKind.Default }));
}
}
@@ -731,4 +732,35 @@ namespace ts.codefix {
}
}
}
+
+ export function moduleSymbolToValidIdentifier(moduleSymbol: Symbol, target: ScriptTarget): string {
+ return moduleSpecifierToValidIdentifier(removeFileExtension(getBaseFileName(moduleSymbol.name)), target);
+ }
+
+ function moduleSpecifierToValidIdentifier(moduleSpecifier: string, target: ScriptTarget): string {
+ let res = "";
+ let lastCharWasValid = true;
+ const firstCharCode = moduleSpecifier.charCodeAt(0);
+ if (isIdentifierStart(firstCharCode, target)) {
+ res += String.fromCharCode(firstCharCode);
+ }
+ else {
+ lastCharWasValid = false;
+ }
+ for (let i = 1; i < moduleSpecifier.length; i++) {
+ const ch = moduleSpecifier.charCodeAt(i);
+ const isValid = isIdentifierPart(ch, target);
+ if (isValid) {
+ let char = String.fromCharCode(ch);
+ if (!lastCharWasValid) {
+ char = char.toUpperCase();
+ }
+ res += char;
+ }
+ lastCharWasValid = isValid;
+ }
+ // Need `|| "_"` to ensure result isn't empty.
+ const token = stringToToken(res);
+ return token === undefined || !isNonContextualKeyword(token) ? res || "_" : `_${res}`;
+ }
}
diff --git a/src/services/completions.ts b/src/services/completions.ts
index 3c233f4dbe8..6a9af1e1941 100644
--- a/src/services/completions.ts
+++ b/src/services/completions.ts
@@ -39,7 +39,7 @@ namespace ts.Completions {
return getStringLiteralCompletionEntries(sourceFile, position, typeChecker, compilerOptions, host, log);
}
- const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles, options);
+ const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles, options, compilerOptions.target);
if (!completionData) {
return undefined;
}
@@ -136,12 +136,12 @@ namespace ts.Completions {
typeChecker: TypeChecker,
target: ScriptTarget,
allowStringLiteral: boolean,
- origin: SymbolOriginInfo,
+ origin: SymbolOriginInfo | undefined,
): CompletionEntry | undefined {
// Try to get a valid display name for this symbol, if we could not find one, then ignore it.
// We would like to only show things that can be added after a dot, so for instance numeric properties can
// not be accessed with a dot (a.1 <- invalid)
- const displayName = getCompletionEntryDisplayNameForSymbol(symbol, target, performCharacterChecks, allowStringLiteral);
+ const displayName = getCompletionEntryDisplayNameForSymbol(symbol, target, performCharacterChecks, allowStringLiteral, origin);
if (!displayName) {
return undefined;
}
@@ -381,7 +381,7 @@ namespace ts.Completions {
{ name, source }: CompletionEntryIdentifier,
allSourceFiles: ReadonlyArray,
): { type: "symbol", symbol: Symbol, location: Node, symbolToOriginInfoMap: SymbolOriginInfoMap } | { type: "request", request: Request } | { type: "none" } {
- const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles, { includeExternalModuleExports: true });
+ const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles, { includeExternalModuleExports: true }, compilerOptions.target);
if (!completionData) {
return { type: "none" };
}
@@ -395,12 +395,18 @@ namespace ts.Completions {
// We don't need to perform character checks here because we're only comparing the
// name against 'entryName' (which is known to be good), not building a new
// completion entry.
- const symbol = find(symbols, s =>
- getCompletionEntryDisplayNameForSymbol(s, compilerOptions.target, /*performCharacterChecks*/ false, allowStringLiteral) === name
- && getSourceFromOrigin(symbolToOriginInfoMap[getSymbolId(s)]) === source);
+ const symbol = find(symbols, s => {
+ const origin = symbolToOriginInfoMap[getSymbolId(s)];
+ return getCompletionEntryDisplayNameForSymbol(s, compilerOptions.target, /*performCharacterChecks*/ false, allowStringLiteral, origin) === name
+ && getSourceFromOrigin(origin) === source;
+ });
return symbol ? { type: "symbol", symbol, location, symbolToOriginInfoMap } : { type: "none" };
}
+ function getSymbolName(symbol: Symbol, origin: SymbolOriginInfo | undefined, target: ScriptTarget): string {
+ return origin && origin.isDefaultExport && symbol.name === "default" ? codefix.moduleSymbolToValidIdentifier(origin.moduleSymbol, target) : symbol.name;
+ }
+
export interface CompletionEntryIdentifier {
name: string;
source?: string;
@@ -415,7 +421,7 @@ namespace ts.Completions {
entryId: CompletionEntryIdentifier,
allSourceFiles: ReadonlyArray,
host: LanguageServiceHost,
- rulesProvider: formatting.RulesProvider,
+ formatContext: formatting.FormatContext,
): CompletionEntryDetails {
const { name, source } = entryId;
// Compute all the completion symbols again.
@@ -436,7 +442,7 @@ namespace ts.Completions {
}
case "symbol": {
const { symbol, location, symbolToOriginInfoMap } = symbolCompletion;
- const codeActions = getCompletionEntryCodeActions(symbolToOriginInfoMap, symbol, typeChecker, host, compilerOptions, sourceFile, rulesProvider);
+ const codeActions = getCompletionEntryCodeActions(symbolToOriginInfoMap, symbol, typeChecker, host, compilerOptions, sourceFile, formatContext);
const kindModifiers = SymbolDisplay.getSymbolModifiers(symbol);
const { displayParts, documentation, symbolKind, tags } = SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, location, location, SemanticMeaning.All);
return { name, kindModifiers, kind: symbolKind, displayParts, documentation, tags, codeActions, source: source === undefined ? undefined : [textPart(source)] };
@@ -467,7 +473,7 @@ namespace ts.Completions {
host: LanguageServiceHost,
compilerOptions: CompilerOptions,
sourceFile: SourceFile,
- rulesProvider: formatting.RulesProvider,
+ formatContext: formatting.FormatContext,
): CodeAction[] | undefined {
const symbolOriginInfo = symbolToOriginInfoMap[getSymbolId(symbol)];
if (!symbolOriginInfo) {
@@ -481,8 +487,8 @@ namespace ts.Completions {
newLineCharacter: host.getNewLine(),
compilerOptions,
sourceFile,
- rulesProvider,
- symbolName: symbol.name,
+ formatContext,
+ symbolName: getSymbolName(symbol, symbolOriginInfo, compilerOptions.target),
getCanonicalFileName: createGetCanonicalFileName(host.useCaseSensitiveFileNames ? host.useCaseSensitiveFileNames() : false),
symbolToken: undefined,
kind: isDefaultExport ? codefix.ImportKind.Default : codefix.ImportKind.Named,
@@ -523,6 +529,7 @@ namespace ts.Completions {
position: number,
allSourceFiles: ReadonlyArray,
options: GetCompletionsAtPositionOptions,
+ target: ScriptTarget,
): CompletionData | undefined {
const isJavaScriptFile = isSourceFileJavaScript(sourceFile);
@@ -921,7 +928,7 @@ namespace ts.Completions {
symbols = typeChecker.getSymbolsInScope(scopeNode, symbolMeanings);
if (options.includeExternalModuleExports) {
- getSymbolsFromOtherSourceFileExports(symbols, previousToken && isIdentifier(previousToken) ? previousToken.text : "");
+ getSymbolsFromOtherSourceFileExports(symbols, previousToken && isIdentifier(previousToken) ? previousToken.text : "", target);
}
filterGlobalCompletion(symbols);
@@ -1003,7 +1010,7 @@ namespace ts.Completions {
}
}
- function getSymbolsFromOtherSourceFileExports(symbols: Symbol[], tokenText: string): void {
+ function getSymbolsFromOtherSourceFileExports(symbols: Symbol[], tokenText: string, target: ScriptTarget): void {
const tokenTextLowerCase = tokenText.toLowerCase();
codefix.forEachExternalModule(typeChecker, allSourceFiles, moduleSymbol => {
@@ -1020,6 +1027,9 @@ namespace ts.Completions {
symbol = localSymbol;
name = localSymbol.name;
}
+ else {
+ name = codefix.moduleSymbolToValidIdentifier(moduleSymbol, target);
+ }
}
if (symbol.declarations && symbol.declarations.some(d => isExportSpecifier(d) && !!d.parent.parent.moduleSpecifier)) {
@@ -1847,8 +1857,8 @@ namespace ts.Completions {
*
* @return undefined if the name is of external module
*/
- function getCompletionEntryDisplayNameForSymbol(symbol: Symbol, target: ScriptTarget, performCharacterChecks: boolean, allowStringLiteral: boolean): string | undefined {
- const name = symbol.name;
+ function getCompletionEntryDisplayNameForSymbol(symbol: Symbol, target: ScriptTarget, performCharacterChecks: boolean, allowStringLiteral: boolean, origin: SymbolOriginInfo | undefined): string | undefined {
+ const name = getSymbolName(symbol, origin, target);
if (!name) return undefined;
// First check of the displayName is not external module; if it is an external module, it is not valid entry
diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts
index 529fdae0545..b8122827491 100644
--- a/src/services/formatting/formatting.ts
+++ b/src/services/formatting/formatting.ts
@@ -1,10 +1,14 @@
-///
-///
-///
-///
+///
+///
+///
+///
/* @internal */
namespace ts.formatting {
+ export interface FormatContext {
+ readonly options: ts.FormatCodeSettings;
+ readonly getRule: ts.formatting.RulesMap;
+ }
export interface TextRangeWithKind extends TextRange {
kind: SyntaxKind;
@@ -67,7 +71,7 @@ namespace ts.formatting {
delta: number;
}
- export function formatOnEnter(position: number, sourceFile: SourceFile, rulesProvider: RulesProvider, options: FormatCodeSettings): TextChange[] {
+ export function formatOnEnter(position: number, sourceFile: SourceFile, formatContext: FormatContext): TextChange[] {
const line = sourceFile.getLineAndCharacterOfPosition(position).line;
if (line === 0) {
return [];
@@ -93,15 +97,15 @@ namespace ts.formatting {
// end value is exclusive so add 1 to the result
end: endOfFormatSpan + 1
};
- return formatSpan(span, sourceFile, options, rulesProvider, FormattingRequestKind.FormatOnEnter);
+ return formatSpan(span, sourceFile, formatContext, FormattingRequestKind.FormatOnEnter);
}
- export function formatOnSemicolon(position: number, sourceFile: SourceFile, rulesProvider: RulesProvider, options: FormatCodeSettings): TextChange[] {
+ export function formatOnSemicolon(position: number, sourceFile: SourceFile, formatContext: FormatContext): TextChange[] {
const semicolon = findImmediatelyPrecedingTokenOfKind(position, SyntaxKind.SemicolonToken, sourceFile);
- return formatNodeLines(findOutermostNodeWithinListLevel(semicolon), sourceFile, options, rulesProvider, FormattingRequestKind.FormatOnSemicolon);
+ return formatNodeLines(findOutermostNodeWithinListLevel(semicolon), sourceFile, formatContext, FormattingRequestKind.FormatOnSemicolon);
}
- export function formatOnOpeningCurly(position: number, sourceFile: SourceFile, rulesProvider: RulesProvider, options: FormatCodeSettings): TextChange[] {
+ export function formatOnOpeningCurly(position: number, sourceFile: SourceFile, formatContext: FormatContext): TextChange[] {
const openingCurly = findImmediatelyPrecedingTokenOfKind(position, SyntaxKind.OpenBraceToken, sourceFile);
if (!openingCurly) {
return [];
@@ -126,29 +130,29 @@ namespace ts.formatting {
end: position
};
- return formatSpan(textRange, sourceFile, options, rulesProvider, FormattingRequestKind.FormatOnOpeningCurlyBrace);
+ return formatSpan(textRange, sourceFile, formatContext, FormattingRequestKind.FormatOnOpeningCurlyBrace);
}
- export function formatOnClosingCurly(position: number, sourceFile: SourceFile, rulesProvider: RulesProvider, options: FormatCodeSettings): TextChange[] {
+ export function formatOnClosingCurly(position: number, sourceFile: SourceFile, formatContext: FormatContext): TextChange[] {
const precedingToken = findImmediatelyPrecedingTokenOfKind(position, SyntaxKind.CloseBraceToken, sourceFile);
- return formatNodeLines(findOutermostNodeWithinListLevel(precedingToken), sourceFile, options, rulesProvider, FormattingRequestKind.FormatOnClosingCurlyBrace);
+ return formatNodeLines(findOutermostNodeWithinListLevel(precedingToken), sourceFile, formatContext, FormattingRequestKind.FormatOnClosingCurlyBrace);
}
- export function formatDocument(sourceFile: SourceFile, rulesProvider: RulesProvider, options: FormatCodeSettings): TextChange[] {
+ export function formatDocument(sourceFile: SourceFile, formatContext: FormatContext): TextChange[] {
const span = {
pos: 0,
end: sourceFile.text.length
};
- return formatSpan(span, sourceFile, options, rulesProvider, FormattingRequestKind.FormatDocument);
+ return formatSpan(span, sourceFile, formatContext, FormattingRequestKind.FormatDocument);
}
- export function formatSelection(start: number, end: number, sourceFile: SourceFile, rulesProvider: RulesProvider, options: FormatCodeSettings): TextChange[] {
+ export function formatSelection(start: number, end: number, sourceFile: SourceFile, formatContext: FormatContext): TextChange[] {
// format from the beginning of the line
const span = {
pos: getLineStartPositionForPosition(start, sourceFile),
end,
};
- return formatSpan(span, sourceFile, options, rulesProvider, FormattingRequestKind.FormatSelection);
+ return formatSpan(span, sourceFile, formatContext, FormattingRequestKind.FormatSelection);
}
/**
@@ -337,7 +341,7 @@ namespace ts.formatting {
}
/* @internal */
- export function formatNodeGivenIndentation(node: Node, sourceFileLike: SourceFileLike, languageVariant: LanguageVariant, initialIndentation: number, delta: number, rulesProvider: RulesProvider): TextChange[] {
+ export function formatNodeGivenIndentation(node: Node, sourceFileLike: SourceFileLike, languageVariant: LanguageVariant, initialIndentation: number, delta: number, formatContext: FormatContext): TextChange[] {
const range = { pos: 0, end: sourceFileLike.text.length };
return getFormattingScanner(sourceFileLike.text, languageVariant, range.pos, range.end, scanner => formatSpanWorker(
range,
@@ -345,14 +349,13 @@ namespace ts.formatting {
initialIndentation,
delta,
scanner,
- rulesProvider.getFormatOptions(),
- rulesProvider,
+ formatContext,
FormattingRequestKind.FormatSelection,
_ => false, // assume that node does not have any errors
sourceFileLike));
}
- function formatNodeLines(node: Node, sourceFile: SourceFile, options: FormatCodeSettings, rulesProvider: RulesProvider, requestKind: FormattingRequestKind): TextChange[] {
+ function formatNodeLines(node: Node, sourceFile: SourceFile, formatContext: FormatContext, requestKind: FormattingRequestKind): TextChange[] {
if (!node) {
return [];
}
@@ -362,24 +365,19 @@ namespace ts.formatting {
end: node.end
};
- return formatSpan(span, sourceFile, options, rulesProvider, requestKind);
+ return formatSpan(span, sourceFile, formatContext, requestKind);
}
- function formatSpan(originalRange: TextRange,
- sourceFile: SourceFile,
- options: FormatCodeSettings,
- rulesProvider: RulesProvider,
- requestKind: FormattingRequestKind): TextChange[] {
+ function formatSpan(originalRange: TextRange, sourceFile: SourceFile, formatContext: FormatContext, requestKind: FormattingRequestKind): TextChange[] {
// find the smallest node that fully wraps the range and compute the initial indentation for the node
const enclosingNode = findEnclosingNode(originalRange, sourceFile);
return getFormattingScanner(sourceFile.text, sourceFile.languageVariant, getScanStartPosition(enclosingNode, originalRange, sourceFile), originalRange.end, scanner => formatSpanWorker(
originalRange,
enclosingNode,
- SmartIndenter.getIndentationForNode(enclosingNode, originalRange, sourceFile, options),
- getOwnOrInheritedDelta(enclosingNode, options, sourceFile),
+ SmartIndenter.getIndentationForNode(enclosingNode, originalRange, sourceFile, formatContext.options),
+ getOwnOrInheritedDelta(enclosingNode, formatContext.options, sourceFile),
scanner,
- options,
- rulesProvider,
+ formatContext,
requestKind,
prepareRangeContainsErrorFunction(sourceFile.parseDiagnostics, originalRange),
sourceFile));
@@ -390,8 +388,7 @@ namespace ts.formatting {
initialIndentation: number,
delta: number,
formattingScanner: FormattingScanner,
- options: FormatCodeSettings,
- rulesProvider: RulesProvider,
+ { options, getRule }: FormatContext,
requestKind: FormattingRequestKind,
rangeContainsError: (r: TextRange) => boolean,
sourceFile: SourceFileLike): TextChange[] {
@@ -917,14 +914,14 @@ namespace ts.formatting {
formattingContext.updateContext(previousItem, previousParent, currentItem, currentParent, contextNode);
- const rule = rulesProvider.getRulesMap().GetRule(formattingContext);
+ const rule = getRule(formattingContext);
let trimTrailingWhitespaces: boolean;
let lineAdded: boolean;
if (rule) {
applyRuleEdits(rule, previousItem, previousStartLine, currentItem, currentStartLine);
- if (rule.operation.action & (RuleAction.Space | RuleAction.Delete) && currentStartLine !== previousStartLine) {
+ if (rule.action & (RuleAction.Space | RuleAction.Delete) && currentStartLine !== previousStartLine) {
lineAdded = false;
// Handle the case where the next line is moved to be the end of this line.
// In this case we don't indent the next line in the next pass.
@@ -932,7 +929,7 @@ namespace ts.formatting {
dynamicIndentation.recomputeIndentation(/*lineAddedByFormatting*/ false);
}
}
- else if (rule.operation.action & RuleAction.NewLine && currentStartLine === previousStartLine) {
+ else if (rule.action & RuleAction.NewLine && currentStartLine === previousStartLine) {
lineAdded = true;
// Handle the case where token2 is moved to the new line.
// In this case we indent token2 in the next pass but we set
@@ -943,7 +940,7 @@ namespace ts.formatting {
}
// We need to trim trailing whitespace between the tokens if they were on different lines, and no rule was applied to put them on the same line
- trimTrailingWhitespaces = !(rule.operation.action & RuleAction.Delete) && rule.flag !== RuleFlags.CanDeleteNewLines;
+ trimTrailingWhitespaces = !(rule.action & RuleAction.Delete) && rule.flags !== RuleFlags.CanDeleteNewLines;
}
else {
trimTrailingWhitespaces = true;
@@ -1118,7 +1115,7 @@ namespace ts.formatting {
currentRange: TextRangeWithKind,
currentStartLine: number): void {
- switch (rule.operation.action) {
+ switch (rule.action) {
case RuleAction.Ignore:
// no action required
return;
@@ -1132,7 +1129,7 @@ namespace ts.formatting {
// exit early if we on different lines and rule cannot change number of newlines
// if line1 and line2 are on subsequent lines then no edits are required - ok to exit
// if line1 and line2 are separated with more than one newline - ok to exit since we cannot delete extra new lines
- if (rule.flag !== RuleFlags.CanDeleteNewLines && previousStartLine !== currentStartLine) {
+ if (rule.flags !== RuleFlags.CanDeleteNewLines && previousStartLine !== currentStartLine) {
return;
}
@@ -1144,7 +1141,7 @@ namespace ts.formatting {
break;
case RuleAction.Space:
// exit early if we on different lines and rule cannot change number of newlines
- if (rule.flag !== RuleFlags.CanDeleteNewLines && previousStartLine !== currentStartLine) {
+ if (rule.flags !== RuleFlags.CanDeleteNewLines && previousStartLine !== currentStartLine) {
return;
}
diff --git a/src/services/formatting/formattingContext.ts b/src/services/formatting/formattingContext.ts
index 043df72f434..2ba987e4af3 100644
--- a/src/services/formatting/formattingContext.ts
+++ b/src/services/formatting/formattingContext.ts
@@ -1,7 +1,14 @@
-///
-
/* @internal */
namespace ts.formatting {
+ export const enum FormattingRequestKind {
+ FormatDocument,
+ FormatSelection,
+ FormatOnEnter,
+ FormatOnSemicolon,
+ FormatOnOpeningCurlyBrace,
+ FormatOnClosingCurlyBrace
+ }
+
export class FormattingContext {
public currentTokenSpan: TextRangeWithKind;
public nextTokenSpan: TextRangeWithKind;
diff --git a/src/services/formatting/formattingRequestKind.ts b/src/services/formatting/formattingRequestKind.ts
deleted file mode 100644
index 6c671e1b888..00000000000
--- a/src/services/formatting/formattingRequestKind.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-///
-
-/* @internal */
-namespace ts.formatting {
- export const enum FormattingRequestKind {
- FormatDocument,
- FormatSelection,
- FormatOnEnter,
- FormatOnSemicolon,
- FormatOnOpeningCurlyBrace,
- FormatOnClosingCurlyBrace
- }
-}
\ No newline at end of file
diff --git a/src/services/formatting/references.ts b/src/services/formatting/references.ts
deleted file mode 100644
index 318f10c664e..00000000000
--- a/src/services/formatting/references.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-///
-///
-///
-///
-///
-///
-///
-///
-///
-///
-///
-///
\ No newline at end of file
diff --git a/src/services/formatting/rule.ts b/src/services/formatting/rule.ts
index 8fd432586b4..aa1bb6b43e9 100644
--- a/src/services/formatting/rule.ts
+++ b/src/services/formatting/rule.ts
@@ -1,14 +1,30 @@
-///
-
/* @internal */
namespace ts.formatting {
- export class Rule {
+ export interface Rule {
// Used for debugging to identify each rule based on the property name it's assigned to.
- public debugName?: string;
- constructor(
- readonly descriptor: RuleDescriptor,
- readonly operation: RuleOperation,
- readonly flag: RuleFlags = RuleFlags.None) {
- }
+ readonly debugName: string;
+ readonly context: ReadonlyArray;
+ readonly action: RuleAction;
+ readonly flags: RuleFlags;
+ }
+
+ export type ContextPredicate = (context: FormattingContext) => boolean;
+ export const anyContext: ReadonlyArray = emptyArray;
+
+ export const enum RuleAction {
+ Ignore = 1 << 0,
+ Space = 1 << 1,
+ NewLine = 1 << 2,
+ Delete = 1 << 3,
+ }
+
+ export const enum RuleFlags {
+ None,
+ CanDeleteNewLines,
+ }
+
+ export interface TokenRange {
+ readonly tokens: ReadonlyArray;
+ readonly isSpecific: boolean;
}
}
\ No newline at end of file
diff --git a/src/services/formatting/ruleAction.ts b/src/services/formatting/ruleAction.ts
deleted file mode 100644
index 13e9043e1c6..00000000000
--- a/src/services/formatting/ruleAction.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-///
-
-/* @internal */
-namespace ts.formatting {
- export const enum RuleAction {
- Ignore = 0x00000001,
- Space = 0x00000002,
- NewLine = 0x00000004,
- Delete = 0x00000008
- }
-}
\ No newline at end of file
diff --git a/src/services/formatting/ruleDescriptor.ts b/src/services/formatting/ruleDescriptor.ts
deleted file mode 100644
index b8529496956..00000000000
--- a/src/services/formatting/ruleDescriptor.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-///
-
-/* @internal */
-namespace ts.formatting {
- export class RuleDescriptor {
- constructor(public leftTokenRange: Shared.TokenRange, public rightTokenRange: Shared.TokenRange) {
- }
-
- public toString(): string {
- return "[leftRange=" + this.leftTokenRange + "," +
- "rightRange=" + this.rightTokenRange + "]";
- }
-
- static create1(left: SyntaxKind, right: SyntaxKind): RuleDescriptor {
- return RuleDescriptor.create4(Shared.TokenRange.FromToken(left), Shared.TokenRange.FromToken(right));
- }
-
- static create2(left: Shared.TokenRange, right: SyntaxKind): RuleDescriptor {
- return RuleDescriptor.create4(left, Shared.TokenRange.FromToken(right));
- }
-
- static create3(left: SyntaxKind, right: Shared.TokenRange): RuleDescriptor {
- return RuleDescriptor.create4(Shared.TokenRange.FromToken(left), right);
- }
-
- static create4(left: Shared.TokenRange, right: Shared.TokenRange): RuleDescriptor {
- return new RuleDescriptor(left, right);
- }
- }
-}
\ No newline at end of file
diff --git a/src/services/formatting/ruleFlag.ts b/src/services/formatting/ruleFlag.ts
deleted file mode 100644
index 7619f232ad4..00000000000
--- a/src/services/formatting/ruleFlag.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-///
-
-
-/* @internal */
-namespace ts.formatting {
- export const enum RuleFlags {
- None,
- CanDeleteNewLines
- }
-}
\ No newline at end of file
diff --git a/src/services/formatting/ruleOperation.ts b/src/services/formatting/ruleOperation.ts
deleted file mode 100644
index 462c27352d8..00000000000
--- a/src/services/formatting/ruleOperation.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-///
-
-/* @internal */
-namespace ts.formatting {
- export class RuleOperation {
- constructor(readonly context: RuleOperationContext, readonly action: RuleAction) {}
-
- public toString(): string {
- return "[context=" + this.context + "," +
- "action=" + this.action + "]";
- }
-
- static create1(action: RuleAction) {
- return RuleOperation.create2(RuleOperationContext.any, action);
- }
-
- static create2(context: RuleOperationContext, action: RuleAction) {
- return new RuleOperation(context, action);
- }
- }
-}
\ No newline at end of file
diff --git a/src/services/formatting/ruleOperationContext.ts b/src/services/formatting/ruleOperationContext.ts
deleted file mode 100644
index c433d106372..00000000000
--- a/src/services/formatting/ruleOperationContext.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-///
-
-/* @internal */
-namespace ts.formatting {
-
- export class RuleOperationContext {
- private readonly customContextChecks: ((context: FormattingContext) => boolean)[];
-
- constructor(...funcs: ((context: FormattingContext) => boolean)[]) {
- this.customContextChecks = funcs;
- }
-
- static readonly any: RuleOperationContext = new RuleOperationContext();
-
- public IsAny(): boolean {
- return this === RuleOperationContext.any;
- }
-
- public InContext(context: FormattingContext): boolean {
- if (this.IsAny()) {
- return true;
- }
-
- for (const check of this.customContextChecks) {
- if (!check(context)) {
- return false;
- }
- }
- return true;
- }
- }
-}
\ No newline at end of file
diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts
index c5b59e818eb..8214ffd6f2d 100644
--- a/src/services/formatting/rules.ts
+++ b/src/services/formatting/rules.ts
@@ -1,929 +1,723 @@
-///
-
/* @internal */
namespace ts.formatting {
- // tslint:disable variable-name (TODO)
- export class Rules {
- public IgnoreBeforeComment: Rule;
- public IgnoreAfterLineComment: Rule;
+ export interface RuleSpec {
+ readonly leftTokenRange: TokenRange;
+ readonly rightTokenRange: TokenRange;
+ readonly rule: Rule;
+ }
- // Space after keyword but not before ; or : or ?
- public NoSpaceBeforeSemicolon: Rule;
- public NoSpaceBeforeColon: Rule;
- public NoSpaceBeforeQuestionMark: Rule;
- public SpaceAfterColon: Rule;
- // insert space after '?' only when it is used in conditional operator
- public SpaceAfterQuestionMarkInConditionalOperator: Rule;
- // in other cases there should be no space between '?' and next token
- public NoSpaceAfterQuestionMark: Rule;
+ export function getAllRules(): RuleSpec[] {
+ const allTokens: SyntaxKind[] = [];
+ for (let token = SyntaxKind.FirstToken; token <= SyntaxKind.LastToken; token++) {
+ allTokens.push(token);
+ }
+ function anyTokenExcept(token: SyntaxKind): TokenRange {
+ return { tokens: allTokens.filter(t => t !== token), isSpecific: false };
+ }
- public SpaceAfterSemicolon: Rule;
+ const anyToken: TokenRange = { tokens: allTokens, isSpecific: false };
+ const anyTokenIncludingMultilineComments = tokenRangeFrom([...allTokens, SyntaxKind.MultiLineCommentTrivia]);
+ const keywords = tokenRangeFromRange(SyntaxKind.FirstKeyword, SyntaxKind.LastKeyword);
+ const binaryOperators = tokenRangeFromRange(SyntaxKind.FirstBinaryOperator, SyntaxKind.LastBinaryOperator);
+ const binaryKeywordOperators = [SyntaxKind.InKeyword, SyntaxKind.InstanceOfKeyword, SyntaxKind.OfKeyword, SyntaxKind.AsKeyword, SyntaxKind.IsKeyword];
+ const unaryPrefixOperators = [SyntaxKind.PlusPlusToken, SyntaxKind.MinusMinusToken, SyntaxKind.TildeToken, SyntaxKind.ExclamationToken];
+ const unaryPrefixExpressions = [
+ SyntaxKind.NumericLiteral, SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.OpenBracketToken,
+ SyntaxKind.OpenBraceToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword];
+ const unaryPreincrementExpressions = [SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword];
+ const unaryPostincrementExpressions = [SyntaxKind.Identifier, SyntaxKind.CloseParenToken, SyntaxKind.CloseBracketToken, SyntaxKind.NewKeyword];
+ const unaryPredecrementExpressions = [SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword];
+ const unaryPostdecrementExpressions = [SyntaxKind.Identifier, SyntaxKind.CloseParenToken, SyntaxKind.CloseBracketToken, SyntaxKind.NewKeyword];
+ const comments = [SyntaxKind.SingleLineCommentTrivia, SyntaxKind.MultiLineCommentTrivia];
+ const typeNames = [SyntaxKind.Identifier, ...typeKeywords];
- // Space/new line after }.
- public SpaceAfterCloseBrace: Rule;
-
- // Special case for (}, else) and (}, while) since else & while tokens are not part of the tree which makes SpaceAfterCloseBrace rule not applied
- // Also should not apply to })
- public SpaceBetweenCloseBraceAndElse: Rule;
- public SpaceBetweenCloseBraceAndWhile: Rule;
- public NoSpaceAfterCloseBrace: Rule;
-
- // No space for dot
- public NoSpaceBeforeDot: Rule;
- public NoSpaceAfterDot: Rule;
-
- // No space before and after indexer
- public NoSpaceBeforeOpenBracket: Rule;
- public NoSpaceAfterCloseBracket: Rule;
-
- // Insert a space after { and before } in single-line contexts, but remove space from empty object literals {}.
- public SpaceAfterOpenBrace: Rule;
- public SpaceBeforeCloseBrace: Rule;
- public NoSpaceAfterOpenBrace: Rule;
- public NoSpaceBeforeCloseBrace: Rule;
- public NoSpaceBetweenEmptyBraceBrackets: Rule;
-
- // Insert new line after { and before } in multi-line contexts.
- public NewLineAfterOpenBraceInBlockContext: Rule;
-
- // For functions and control block place } on a new line [multi-line rule]
- public NewLineBeforeCloseBraceInBlockContext: Rule;
-
- // Special handling of unary operators.
- // Prefix operators generally shouldn't have a space between
- // them and their target unary expression.
- public NoSpaceAfterUnaryPrefixOperator: Rule;
- public NoSpaceAfterUnaryPreincrementOperator: Rule;
- public NoSpaceAfterUnaryPredecrementOperator: Rule;
- public NoSpaceBeforeUnaryPostincrementOperator: Rule;
- public NoSpaceBeforeUnaryPostdecrementOperator: Rule;
-
- // More unary operator special-casing.
- // DevDiv 181814: Be careful when removing leading whitespace
- // around unary operators. Examples:
- // 1 - -2 --X--> 1--2
- // a + ++b --X--> a+++b
- public SpaceAfterPostincrementWhenFollowedByAdd: Rule;
- public SpaceAfterAddWhenFollowedByUnaryPlus: Rule;
- public SpaceAfterAddWhenFollowedByPreincrement: Rule;
- public SpaceAfterPostdecrementWhenFollowedBySubtract: Rule;
- public SpaceAfterSubtractWhenFollowedByUnaryMinus: Rule;
- public SpaceAfterSubtractWhenFollowedByPredecrement: Rule;
-
- public NoSpaceBeforeComma: Rule;
-
- public SpaceAfterCertainKeywords: Rule;
- public NoSpaceAfterNewKeywordOnConstructorSignature: Rule;
- public SpaceAfterLetConstInVariableDeclaration: Rule;
- public NoSpaceBeforeOpenParenInFuncCall: Rule;
- public SpaceAfterFunctionInFuncDecl: Rule;
- public SpaceBeforeOpenParenInFuncDecl: Rule;
- public NoSpaceBeforeOpenParenInFuncDecl: Rule;
- public SpaceAfterVoidOperator: Rule;
-
- public NoSpaceBetweenReturnAndSemicolon: Rule;
-
- // Add a space between statements. All keywords except (do,else,case) has open/close parens after them.
- // So, we have a rule to add a space for [),Any], [do,Any], [else,Any], and [case,Any]
- public SpaceBetweenStatements: Rule;
-
- // This low-pri rule takes care of "try {" and "finally {" in case the rule SpaceBeforeOpenBraceInControl didn't execute on FormatOnEnter.
- public SpaceAfterTryFinally: Rule;
-
- // For get/set members, we check for (identifier,identifier) since get/set don't have tokens and they are represented as just an identifier token.
- // Though, we do extra check on the context to make sure we are dealing with get/set node. Example:
- // get x() {}
- // set x(val) {}
- public SpaceAfterGetSetInMember: Rule;
-
- // Special case for binary operators (that are keywords). For these we have to add a space and shouldn't follow any user options.
- public SpaceBeforeBinaryKeywordOperator: Rule;
- public SpaceAfterBinaryKeywordOperator: Rule;
-
- // TypeScript-specific rules
-
- // Treat constructor as an identifier in a function declaration, and remove spaces between constructor and following left parentheses
- public SpaceAfterConstructor: Rule;
- public NoSpaceAfterConstructor: Rule;
-
- // Use of module as a function call. e.g.: import m2 = module("m2");
- public NoSpaceAfterModuleImport: Rule;
-
- // Add a space around certain TypeScript keywords
- public SpaceAfterCertainTypeScriptKeywords: Rule;
- public SpaceBeforeCertainTypeScriptKeywords: Rule;
-
- // Treat string literals in module names as identifiers, and add a space between the literal and the opening Brace braces, e.g.: module "m2" {
- public SpaceAfterModuleName: Rule;
-
- // Lambda expressions
- public SpaceBeforeArrow: Rule;
- public SpaceAfterArrow: Rule;
-
- // Optional parameters and let args
- public NoSpaceAfterEllipsis: Rule;
- public NoSpaceAfterOptionalParameters: Rule;
-
- // generics
- public NoSpaceBeforeOpenAngularBracket: Rule;
- public NoSpaceBetweenCloseParenAndAngularBracket: Rule;
- public NoSpaceAfterOpenAngularBracket: Rule;
- public NoSpaceBeforeCloseAngularBracket: Rule;
- public NoSpaceAfterCloseAngularBracket: Rule;
-
- // Remove spaces in empty interface literals. e.g.: x: {}
- public NoSpaceBetweenEmptyInterfaceBraceBrackets: Rule;
-
- // These rules are higher in priority than user-configurable rules.
- public HighPriorityCommonRules: Rule[];
-
- // These rules are applied after high priority rules.
- public UserConfigurableRules: Rule[];
-
- // These rules are lower in priority than user-configurable rules.
- public LowPriorityCommonRules: Rule[];
-
- ///
- /// Rules controlled by user options
- ///
-
- // Insert space after comma delimiter
- public SpaceAfterComma: Rule;
- public NoSpaceAfterComma: Rule;
-
- // Insert space before and after binary operators
- public SpaceBeforeBinaryOperator: Rule;
- public SpaceAfterBinaryOperator: Rule;
- public NoSpaceBeforeBinaryOperator: Rule;
- public NoSpaceAfterBinaryOperator: Rule;
-
- // Insert space after keywords in control flow statements
- public SpaceAfterKeywordInControl: Rule;
- public NoSpaceAfterKeywordInControl: Rule;
-
- // Open Brace braces after function
+ // Place a space before open brace in a function declaration
// TypeScript: Function can have return types, which can be made of tons of different token kinds
- public FunctionOpenBraceLeftTokenRange: Shared.TokenRange;
- public SpaceBeforeOpenBraceInFunction: Rule;
- public NewLineBeforeOpenBraceInFunction: Rule;
+ const functionOpenBraceLeftTokenRange = anyTokenIncludingMultilineComments;
- // Open Brace braces after TypeScript module/class/interface
- public TypeScriptOpenBraceLeftTokenRange: Shared.TokenRange;
- public SpaceBeforeOpenBraceInTypeScriptDeclWithBlock: Rule;
- public NewLineBeforeOpenBraceInTypeScriptDeclWithBlock: Rule;
+ // Place a space before open brace in a TypeScript declaration that has braces as children (class, module, enum, etc)
+ const typeScriptOpenBraceLeftTokenRange = tokenRangeFrom([SyntaxKind.Identifier, SyntaxKind.MultiLineCommentTrivia, SyntaxKind.ClassKeyword, SyntaxKind.ExportKeyword, SyntaxKind.ImportKeyword]);
- // Open Brace braces after control block
- public ControlOpenBraceLeftTokenRange: Shared.TokenRange;
- public SpaceBeforeOpenBraceInControl: Rule;
- public NewLineBeforeOpenBraceInControl: Rule;
-
- // Insert space after semicolon in for statement
- public SpaceAfterSemicolonInFor: Rule;
- public NoSpaceAfterSemicolonInFor: Rule;
-
- // Insert space after opening and before closing nonempty parenthesis
- public SpaceAfterOpenParen: Rule;
- public SpaceBeforeCloseParen: Rule;
- public SpaceBetweenOpenParens: Rule;
- public NoSpaceBetweenParens: Rule;
- public NoSpaceAfterOpenParen: Rule;
- public NoSpaceBeforeCloseParen: Rule;
-
- // Insert space after opening and before closing nonempty brackets
- public SpaceAfterOpenBracket: Rule;
- public SpaceBeforeCloseBracket: Rule;
- public NoSpaceBetweenBrackets: Rule;
- public NoSpaceAfterOpenBracket: Rule;
- public NoSpaceBeforeCloseBracket: Rule;
-
- // Insert space after function keyword for anonymous functions
- public SpaceAfterAnonymousFunctionKeyword: Rule;
- public NoSpaceAfterAnonymousFunctionKeyword: Rule;
-
- // Insert space after @ in decorator
- public SpaceBeforeAt: Rule;
- public NoSpaceAfterAt: Rule;
- public SpaceAfterDecorator: Rule;
-
- // Generator: function*
- public NoSpaceBetweenFunctionKeywordAndStar: Rule;
- public SpaceAfterStarInGeneratorDeclaration: Rule;
- public NoSpaceBetweenYieldKeywordAndStar: Rule;
- public SpaceBetweenYieldOrYieldStarAndOperand: Rule;
-
- // Async functions
- public SpaceBetweenAsyncAndOpenParen: Rule;
- public SpaceBetweenAsyncAndFunctionKeyword: Rule;
-
- // Template strings
- public NoSpaceBetweenTagAndTemplateString: Rule;
- public NoSpaceAfterTemplateHeadAndMiddle: Rule;
- public SpaceAfterTemplateHeadAndMiddle: Rule;
- public NoSpaceBeforeTemplateMiddleAndTail: Rule;
- public SpaceBeforeTemplateMiddleAndTail: Rule;
-
- // No space after { and before } in JSX expression
- public NoSpaceAfterOpenBraceInJsxExpression: Rule;
- public SpaceAfterOpenBraceInJsxExpression: Rule;
- public NoSpaceBeforeCloseBraceInJsxExpression: Rule;
- public SpaceBeforeCloseBraceInJsxExpression: Rule;
-
- // JSX opening elements
- public SpaceBeforeJsxAttribute: Rule;
- public SpaceBeforeSlashInJsxOpeningElement: Rule;
- public NoSpaceBeforeGreaterThanTokenInJsxOpeningElement: Rule;
- public NoSpaceBeforeEqualInJsxAttribute: Rule;
- public NoSpaceAfterEqualInJsxAttribute: Rule;
-
- // No space after type assertions
- public NoSpaceAfterTypeAssertion: Rule;
- public SpaceAfterTypeAssertion: Rule;
-
- // No space before non-null assertion operator
- public NoSpaceBeforeNonNullAssertionOperator: Rule;
-
- constructor() {
- ///
- /// Common Rules
- ///
+ // Place a space before open brace in a control flow construct
+ const controlOpenBraceLeftTokenRange = tokenRangeFrom([SyntaxKind.CloseParenToken, SyntaxKind.MultiLineCommentTrivia, SyntaxKind.DoKeyword, SyntaxKind.TryKeyword, SyntaxKind.FinallyKeyword, SyntaxKind.ElseKeyword]);
+ // These rules are higher in priority than user-configurable
+ const highPriorityCommonRules = [
// Leave comments alone
- this.IgnoreBeforeComment = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.Comments), RuleOperation.create1(RuleAction.Ignore));
- this.IgnoreAfterLineComment = new Rule(RuleDescriptor.create3(SyntaxKind.SingleLineCommentTrivia, Shared.TokenRange.Any), RuleOperation.create1(RuleAction.Ignore));
+ rule("IgnoreBeforeComment", anyToken, comments, anyContext, RuleAction.Ignore),
+ rule("IgnoreAfterLineComment", SyntaxKind.SingleLineCommentTrivia, anyToken, anyContext, RuleAction.Ignore),
- // Space after keyword but not before ; or : or ?
- this.NoSpaceBeforeSemicolon = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.SemicolonToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
- this.NoSpaceBeforeColon = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.ColonToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNotBinaryOpContext), RuleAction.Delete));
- this.NoSpaceBeforeQuestionMark = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.QuestionToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNotBinaryOpContext), RuleAction.Delete));
- this.SpaceAfterColon = new Rule(RuleDescriptor.create3(SyntaxKind.ColonToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNotBinaryOpContext), RuleAction.Space));
- this.SpaceAfterQuestionMarkInConditionalOperator = new Rule(RuleDescriptor.create3(SyntaxKind.QuestionToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsConditionalOperatorContext), RuleAction.Space));
- this.NoSpaceAfterQuestionMark = new Rule(RuleDescriptor.create3(SyntaxKind.QuestionToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
- this.SpaceAfterSemicolon = new Rule(RuleDescriptor.create3(SyntaxKind.SemicolonToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
+ rule("NoSpaceBeforeColon", anyToken, SyntaxKind.ColonToken, [isNonJsxSameLineTokenContext, isNotBinaryOpContext], RuleAction.Delete),
+ rule("SpaceAfterColon", SyntaxKind.ColonToken, anyToken, [isNonJsxSameLineTokenContext, isNotBinaryOpContext], RuleAction.Space),
+ rule("NoSpaceBeforeQuestionMark", anyToken, SyntaxKind.QuestionToken, [isNonJsxSameLineTokenContext, isNotBinaryOpContext], RuleAction.Delete),
+ // insert space after '?' only when it is used in conditional operator
+ rule("SpaceAfterQuestionMarkInConditionalOperator", SyntaxKind.QuestionToken, anyToken, [isNonJsxSameLineTokenContext, isConditionalOperatorContext], RuleAction.Space),
- // Space after }.
- this.SpaceAfterCloseBrace = new Rule(RuleDescriptor.create3(SyntaxKind.CloseBraceToken, Shared.TokenRange.FromRange(SyntaxKind.FirstToken, SyntaxKind.LastToken, [SyntaxKind.CloseParenToken])), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsAfterCodeBlockContext), RuleAction.Space));
+ // in other cases there should be no space between '?' and next token
+ rule("NoSpaceAfterQuestionMark", SyntaxKind.QuestionToken, anyToken, [isNonJsxSameLineTokenContext], RuleAction.Delete),
- // Special case for (}, else) and (}, while) since else & while tokens are not part of the tree which makes SpaceAfterCloseBrace rule not applied
- this.SpaceBetweenCloseBraceAndElse = new Rule(RuleDescriptor.create1(SyntaxKind.CloseBraceToken, SyntaxKind.ElseKeyword), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
- this.SpaceBetweenCloseBraceAndWhile = new Rule(RuleDescriptor.create1(SyntaxKind.CloseBraceToken, SyntaxKind.WhileKeyword), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
- this.NoSpaceAfterCloseBrace = new Rule(RuleDescriptor.create3(SyntaxKind.CloseBraceToken, Shared.TokenRange.FromTokens([SyntaxKind.CloseBracketToken, SyntaxKind.CommaToken, SyntaxKind.SemicolonToken])), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
-
- // No space for dot
- this.NoSpaceBeforeDot = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.DotToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
- this.NoSpaceAfterDot = new Rule(RuleDescriptor.create3(SyntaxKind.DotToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
-
- // No space before and after indexer
- this.NoSpaceBeforeOpenBracket = new Rule(
- RuleDescriptor.create2(Shared.TokenRange.AnyExcept(SyntaxKind.AsyncKeyword), SyntaxKind.OpenBracketToken),
- RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
- this.NoSpaceAfterCloseBracket = new Rule(RuleDescriptor.create3(SyntaxKind.CloseBracketToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNotBeforeBlockInFunctionDeclarationContext), RuleAction.Delete));
-
- // Place a space before open brace in a function declaration
- this.FunctionOpenBraceLeftTokenRange = Shared.TokenRange.AnyIncludingMultilineComments;
- this.SpaceBeforeOpenBraceInFunction = new Rule(RuleDescriptor.create2(this.FunctionOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForFunctions"), Rules.IsFunctionDeclContext, Rules.IsBeforeBlockContext, Rules.IsNotFormatOnEnter, Rules.IsSameLineTokenOrBeforeBlockContext), RuleAction.Space), RuleFlags.CanDeleteNewLines);
-
- // Place a space before open brace in a TypeScript declaration that has braces as children (class, module, enum, etc)
- this.TypeScriptOpenBraceLeftTokenRange = Shared.TokenRange.FromTokens([SyntaxKind.Identifier, SyntaxKind.MultiLineCommentTrivia, SyntaxKind.ClassKeyword, SyntaxKind.ExportKeyword, SyntaxKind.ImportKeyword]);
- this.SpaceBeforeOpenBraceInTypeScriptDeclWithBlock = new Rule(RuleDescriptor.create2(this.TypeScriptOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForFunctions"), Rules.IsTypeScriptDeclWithBlockContext, Rules.IsNotFormatOnEnter, Rules.IsSameLineTokenOrBeforeBlockContext), RuleAction.Space), RuleFlags.CanDeleteNewLines);
-
- // Place a space before open brace in a control flow construct
- this.ControlOpenBraceLeftTokenRange = Shared.TokenRange.FromTokens([SyntaxKind.CloseParenToken, SyntaxKind.MultiLineCommentTrivia, SyntaxKind.DoKeyword, SyntaxKind.TryKeyword, SyntaxKind.FinallyKeyword, SyntaxKind.ElseKeyword]);
- this.SpaceBeforeOpenBraceInControl = new Rule(RuleDescriptor.create2(this.ControlOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForControlBlocks"), Rules.IsControlDeclContext, Rules.IsNotFormatOnEnter, Rules.IsSameLineTokenOrBeforeBlockContext), RuleAction.Space), RuleFlags.CanDeleteNewLines);
-
- // Insert a space after { and before } in single-line contexts, but remove space from empty object literals {}.
- this.SpaceAfterOpenBrace = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), Rules.IsBraceWrappedContext), RuleAction.Space));
- this.SpaceBeforeCloseBrace = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), Rules.IsBraceWrappedContext), RuleAction.Space));
- this.NoSpaceAfterOpenBrace = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
- this.NoSpaceBeforeCloseBrace = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
- this.NoSpaceBetweenEmptyBraceBrackets = new Rule(RuleDescriptor.create1(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsObjectContext), RuleAction.Delete));
-
- // Insert new line after { and before } in multi-line contexts.
- this.NewLineAfterOpenBraceInBlockContext = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsMultilineBlockContext), RuleAction.NewLine));
-
- // For functions and control block place } on a new line [multi-line rule]
- this.NewLineBeforeCloseBraceInBlockContext = new Rule(RuleDescriptor.create2(Shared.TokenRange.AnyIncludingMultilineComments, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsMultilineBlockContext), RuleAction.NewLine));
+ rule("NoSpaceBeforeDot", anyToken, SyntaxKind.DotToken, [isNonJsxSameLineTokenContext], RuleAction.Delete),
+ rule("NoSpaceAfterDot", SyntaxKind.DotToken, anyToken, [isNonJsxSameLineTokenContext], RuleAction.Delete),
// Special handling of unary operators.
// Prefix operators generally shouldn't have a space between
// them and their target unary expression.
- this.NoSpaceAfterUnaryPrefixOperator = new Rule(RuleDescriptor.create4(Shared.TokenRange.UnaryPrefixOperators, Shared.TokenRange.UnaryPrefixExpressions), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNotBinaryOpContext), RuleAction.Delete));
- this.NoSpaceAfterUnaryPreincrementOperator = new Rule(RuleDescriptor.create3(SyntaxKind.PlusPlusToken, Shared.TokenRange.UnaryPreincrementExpressions), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
- this.NoSpaceAfterUnaryPredecrementOperator = new Rule(RuleDescriptor.create3(SyntaxKind.MinusMinusToken, Shared.TokenRange.UnaryPredecrementExpressions), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
- this.NoSpaceBeforeUnaryPostincrementOperator = new Rule(RuleDescriptor.create2(Shared.TokenRange.UnaryPostincrementExpressions, SyntaxKind.PlusPlusToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
- this.NoSpaceBeforeUnaryPostdecrementOperator = new Rule(RuleDescriptor.create2(Shared.TokenRange.UnaryPostdecrementExpressions, SyntaxKind.MinusMinusToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
+ rule("NoSpaceAfterUnaryPrefixOperator", unaryPrefixOperators, unaryPrefixExpressions, [isNonJsxSameLineTokenContext, isNotBinaryOpContext], RuleAction.Delete),
+ rule("NoSpaceAfterUnaryPreincrementOperator", SyntaxKind.PlusPlusToken, unaryPreincrementExpressions, [isNonJsxSameLineTokenContext], RuleAction.Delete),
+ rule("NoSpaceAfterUnaryPredecrementOperator", SyntaxKind.MinusMinusToken, unaryPredecrementExpressions, [isNonJsxSameLineTokenContext], RuleAction.Delete),
+ rule("NoSpaceBeforeUnaryPostincrementOperator", unaryPostincrementExpressions, SyntaxKind.PlusPlusToken, [isNonJsxSameLineTokenContext], RuleAction.Delete),
+ rule("NoSpaceBeforeUnaryPostdecrementOperator", unaryPostdecrementExpressions, SyntaxKind.MinusMinusToken, [isNonJsxSameLineTokenContext], RuleAction.Delete),
// More unary operator special-casing.
// DevDiv 181814: Be careful when removing leading whitespace
// around unary operators. Examples:
// 1 - -2 --X--> 1--2
// a + ++b --X--> a+++b
- this.SpaceAfterPostincrementWhenFollowedByAdd = new Rule(RuleDescriptor.create1(SyntaxKind.PlusPlusToken, SyntaxKind.PlusToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), RuleAction.Space));
- this.SpaceAfterAddWhenFollowedByUnaryPlus = new Rule(RuleDescriptor.create1(SyntaxKind.PlusToken, SyntaxKind.PlusToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), RuleAction.Space));
- this.SpaceAfterAddWhenFollowedByPreincrement = new Rule(RuleDescriptor.create1(SyntaxKind.PlusToken, SyntaxKind.PlusPlusToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), RuleAction.Space));
- this.SpaceAfterPostdecrementWhenFollowedBySubtract = new Rule(RuleDescriptor.create1(SyntaxKind.MinusMinusToken, SyntaxKind.MinusToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), RuleAction.Space));
- this.SpaceAfterSubtractWhenFollowedByUnaryMinus = new Rule(RuleDescriptor.create1(SyntaxKind.MinusToken, SyntaxKind.MinusToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), RuleAction.Space));
- this.SpaceAfterSubtractWhenFollowedByPredecrement = new Rule(RuleDescriptor.create1(SyntaxKind.MinusToken, SyntaxKind.MinusMinusToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), RuleAction.Space));
+ rule("SpaceAfterPostincrementWhenFollowedByAdd", SyntaxKind.PlusPlusToken, SyntaxKind.PlusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Space),
+ rule("SpaceAfterAddWhenFollowedByUnaryPlus", SyntaxKind.PlusToken, SyntaxKind.PlusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Space),
+ rule("SpaceAfterAddWhenFollowedByPreincrement", SyntaxKind.PlusToken, SyntaxKind.PlusPlusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Space),
+ rule("SpaceAfterPostdecrementWhenFollowedBySubtract", SyntaxKind.MinusMinusToken, SyntaxKind.MinusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Space),
+ rule("SpaceAfterSubtractWhenFollowedByUnaryMinus", SyntaxKind.MinusToken, SyntaxKind.MinusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Space),
+ rule("SpaceAfterSubtractWhenFollowedByPredecrement", SyntaxKind.MinusToken, SyntaxKind.MinusMinusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Space),
- this.NoSpaceBeforeComma = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CommaToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
+ rule("NoSpaceAfterCloseBrace", SyntaxKind.CloseBraceToken, [SyntaxKind.CloseBracketToken, SyntaxKind.CommaToken, SyntaxKind.SemicolonToken], [isNonJsxSameLineTokenContext], RuleAction.Delete),
+ // For functions and control block place } on a new line [multi-line rule]
+ rule("NewLineBeforeCloseBraceInBlockContext", anyTokenIncludingMultilineComments, SyntaxKind.CloseBraceToken, [isMultilineBlockContext], RuleAction.NewLine),
- this.SpaceAfterCertainKeywords = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.VarKeyword, SyntaxKind.ThrowKeyword, SyntaxKind.NewKeyword, SyntaxKind.DeleteKeyword, SyntaxKind.ReturnKeyword, SyntaxKind.TypeOfKeyword, SyntaxKind.AwaitKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
- this.NoSpaceAfterNewKeywordOnConstructorSignature = new Rule(RuleDescriptor.create1(SyntaxKind.NewKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsConstructorSignatureContext), RuleAction.Delete));
- this.SpaceAfterLetConstInVariableDeclaration = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.LetKeyword, SyntaxKind.ConstKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsStartOfVariableDeclarationList), RuleAction.Space));
- this.NoSpaceBeforeOpenParenInFuncCall = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsFunctionCallOrNewContext, Rules.IsPreviousTokenNotComma), RuleAction.Delete));
- this.SpaceAfterFunctionInFuncDecl = new Rule(RuleDescriptor.create3(SyntaxKind.FunctionKeyword, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsFunctionDeclContext), RuleAction.Space));
- this.SpaceBeforeOpenParenInFuncDecl = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceBeforeFunctionParenthesis"), Rules.IsNonJsxSameLineTokenContext, Rules.IsFunctionDeclContext), RuleAction.Space));
- this.NoSpaceBeforeOpenParenInFuncDecl = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceBeforeFunctionParenthesis"), Rules.IsNonJsxSameLineTokenContext, Rules.IsFunctionDeclContext), RuleAction.Delete));
- this.SpaceAfterVoidOperator = new Rule(RuleDescriptor.create3(SyntaxKind.VoidKeyword, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsVoidOpContext), RuleAction.Space));
+ // Space/new line after }.
+ rule("SpaceAfterCloseBrace", SyntaxKind.CloseBraceToken, anyTokenExcept(SyntaxKind.CloseParenToken), [isNonJsxSameLineTokenContext, isAfterCodeBlockContext], RuleAction.Space),
+ // Special case for (}, else) and (}, while) since else & while tokens are not part of the tree which makes SpaceAfterCloseBrace rule not applied
+ // Also should not apply to })
+ rule("SpaceBetweenCloseBraceAndElse", SyntaxKind.CloseBraceToken, SyntaxKind.ElseKeyword, [isNonJsxSameLineTokenContext], RuleAction.Space),
+ rule("SpaceBetweenCloseBraceAndWhile", SyntaxKind.CloseBraceToken, SyntaxKind.WhileKeyword, [isNonJsxSameLineTokenContext], RuleAction.Space),
+ rule("NoSpaceBetweenEmptyBraceBrackets", SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, [isNonJsxSameLineTokenContext, isObjectContext], RuleAction.Delete),
- this.NoSpaceBetweenReturnAndSemicolon = new Rule(RuleDescriptor.create1(SyntaxKind.ReturnKeyword, SyntaxKind.SemicolonToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
+ rule("NoSpaceBetweenFunctionKeywordAndStar", SyntaxKind.FunctionKeyword, SyntaxKind.AsteriskToken, [isFunctionDeclarationOrFunctionExpressionContext], RuleAction.Delete),
+ rule("SpaceAfterStarInGeneratorDeclaration", SyntaxKind.AsteriskToken, [SyntaxKind.Identifier, SyntaxKind.OpenParenToken], [isFunctionDeclarationOrFunctionExpressionContext], RuleAction.Space),
- // Add a space between statements. All keywords except (do,else,case) has open/close parens after them.
- // So, we have a rule to add a space for [),Any], [do,Any], [else,Any], and [case,Any]
- this.SpaceBetweenStatements = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.CloseParenToken, SyntaxKind.DoKeyword, SyntaxKind.ElseKeyword, SyntaxKind.CaseKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNonJsxElementContext, Rules.IsNotForContext), RuleAction.Space));
-
- // This low-pri rule takes care of "try {" and "finally {" in case the rule SpaceBeforeOpenBraceInControl didn't execute on FormatOnEnter.
- this.SpaceAfterTryFinally = new Rule(RuleDescriptor.create2(Shared.TokenRange.FromTokens([SyntaxKind.TryKeyword, SyntaxKind.FinallyKeyword]), SyntaxKind.OpenBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
+ rule("SpaceAfterFunctionInFuncDecl", SyntaxKind.FunctionKeyword, anyToken, [isFunctionDeclContext], RuleAction.Space),
+ // Insert new line after { and before } in multi-line contexts.
+ rule("NewLineAfterOpenBraceInBlockContext", SyntaxKind.OpenBraceToken, anyToken, [isMultilineBlockContext], RuleAction.NewLine),
+ // For get/set members, we check for (identifier,identifier) since get/set don't have tokens and they are represented as just an identifier token.
+ // Though, we do extra check on the context to make sure we are dealing with get/set node. Example:
// get x() {}
// set x(val) {}
- this.SpaceAfterGetSetInMember = new Rule(RuleDescriptor.create2(Shared.TokenRange.FromTokens([SyntaxKind.GetKeyword, SyntaxKind.SetKeyword]), SyntaxKind.Identifier), RuleOperation.create2(new RuleOperationContext(Rules.IsFunctionDeclContext), RuleAction.Space));
+ rule("SpaceAfterGetSetInMember", [SyntaxKind.GetKeyword, SyntaxKind.SetKeyword], SyntaxKind.Identifier, [isFunctionDeclContext], RuleAction.Space),
+
+ rule("NoSpaceBetweenYieldKeywordAndStar", SyntaxKind.YieldKeyword, SyntaxKind.AsteriskToken, [isNonJsxSameLineTokenContext, isYieldOrYieldStarWithOperand], RuleAction.Delete),
+ rule("SpaceBetweenYieldOrYieldStarAndOperand", [SyntaxKind.YieldKeyword, SyntaxKind.AsteriskToken], anyToken, [isNonJsxSameLineTokenContext, isYieldOrYieldStarWithOperand], RuleAction.Space),
+
+ rule("NoSpaceBetweenReturnAndSemicolon", SyntaxKind.ReturnKeyword, SyntaxKind.SemicolonToken, [isNonJsxSameLineTokenContext], RuleAction.Delete),
+ rule("SpaceAfterCertainKeywords", [SyntaxKind.VarKeyword, SyntaxKind.ThrowKeyword, SyntaxKind.NewKeyword, SyntaxKind.DeleteKeyword, SyntaxKind.ReturnKeyword, SyntaxKind.TypeOfKeyword, SyntaxKind.AwaitKeyword], anyToken, [isNonJsxSameLineTokenContext], RuleAction.Space),
+ rule("SpaceAfterLetConstInVariableDeclaration", [SyntaxKind.LetKeyword, SyntaxKind.ConstKeyword], anyToken, [isNonJsxSameLineTokenContext, isStartOfVariableDeclarationList], RuleAction.Space),
+ rule("NoSpaceBeforeOpenParenInFuncCall", anyToken, SyntaxKind.OpenParenToken, [isNonJsxSameLineTokenContext, isFunctionCallOrNewContext, isPreviousTokenNotComma], RuleAction.Delete),
// Special case for binary operators (that are keywords). For these we have to add a space and shouldn't follow any user options.
- this.SpaceBeforeBinaryKeywordOperator = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.BinaryKeywordOperators), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), RuleAction.Space));
- this.SpaceAfterBinaryKeywordOperator = new Rule(RuleDescriptor.create4(Shared.TokenRange.BinaryKeywordOperators, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), RuleAction.Space));
+ rule("SpaceBeforeBinaryKeywordOperator", anyToken, binaryKeywordOperators, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Space),
+ rule("SpaceAfterBinaryKeywordOperator", binaryKeywordOperators, anyToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Space),
- // TypeScript-specific higher priority rules
-
- this.SpaceAfterConstructor = new Rule(RuleDescriptor.create1(SyntaxKind.ConstructorKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterConstructor"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
- this.NoSpaceAfterConstructor = new Rule(RuleDescriptor.create1(SyntaxKind.ConstructorKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterConstructor"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
-
- // Use of module as a function call. e.g.: import m2 = module("m2");
- this.NoSpaceAfterModuleImport = new Rule(RuleDescriptor.create2(Shared.TokenRange.FromTokens([SyntaxKind.ModuleKeyword, SyntaxKind.RequireKeyword]), SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
-
- // Add a space around certain TypeScript keywords
- this.SpaceAfterCertainTypeScriptKeywords = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.AbstractKeyword, SyntaxKind.ClassKeyword, SyntaxKind.DeclareKeyword, SyntaxKind.DefaultKeyword, SyntaxKind.EnumKeyword, SyntaxKind.ExportKeyword, SyntaxKind.ExtendsKeyword, SyntaxKind.GetKeyword, SyntaxKind.ImplementsKeyword, SyntaxKind.ImportKeyword, SyntaxKind.InterfaceKeyword, SyntaxKind.ModuleKeyword, SyntaxKind.NamespaceKeyword, SyntaxKind.PrivateKeyword, SyntaxKind.PublicKeyword, SyntaxKind.ProtectedKeyword, SyntaxKind.ReadonlyKeyword, SyntaxKind.SetKeyword, SyntaxKind.StaticKeyword, SyntaxKind.TypeKeyword, SyntaxKind.FromKeyword, SyntaxKind.KeyOfKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
- this.SpaceBeforeCertainTypeScriptKeywords = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.FromTokens([SyntaxKind.ExtendsKeyword, SyntaxKind.ImplementsKeyword, SyntaxKind.FromKeyword])), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
-
- // Treat string literals in module names as identifiers, and add a space between the literal and the opening Brace braces, e.g.: module "m2" {
- this.SpaceAfterModuleName = new Rule(RuleDescriptor.create1(SyntaxKind.StringLiteral, SyntaxKind.OpenBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsModuleDeclContext), RuleAction.Space));
-
- // Lambda expressions
- this.SpaceBeforeArrow = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.EqualsGreaterThanToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
- this.SpaceAfterArrow = new Rule(RuleDescriptor.create3(SyntaxKind.EqualsGreaterThanToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
-
- // Optional parameters and let args
- this.NoSpaceAfterEllipsis = new Rule(RuleDescriptor.create1(SyntaxKind.DotDotDotToken, SyntaxKind.Identifier), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
- this.NoSpaceAfterOptionalParameters = new Rule(RuleDescriptor.create3(SyntaxKind.QuestionToken, Shared.TokenRange.FromTokens([SyntaxKind.CloseParenToken, SyntaxKind.CommaToken])), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNotBinaryOpContext), RuleAction.Delete));
-
- // generics and type assertions
- this.NoSpaceBeforeOpenAngularBracket = new Rule(RuleDescriptor.create2(Shared.TokenRange.TypeNames, SyntaxKind.LessThanToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeArgumentOrParameterOrAssertionContext), RuleAction.Delete));
- this.NoSpaceBetweenCloseParenAndAngularBracket = new Rule(RuleDescriptor.create1(SyntaxKind.CloseParenToken, SyntaxKind.LessThanToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeArgumentOrParameterOrAssertionContext), RuleAction.Delete));
- this.NoSpaceAfterOpenAngularBracket = new Rule(RuleDescriptor.create3(SyntaxKind.LessThanToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeArgumentOrParameterOrAssertionContext), RuleAction.Delete));
- this.NoSpaceBeforeCloseAngularBracket = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.GreaterThanToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeArgumentOrParameterOrAssertionContext), RuleAction.Delete));
- this.NoSpaceAfterCloseAngularBracket = new Rule(RuleDescriptor.create3(SyntaxKind.GreaterThanToken, Shared.TokenRange.FromTokens([SyntaxKind.OpenParenToken, SyntaxKind.OpenBracketToken, SyntaxKind.GreaterThanToken, SyntaxKind.CommaToken])), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeArgumentOrParameterOrAssertionContext), RuleAction.Delete));
-
- // Remove spaces in empty interface literals. e.g.: x: {}
- this.NoSpaceBetweenEmptyInterfaceBraceBrackets = new Rule(RuleDescriptor.create1(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsObjectTypeContext), RuleAction.Delete));
-
- // decorators
- this.SpaceBeforeAt = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.AtToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
- this.NoSpaceAfterAt = new Rule(RuleDescriptor.create3(SyntaxKind.AtToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
- this.SpaceAfterDecorator = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.FromTokens([SyntaxKind.AbstractKeyword, SyntaxKind.Identifier, SyntaxKind.ExportKeyword, SyntaxKind.DefaultKeyword, SyntaxKind.ClassKeyword, SyntaxKind.StaticKeyword, SyntaxKind.PublicKeyword, SyntaxKind.PrivateKeyword, SyntaxKind.ProtectedKeyword, SyntaxKind.GetKeyword, SyntaxKind.SetKeyword, SyntaxKind.OpenBracketToken, SyntaxKind.AsteriskToken])), RuleOperation.create2(new RuleOperationContext(Rules.IsEndOfDecoratorContextOnSameLine), RuleAction.Space));
-
- this.NoSpaceBetweenFunctionKeywordAndStar = new Rule(RuleDescriptor.create1(SyntaxKind.FunctionKeyword, SyntaxKind.AsteriskToken), RuleOperation.create2(new RuleOperationContext(Rules.IsFunctionDeclarationOrFunctionExpressionContext), RuleAction.Delete));
- this.SpaceAfterStarInGeneratorDeclaration = new Rule(RuleDescriptor.create3(SyntaxKind.AsteriskToken, Shared.TokenRange.FromTokens([SyntaxKind.Identifier, SyntaxKind.OpenParenToken])), RuleOperation.create2(new RuleOperationContext(Rules.IsFunctionDeclarationOrFunctionExpressionContext), RuleAction.Space));
- this.NoSpaceBetweenYieldKeywordAndStar = new Rule(RuleDescriptor.create1(SyntaxKind.YieldKeyword, SyntaxKind.AsteriskToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsYieldOrYieldStarWithOperand), RuleAction.Delete));
- this.SpaceBetweenYieldOrYieldStarAndOperand = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.YieldKeyword, SyntaxKind.AsteriskToken]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsYieldOrYieldStarWithOperand), RuleAction.Space));
+ rule("SpaceAfterVoidOperator", SyntaxKind.VoidKeyword, anyToken, [isNonJsxSameLineTokenContext, isVoidOpContext], RuleAction.Space),
// Async-await
- this.SpaceBetweenAsyncAndOpenParen = new Rule(RuleDescriptor.create1(SyntaxKind.AsyncKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsArrowFunctionContext, Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
- this.SpaceBetweenAsyncAndFunctionKeyword = new Rule(RuleDescriptor.create1(SyntaxKind.AsyncKeyword, SyntaxKind.FunctionKeyword), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
+ rule("SpaceBetweenAsyncAndOpenParen", SyntaxKind.AsyncKeyword, SyntaxKind.OpenParenToken, [isArrowFunctionContext, isNonJsxSameLineTokenContext], RuleAction.Space),
+ rule("SpaceBetweenAsyncAndFunctionKeyword", SyntaxKind.AsyncKeyword, SyntaxKind.FunctionKeyword, [isNonJsxSameLineTokenContext], RuleAction.Space),
// template string
- this.NoSpaceBetweenTagAndTemplateString = new Rule(RuleDescriptor.create3(SyntaxKind.Identifier, Shared.TokenRange.FromTokens([SyntaxKind.NoSubstitutionTemplateLiteral, SyntaxKind.TemplateHead])), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
+ rule("NoSpaceBetweenTagAndTemplateString", SyntaxKind.Identifier, [SyntaxKind.NoSubstitutionTemplateLiteral, SyntaxKind.TemplateHead], [isNonJsxSameLineTokenContext], RuleAction.Delete),
- // jsx opening element
- this.SpaceBeforeJsxAttribute = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.Identifier), RuleOperation.create2(new RuleOperationContext(Rules.IsNextTokenParentJsxAttribute, Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
- this.SpaceBeforeSlashInJsxOpeningElement = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.SlashToken), RuleOperation.create2(new RuleOperationContext(Rules.IsJsxSelfClosingElementContext, Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
- this.NoSpaceBeforeGreaterThanTokenInJsxOpeningElement = new Rule(RuleDescriptor.create1(SyntaxKind.SlashToken, SyntaxKind.GreaterThanToken), RuleOperation.create2(new RuleOperationContext(Rules.IsJsxSelfClosingElementContext, Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
- this.NoSpaceBeforeEqualInJsxAttribute = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.EqualsToken), RuleOperation.create2(new RuleOperationContext(Rules.IsJsxAttributeContext, Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
- this.NoSpaceAfterEqualInJsxAttribute = new Rule(RuleDescriptor.create3(SyntaxKind.EqualsToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsJsxAttributeContext, Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
+ // JSX opening elements
+ rule("SpaceBeforeJsxAttribute", anyToken, SyntaxKind.Identifier, [isNextTokenParentJsxAttribute, isNonJsxSameLineTokenContext], RuleAction.Space),
+ rule("SpaceBeforeSlashInJsxOpeningElement", anyToken, SyntaxKind.SlashToken, [isJsxSelfClosingElementContext, isNonJsxSameLineTokenContext], RuleAction.Space),
+ rule("NoSpaceBeforeGreaterThanTokenInJsxOpeningElement", SyntaxKind.SlashToken, SyntaxKind.GreaterThanToken, [isJsxSelfClosingElementContext, isNonJsxSameLineTokenContext], RuleAction.Delete),
+ rule("NoSpaceBeforeEqualInJsxAttribute", anyToken, SyntaxKind.EqualsToken, [isJsxAttributeContext, isNonJsxSameLineTokenContext], RuleAction.Delete),
+ rule("NoSpaceAfterEqualInJsxAttribute", SyntaxKind.EqualsToken, anyToken, [isJsxAttributeContext, isNonJsxSameLineTokenContext], RuleAction.Delete),
- // No space before non-null assertion operator
- this.NoSpaceBeforeNonNullAssertionOperator = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.ExclamationToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNonNullAssertionContext), RuleAction.Delete));
+ // TypeScript-specific rules
+ // Use of module as a function call. e.g.: import m2 = module("m2");
+ rule("NoSpaceAfterModuleImport", [SyntaxKind.ModuleKeyword, SyntaxKind.RequireKeyword], SyntaxKind.OpenParenToken, [isNonJsxSameLineTokenContext], RuleAction.Delete),
+ // Add a space around certain TypeScript keywords
+ rule(
+ "SpaceAfterCertainTypeScriptKeywords",
+ [
+ SyntaxKind.AbstractKeyword,
+ SyntaxKind.ClassKeyword,
+ SyntaxKind.DeclareKeyword,
+ SyntaxKind.DefaultKeyword,
+ SyntaxKind.EnumKeyword,
+ SyntaxKind.ExportKeyword,
+ SyntaxKind.ExtendsKeyword,
+ SyntaxKind.GetKeyword,
+ SyntaxKind.ImplementsKeyword,
+ SyntaxKind.ImportKeyword,
+ SyntaxKind.InterfaceKeyword,
+ SyntaxKind.ModuleKeyword,
+ SyntaxKind.NamespaceKeyword,
+ SyntaxKind.PrivateKeyword,
+ SyntaxKind.PublicKeyword,
+ SyntaxKind.ProtectedKeyword,
+ SyntaxKind.ReadonlyKeyword,
+ SyntaxKind.SetKeyword,
+ SyntaxKind.StaticKeyword,
+ SyntaxKind.TypeKeyword,
+ SyntaxKind.FromKeyword,
+ SyntaxKind.KeyOfKeyword,
+ ],
+ anyToken,
+ [isNonJsxSameLineTokenContext],
+ RuleAction.Space),
+ rule(
+ "SpaceBeforeCertainTypeScriptKeywords",
+ anyToken,
+ [SyntaxKind.ExtendsKeyword, SyntaxKind.ImplementsKeyword, SyntaxKind.FromKeyword],
+ [isNonJsxSameLineTokenContext],
+ RuleAction.Space),
+ // Treat string literals in module names as identifiers, and add a space between the literal and the opening Brace braces, e.g.: module "m2" {
+ rule("SpaceAfterModuleName", SyntaxKind.StringLiteral, SyntaxKind.OpenBraceToken, [isModuleDeclContext], RuleAction.Space),
- ///
- /// Rules controlled by user options
- ///
+ // Lambda expressions
+ rule("SpaceBeforeArrow", anyToken, SyntaxKind.EqualsGreaterThanToken, [isNonJsxSameLineTokenContext], RuleAction.Space),
+ rule("SpaceAfterArrow", SyntaxKind.EqualsGreaterThanToken, anyToken, [isNonJsxSameLineTokenContext], RuleAction.Space),
- // Insert space after comma delimiter
- this.SpaceAfterComma = new Rule(RuleDescriptor.create3(SyntaxKind.CommaToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterCommaDelimiter"), Rules.IsNonJsxSameLineTokenContext, Rules.IsNonJsxElementContext, Rules.IsNextTokenNotCloseBracket), RuleAction.Space));
- this.NoSpaceAfterComma = new Rule(RuleDescriptor.create3(SyntaxKind.CommaToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterCommaDelimiter"), Rules.IsNonJsxSameLineTokenContext, Rules.IsNonJsxElementContext), RuleAction.Delete));
+ // Optional parameters and let args
+ rule("NoSpaceAfterEllipsis", SyntaxKind.DotDotDotToken, SyntaxKind.Identifier, [isNonJsxSameLineTokenContext], RuleAction.Delete),
+ rule("NoSpaceAfterOptionalParameters", SyntaxKind.QuestionToken, [SyntaxKind.CloseParenToken, SyntaxKind.CommaToken], [isNonJsxSameLineTokenContext, isNotBinaryOpContext], RuleAction.Delete),
- // Insert space before and after binary operators
- this.SpaceBeforeBinaryOperator = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.BinaryOperators), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceBeforeAndAfterBinaryOperators"), Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), RuleAction.Space));
- this.SpaceAfterBinaryOperator = new Rule(RuleDescriptor.create4(Shared.TokenRange.BinaryOperators, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceBeforeAndAfterBinaryOperators"), Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), RuleAction.Space));
- this.NoSpaceBeforeBinaryOperator = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.BinaryOperators), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceBeforeAndAfterBinaryOperators"), Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), RuleAction.Delete));
- this.NoSpaceAfterBinaryOperator = new Rule(RuleDescriptor.create4(Shared.TokenRange.BinaryOperators, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceBeforeAndAfterBinaryOperators"), Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), RuleAction.Delete));
+ // Remove spaces in empty interface literals. e.g.: x: {}
+ rule("NoSpaceBetweenEmptyInterfaceBraceBrackets", SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, [isNonJsxSameLineTokenContext, isObjectTypeContext], RuleAction.Delete),
+
+ // generics and type assertions
+ rule("NoSpaceBeforeOpenAngularBracket", typeNames, SyntaxKind.LessThanToken, [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext], RuleAction.Delete),
+ rule("NoSpaceBetweenCloseParenAndAngularBracket", SyntaxKind.CloseParenToken, SyntaxKind.LessThanToken, [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext], RuleAction.Delete),
+ rule("NoSpaceAfterOpenAngularBracket", SyntaxKind.LessThanToken, anyToken, [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext], RuleAction.Delete),
+ rule("NoSpaceBeforeCloseAngularBracket", anyToken, SyntaxKind.GreaterThanToken, [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext], RuleAction.Delete),
+ rule("NoSpaceAfterCloseAngularBracket",
+ SyntaxKind.GreaterThanToken,
+ [SyntaxKind.OpenParenToken, SyntaxKind.OpenBracketToken, SyntaxKind.GreaterThanToken, SyntaxKind.CommaToken],
+ [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext],
+ RuleAction.Delete),
+
+ // decorators
+ rule("SpaceBeforeAt", anyToken, SyntaxKind.AtToken, [isNonJsxSameLineTokenContext], RuleAction.Space),
+ rule("NoSpaceAfterAt", SyntaxKind.AtToken, anyToken, [isNonJsxSameLineTokenContext], RuleAction.Delete),
+ // Insert space after @ in decorator
+ rule("SpaceAfterDecorator",
+ anyToken,
+ [
+ SyntaxKind.AbstractKeyword,
+ SyntaxKind.Identifier,
+ SyntaxKind.ExportKeyword,
+ SyntaxKind.DefaultKeyword,
+ SyntaxKind.ClassKeyword,
+ SyntaxKind.StaticKeyword,
+ SyntaxKind.PublicKeyword,
+ SyntaxKind.PrivateKeyword,
+ SyntaxKind.ProtectedKeyword,
+ SyntaxKind.GetKeyword,
+ SyntaxKind.SetKeyword,
+ SyntaxKind.OpenBracketToken,
+ SyntaxKind.AsteriskToken,
+ ],
+ [isEndOfDecoratorContextOnSameLine],
+ RuleAction.Space),
+
+ rule("NoSpaceBeforeNonNullAssertionOperator", anyToken, SyntaxKind.ExclamationToken, [isNonJsxSameLineTokenContext, isNonNullAssertionContext], RuleAction.Delete),
+ rule("NoSpaceAfterNewKeywordOnConstructorSignature", SyntaxKind.NewKeyword, SyntaxKind.OpenParenToken, [isNonJsxSameLineTokenContext, isConstructorSignatureContext], RuleAction.Delete),
+ ];
+
+ // These rules are applied after high priority
+ const userConfigurableRules = [
+ // Treat constructor as an identifier in a function declaration, and remove spaces between constructor and following left parentheses
+ rule("SpaceAfterConstructor", SyntaxKind.ConstructorKeyword, SyntaxKind.OpenParenToken, [isOptionEnabled("insertSpaceAfterConstructor"), isNonJsxSameLineTokenContext], RuleAction.Space),
+ rule("NoSpaceAfterConstructor", SyntaxKind.ConstructorKeyword, SyntaxKind.OpenParenToken, [isOptionDisabledOrUndefined("insertSpaceAfterConstructor"), isNonJsxSameLineTokenContext], RuleAction.Delete),
+
+ rule("SpaceAfterComma", SyntaxKind.CommaToken, anyToken, [isOptionEnabled("insertSpaceAfterCommaDelimiter"), isNonJsxSameLineTokenContext, isNonJsxElementContext, isNextTokenNotCloseBracket], RuleAction.Space),
+ rule("NoSpaceAfterComma", SyntaxKind.CommaToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterCommaDelimiter"), isNonJsxSameLineTokenContext, isNonJsxElementContext], RuleAction.Delete),
+
+ // Insert space after function keyword for anonymous functions
+ rule("SpaceAfterAnonymousFunctionKeyword", SyntaxKind.FunctionKeyword, SyntaxKind.OpenParenToken, [isOptionEnabled("insertSpaceAfterFunctionKeywordForAnonymousFunctions"), isFunctionDeclContext], RuleAction.Space),
+ rule("NoSpaceAfterAnonymousFunctionKeyword", SyntaxKind.FunctionKeyword, SyntaxKind.OpenParenToken, [isOptionDisabledOrUndefined("insertSpaceAfterFunctionKeywordForAnonymousFunctions"), isFunctionDeclContext], RuleAction.Delete),
// Insert space after keywords in control flow statements
- this.SpaceAfterKeywordInControl = new Rule(RuleDescriptor.create2(Shared.TokenRange.Keywords, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterKeywordsInControlFlowStatements"), Rules.IsControlDeclContext), RuleAction.Space));
- this.NoSpaceAfterKeywordInControl = new Rule(RuleDescriptor.create2(Shared.TokenRange.Keywords, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterKeywordsInControlFlowStatements"), Rules.IsControlDeclContext), RuleAction.Delete));
+ rule("SpaceAfterKeywordInControl", keywords, SyntaxKind.OpenParenToken, [isOptionEnabled("insertSpaceAfterKeywordsInControlFlowStatements"), isControlDeclContext], RuleAction.Space),
+ rule("NoSpaceAfterKeywordInControl", keywords, SyntaxKind.OpenParenToken, [isOptionDisabledOrUndefined("insertSpaceAfterKeywordsInControlFlowStatements"), isControlDeclContext], RuleAction.Delete),
+
+ // Insert space after opening and before closing nonempty parenthesis
+ rule("SpaceAfterOpenParen", SyntaxKind.OpenParenToken, anyToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], RuleAction.Space),
+ rule("SpaceBeforeCloseParen", anyToken, SyntaxKind.CloseParenToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], RuleAction.Space),
+ rule("SpaceBetweenOpenParens", SyntaxKind.OpenParenToken, SyntaxKind.OpenParenToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], RuleAction.Space),
+ rule("NoSpaceBetweenParens", SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, [isNonJsxSameLineTokenContext], RuleAction.Delete),
+ rule("NoSpaceAfterOpenParen", SyntaxKind.OpenParenToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], RuleAction.Delete),
+ rule("NoSpaceBeforeCloseParen", anyToken, SyntaxKind.CloseParenToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], RuleAction.Delete),
+
+ // Insert space after opening and before closing nonempty brackets
+ rule("SpaceAfterOpenBracket", SyntaxKind.OpenBracketToken, anyToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), isNonJsxSameLineTokenContext], RuleAction.Space),
+ rule("SpaceBeforeCloseBracket", anyToken, SyntaxKind.CloseBracketToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), isNonJsxSameLineTokenContext], RuleAction.Space),
+ rule("NoSpaceBetweenBrackets", SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken, [isNonJsxSameLineTokenContext], RuleAction.Delete),
+ rule("NoSpaceAfterOpenBracket", SyntaxKind.OpenBracketToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), isNonJsxSameLineTokenContext], RuleAction.Delete),
+ rule("NoSpaceBeforeCloseBracket", anyToken, SyntaxKind.CloseBracketToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), isNonJsxSameLineTokenContext], RuleAction.Delete),
+
+ // Insert a space after { and before } in single-line contexts, but remove space from empty object literals {}.
+ rule("SpaceAfterOpenBrace", SyntaxKind.OpenBraceToken, anyToken, [isOptionEnabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), isBraceWrappedContext], RuleAction.Space),
+ rule("SpaceBeforeCloseBrace", anyToken, SyntaxKind.CloseBraceToken, [isOptionEnabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), isBraceWrappedContext], RuleAction.Space),
+ rule("NoSpaceBetweenEmptyBraceBrackets", SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, [isNonJsxSameLineTokenContext, isObjectContext], RuleAction.Delete),
+ rule("NoSpaceAfterOpenBrace", SyntaxKind.OpenBraceToken, anyToken, [isOptionDisabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), isNonJsxSameLineTokenContext], RuleAction.Delete),
+ rule("NoSpaceBeforeCloseBrace", anyToken, SyntaxKind.CloseBraceToken, [isOptionDisabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), isNonJsxSameLineTokenContext], RuleAction.Delete),
+
+ // Insert space after opening and before closing template string braces
+ rule("SpaceAfterTemplateHeadAndMiddle", [SyntaxKind.TemplateHead, SyntaxKind.TemplateMiddle], anyToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), isNonJsxSameLineTokenContext], RuleAction.Space),
+ rule("SpaceBeforeTemplateMiddleAndTail", anyToken, [SyntaxKind.TemplateMiddle, SyntaxKind.TemplateTail], [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), isNonJsxSameLineTokenContext], RuleAction.Space),
+ rule("NoSpaceAfterTemplateHeadAndMiddle", [SyntaxKind.TemplateHead, SyntaxKind.TemplateMiddle], anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), isNonJsxSameLineTokenContext], RuleAction.Delete),
+ rule("NoSpaceBeforeTemplateMiddleAndTail", anyToken, [SyntaxKind.TemplateMiddle, SyntaxKind.TemplateTail], [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), isNonJsxSameLineTokenContext], RuleAction.Delete),
+
+ // No space after { and before } in JSX expression
+ rule("SpaceAfterOpenBraceInJsxExpression", SyntaxKind.OpenBraceToken, anyToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), isNonJsxSameLineTokenContext, isJsxExpressionContext], RuleAction.Space),
+ rule("SpaceBeforeCloseBraceInJsxExpression", anyToken, SyntaxKind.CloseBraceToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), isNonJsxSameLineTokenContext, isJsxExpressionContext], RuleAction.Space),
+ rule("NoSpaceAfterOpenBraceInJsxExpression", SyntaxKind.OpenBraceToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), isNonJsxSameLineTokenContext, isJsxExpressionContext], RuleAction.Delete),
+ rule("NoSpaceBeforeCloseBraceInJsxExpression", anyToken, SyntaxKind.CloseBraceToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), isNonJsxSameLineTokenContext, isJsxExpressionContext], RuleAction.Delete),
+
+ // Insert space after semicolon in for statement
+ rule("SpaceAfterSemicolonInFor", SyntaxKind.SemicolonToken, anyToken, [isOptionEnabled("insertSpaceAfterSemicolonInForStatements"), isNonJsxSameLineTokenContext, isForContext], RuleAction.Space),
+ rule("NoSpaceAfterSemicolonInFor", SyntaxKind.SemicolonToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterSemicolonInForStatements"), isNonJsxSameLineTokenContext, isForContext], RuleAction.Delete),
+
+ // Insert space before and after binary operators
+ rule("SpaceBeforeBinaryOperator", anyToken, binaryOperators, [isOptionEnabled("insertSpaceBeforeAndAfterBinaryOperators"), isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Space),
+ rule("SpaceAfterBinaryOperator", binaryOperators, anyToken, [isOptionEnabled("insertSpaceBeforeAndAfterBinaryOperators"), isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Space),
+ rule("NoSpaceBeforeBinaryOperator", anyToken, binaryOperators, [isOptionDisabledOrUndefined("insertSpaceBeforeAndAfterBinaryOperators"), isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Delete),
+ rule("NoSpaceAfterBinaryOperator", binaryOperators, anyToken, [isOptionDisabledOrUndefined("insertSpaceBeforeAndAfterBinaryOperators"), isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Delete),
+
+ rule("SpaceBeforeOpenParenInFuncDecl", anyToken, SyntaxKind.OpenParenToken, [isOptionEnabled("insertSpaceBeforeFunctionParenthesis"), isNonJsxSameLineTokenContext, isFunctionDeclContext], RuleAction.Space),
+ rule("NoSpaceBeforeOpenParenInFuncDecl", anyToken, SyntaxKind.OpenParenToken, [isOptionDisabledOrUndefined("insertSpaceBeforeFunctionParenthesis"), isNonJsxSameLineTokenContext, isFunctionDeclContext], RuleAction.Delete),
+
+ // Open Brace braces after control block
+ rule("NewLineBeforeOpenBraceInControl", controlOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken, [isOptionEnabled("placeOpenBraceOnNewLineForControlBlocks"), isControlDeclContext, isBeforeMultilineBlockContext], RuleAction.NewLine, RuleFlags.CanDeleteNewLines),
// Open Brace braces after function
// TypeScript: Function can have return types, which can be made of tons of different token kinds
- this.NewLineBeforeOpenBraceInFunction = new Rule(RuleDescriptor.create2(this.FunctionOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("placeOpenBraceOnNewLineForFunctions"), Rules.IsFunctionDeclContext, Rules.IsBeforeMultilineBlockContext), RuleAction.NewLine), RuleFlags.CanDeleteNewLines);
-
+ rule("NewLineBeforeOpenBraceInFunction", functionOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken, [isOptionEnabled("placeOpenBraceOnNewLineForFunctions"), isFunctionDeclContext, isBeforeMultilineBlockContext], RuleAction.NewLine, RuleFlags.CanDeleteNewLines),
// Open Brace braces after TypeScript module/class/interface
- this.NewLineBeforeOpenBraceInTypeScriptDeclWithBlock = new Rule(RuleDescriptor.create2(this.TypeScriptOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("placeOpenBraceOnNewLineForFunctions"), Rules.IsTypeScriptDeclWithBlockContext, Rules.IsBeforeMultilineBlockContext), RuleAction.NewLine), RuleFlags.CanDeleteNewLines);
+ rule("NewLineBeforeOpenBraceInTypeScriptDeclWithBlock", typeScriptOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken, [isOptionEnabled("placeOpenBraceOnNewLineForFunctions"), isTypeScriptDeclWithBlockContext, isBeforeMultilineBlockContext], RuleAction.NewLine, RuleFlags.CanDeleteNewLines),
- // Open Brace braces after control block
- this.NewLineBeforeOpenBraceInControl = new Rule(RuleDescriptor.create2(this.ControlOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("placeOpenBraceOnNewLineForControlBlocks"), Rules.IsControlDeclContext, Rules.IsBeforeMultilineBlockContext), RuleAction.NewLine), RuleFlags.CanDeleteNewLines);
+ rule("SpaceAfterTypeAssertion", SyntaxKind.GreaterThanToken, anyToken, [isOptionEnabled("insertSpaceAfterTypeAssertion"), isNonJsxSameLineTokenContext, isTypeAssertionContext], RuleAction.Space),
+ rule("NoSpaceAfterTypeAssertion", SyntaxKind.GreaterThanToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterTypeAssertion"), isNonJsxSameLineTokenContext, isTypeAssertionContext], RuleAction.Delete),
+ ];
- // Insert space after semicolon in for statement
- this.SpaceAfterSemicolonInFor = new Rule(RuleDescriptor.create3(SyntaxKind.SemicolonToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterSemicolonInForStatements"), Rules.IsNonJsxSameLineTokenContext, Rules.IsForContext), RuleAction.Space));
- this.NoSpaceAfterSemicolonInFor = new Rule(RuleDescriptor.create3(SyntaxKind.SemicolonToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterSemicolonInForStatements"), Rules.IsNonJsxSameLineTokenContext, Rules.IsForContext), RuleAction.Delete));
+ // These rules are lower in priority than user-configurable
+ const lowPriorityCommonRules = [
+ // Space after keyword but not before ; or : or ?
+ rule("NoSpaceBeforeSemicolon", anyToken, SyntaxKind.SemicolonToken, [isNonJsxSameLineTokenContext], RuleAction.Delete),
- // Insert space after opening and before closing nonempty parenthesis
- this.SpaceAfterOpenParen = new Rule(RuleDescriptor.create3(SyntaxKind.OpenParenToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
- this.SpaceBeforeCloseParen = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
- this.SpaceBetweenOpenParens = new Rule(RuleDescriptor.create1(SyntaxKind.OpenParenToken, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
- this.NoSpaceBetweenParens = new Rule(RuleDescriptor.create1(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
- this.NoSpaceAfterOpenParen = new Rule(RuleDescriptor.create3(SyntaxKind.OpenParenToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
- this.NoSpaceBeforeCloseParen = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
+ rule("SpaceBeforeOpenBraceInControl", controlOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken, [isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForControlBlocks"), isControlDeclContext, isNotFormatOnEnter, isSameLineTokenOrBeforeBlockContext], RuleAction.Space, RuleFlags.CanDeleteNewLines),
+ rule("SpaceBeforeOpenBraceInFunction", functionOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken, [isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForFunctions"), isFunctionDeclContext, isBeforeBlockContext, isNotFormatOnEnter, isSameLineTokenOrBeforeBlockContext], RuleAction.Space, RuleFlags.CanDeleteNewLines),
+ rule("SpaceBeforeOpenBraceInTypeScriptDeclWithBlock", typeScriptOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken, [isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForFunctions"), isTypeScriptDeclWithBlockContext, isNotFormatOnEnter, isSameLineTokenOrBeforeBlockContext], RuleAction.Space, RuleFlags.CanDeleteNewLines),
- // Insert space after opening and before closing nonempty brackets
- this.SpaceAfterOpenBracket = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBracketToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
- this.SpaceBeforeCloseBracket = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBracketToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
- this.NoSpaceBetweenBrackets = new Rule(RuleDescriptor.create1(SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
- this.NoSpaceAfterOpenBracket = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBracketToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
- this.NoSpaceBeforeCloseBracket = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBracketToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
+ rule("NoSpaceBeforeComma", anyToken, SyntaxKind.CommaToken, [isNonJsxSameLineTokenContext], RuleAction.Delete),
+ // No space before and after indexer
+ rule("NoSpaceBeforeOpenBracket", anyTokenExcept(SyntaxKind.AsyncKeyword), SyntaxKind.OpenBracketToken, [isNonJsxSameLineTokenContext], RuleAction.Delete),
+ rule("NoSpaceAfterCloseBracket", SyntaxKind.CloseBracketToken, anyToken, [isNonJsxSameLineTokenContext, isNotBeforeBlockInFunctionDeclarationContext], RuleAction.Delete),
+ rule("SpaceAfterSemicolon", SyntaxKind.SemicolonToken, anyToken, [isNonJsxSameLineTokenContext], RuleAction.Space),
- // Insert space after opening and before closing template string braces
- this.NoSpaceAfterTemplateHeadAndMiddle = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.TemplateHead, SyntaxKind.TemplateMiddle]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
- this.SpaceAfterTemplateHeadAndMiddle = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.TemplateHead, SyntaxKind.TemplateMiddle]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
- this.NoSpaceBeforeTemplateMiddleAndTail = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.FromTokens([SyntaxKind.TemplateMiddle, SyntaxKind.TemplateTail])), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
- this.SpaceBeforeTemplateMiddleAndTail = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.FromTokens([SyntaxKind.TemplateMiddle, SyntaxKind.TemplateTail])), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
+ // Add a space between statements. All keywords except (do,else,case) has open/close parens after them.
+ // So, we have a rule to add a space for [),Any], [do,Any], [else,Any], and [case,Any]
+ rule(
+ "SpaceBetweenStatements",
+ [SyntaxKind.CloseParenToken, SyntaxKind.DoKeyword, SyntaxKind.ElseKeyword, SyntaxKind.CaseKeyword],
+ anyToken,
+ [isNonJsxSameLineTokenContext, isNonJsxElementContext, isNotForContext],
+ RuleAction.Space),
+ // This low-pri rule takes care of "try {" and "finally {" in case the rule SpaceBeforeOpenBraceInControl didn't execute on FormatOnEnter.
+ rule("SpaceAfterTryFinally", [SyntaxKind.TryKeyword, SyntaxKind.FinallyKeyword], SyntaxKind.OpenBraceToken, [isNonJsxSameLineTokenContext], RuleAction.Space),
+ ];
- // No space after { and before } in JSX expression
- this.NoSpaceAfterOpenBraceInJsxExpression = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), Rules.IsNonJsxSameLineTokenContext, Rules.IsJsxExpressionContext), RuleAction.Delete));
- this.SpaceAfterOpenBraceInJsxExpression = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), Rules.IsNonJsxSameLineTokenContext, Rules.IsJsxExpressionContext), RuleAction.Space));
- this.NoSpaceBeforeCloseBraceInJsxExpression = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), Rules.IsNonJsxSameLineTokenContext, Rules.IsJsxExpressionContext), RuleAction.Delete));
- this.SpaceBeforeCloseBraceInJsxExpression = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), Rules.IsNonJsxSameLineTokenContext, Rules.IsJsxExpressionContext), RuleAction.Space));
+ return [
+ ...highPriorityCommonRules,
+ ...userConfigurableRules,
+ ...lowPriorityCommonRules,
+ ];
+ }
- // Insert space after function keyword for anonymous functions
- this.SpaceAfterAnonymousFunctionKeyword = new Rule(RuleDescriptor.create1(SyntaxKind.FunctionKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterFunctionKeywordForAnonymousFunctions"), Rules.IsFunctionDeclContext), RuleAction.Space));
- this.NoSpaceAfterAnonymousFunctionKeyword = new Rule(RuleDescriptor.create1(SyntaxKind.FunctionKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterFunctionKeywordForAnonymousFunctions"), Rules.IsFunctionDeclContext), RuleAction.Delete));
+ function rule(
+ debugName: string,
+ left: SyntaxKind | ReadonlyArray | TokenRange,
+ right: SyntaxKind | ReadonlyArray | TokenRange,
+ context: ReadonlyArray,
+ action: RuleAction,
+ flags: RuleFlags = RuleFlags.None,
+ ): RuleSpec {
+ return { leftTokenRange: toTokenRange(left), rightTokenRange: toTokenRange(right), rule: { debugName, context, action, flags } };
+ }
- // No space after type assertion
- this.NoSpaceAfterTypeAssertion = new Rule(RuleDescriptor.create3(SyntaxKind.GreaterThanToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterTypeAssertion"), Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeAssertionContext), RuleAction.Delete));
- this.SpaceAfterTypeAssertion = new Rule(RuleDescriptor.create3(SyntaxKind.GreaterThanToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterTypeAssertion"), Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeAssertionContext), RuleAction.Space));
+ function tokenRangeFrom(tokens: ReadonlyArray): TokenRange {
+ return { tokens, isSpecific: true };
+ }
- // These rules are higher in priority than user-configurable rules.
- this.HighPriorityCommonRules = [
- this.IgnoreBeforeComment, this.IgnoreAfterLineComment,
- this.NoSpaceBeforeColon, this.SpaceAfterColon, this.NoSpaceBeforeQuestionMark, this.SpaceAfterQuestionMarkInConditionalOperator,
- this.NoSpaceAfterQuestionMark,
- this.NoSpaceBeforeDot, this.NoSpaceAfterDot,
- this.NoSpaceAfterUnaryPrefixOperator,
- this.NoSpaceAfterUnaryPreincrementOperator, this.NoSpaceAfterUnaryPredecrementOperator,
- this.NoSpaceBeforeUnaryPostincrementOperator, this.NoSpaceBeforeUnaryPostdecrementOperator,
- this.SpaceAfterPostincrementWhenFollowedByAdd,
- this.SpaceAfterAddWhenFollowedByUnaryPlus, this.SpaceAfterAddWhenFollowedByPreincrement,
- this.SpaceAfterPostdecrementWhenFollowedBySubtract,
- this.SpaceAfterSubtractWhenFollowedByUnaryMinus, this.SpaceAfterSubtractWhenFollowedByPredecrement,
- this.NoSpaceAfterCloseBrace,
- this.NewLineBeforeCloseBraceInBlockContext,
- this.SpaceAfterCloseBrace, this.SpaceBetweenCloseBraceAndElse, this.SpaceBetweenCloseBraceAndWhile, this.NoSpaceBetweenEmptyBraceBrackets,
- this.NoSpaceBetweenFunctionKeywordAndStar, this.SpaceAfterStarInGeneratorDeclaration,
- this.SpaceAfterFunctionInFuncDecl, this.NewLineAfterOpenBraceInBlockContext, this.SpaceAfterGetSetInMember,
- this.NoSpaceBetweenYieldKeywordAndStar, this.SpaceBetweenYieldOrYieldStarAndOperand,
- this.NoSpaceBetweenReturnAndSemicolon,
- this.SpaceAfterCertainKeywords,
- this.SpaceAfterLetConstInVariableDeclaration,
- this.NoSpaceBeforeOpenParenInFuncCall,
- this.SpaceBeforeBinaryKeywordOperator, this.SpaceAfterBinaryKeywordOperator,
- this.SpaceAfterVoidOperator,
- this.SpaceBetweenAsyncAndOpenParen, this.SpaceBetweenAsyncAndFunctionKeyword,
- this.NoSpaceBetweenTagAndTemplateString,
- this.SpaceBeforeJsxAttribute, this.SpaceBeforeSlashInJsxOpeningElement, this.NoSpaceBeforeGreaterThanTokenInJsxOpeningElement,
- this.NoSpaceBeforeEqualInJsxAttribute, this.NoSpaceAfterEqualInJsxAttribute,
+ function toTokenRange(arg: SyntaxKind | ReadonlyArray | TokenRange): TokenRange {
+ return typeof arg === "number" ? tokenRangeFrom([arg]) : isArray(arg) ? tokenRangeFrom(arg) : arg;
+ }
- // TypeScript-specific rules
- this.NoSpaceAfterModuleImport,
- this.SpaceAfterCertainTypeScriptKeywords, this.SpaceBeforeCertainTypeScriptKeywords,
- this.SpaceAfterModuleName,
- this.SpaceBeforeArrow, this.SpaceAfterArrow,
- this.NoSpaceAfterEllipsis,
- this.NoSpaceAfterOptionalParameters,
- this.NoSpaceBetweenEmptyInterfaceBraceBrackets,
- this.NoSpaceBeforeOpenAngularBracket,
- this.NoSpaceBetweenCloseParenAndAngularBracket,
- this.NoSpaceAfterOpenAngularBracket,
- this.NoSpaceBeforeCloseAngularBracket,
- this.NoSpaceAfterCloseAngularBracket,
- this.SpaceBeforeAt,
- this.NoSpaceAfterAt,
- this.SpaceAfterDecorator,
- this.NoSpaceBeforeNonNullAssertionOperator,
- this.NoSpaceAfterNewKeywordOnConstructorSignature
- ];
-
- // These rules are applied after high priority rules.
- this.UserConfigurableRules = [
- this.SpaceAfterConstructor, this.NoSpaceAfterConstructor,
- this.SpaceAfterComma, this.NoSpaceAfterComma,
- this.SpaceAfterAnonymousFunctionKeyword, this.NoSpaceAfterAnonymousFunctionKeyword,
- this.SpaceAfterKeywordInControl, this.NoSpaceAfterKeywordInControl,
- this.SpaceAfterOpenParen, this.SpaceBeforeCloseParen, this.SpaceBetweenOpenParens, this.NoSpaceBetweenParens, this.NoSpaceAfterOpenParen, this.NoSpaceBeforeCloseParen,
- this.SpaceAfterOpenBracket, this.SpaceBeforeCloseBracket, this.NoSpaceBetweenBrackets, this.NoSpaceAfterOpenBracket, this.NoSpaceBeforeCloseBracket,
- this.SpaceAfterOpenBrace, this.SpaceBeforeCloseBrace, this.NoSpaceBetweenEmptyBraceBrackets, this.NoSpaceAfterOpenBrace, this.NoSpaceBeforeCloseBrace,
- this.SpaceAfterTemplateHeadAndMiddle, this.SpaceBeforeTemplateMiddleAndTail, this.NoSpaceAfterTemplateHeadAndMiddle, this.NoSpaceBeforeTemplateMiddleAndTail,
- this.SpaceAfterOpenBraceInJsxExpression, this.SpaceBeforeCloseBraceInJsxExpression, this.NoSpaceAfterOpenBraceInJsxExpression, this.NoSpaceBeforeCloseBraceInJsxExpression,
- this.SpaceAfterSemicolonInFor, this.NoSpaceAfterSemicolonInFor,
- this.SpaceBeforeBinaryOperator, this.SpaceAfterBinaryOperator, this.NoSpaceBeforeBinaryOperator, this.NoSpaceAfterBinaryOperator,
- this.SpaceBeforeOpenParenInFuncDecl, this.NoSpaceBeforeOpenParenInFuncDecl,
- this.NewLineBeforeOpenBraceInControl,
- this.NewLineBeforeOpenBraceInFunction, this.NewLineBeforeOpenBraceInTypeScriptDeclWithBlock,
- this.SpaceAfterTypeAssertion, this.NoSpaceAfterTypeAssertion
- ];
-
- // These rules are lower in priority than user-configurable rules.
- this.LowPriorityCommonRules = [
- this.NoSpaceBeforeSemicolon,
- this.SpaceBeforeOpenBraceInControl, this.SpaceBeforeOpenBraceInFunction, this.SpaceBeforeOpenBraceInTypeScriptDeclWithBlock,
- this.NoSpaceBeforeComma,
- this.NoSpaceBeforeOpenBracket,
- this.NoSpaceAfterCloseBracket,
- this.SpaceAfterSemicolon,
- this.SpaceBetweenStatements, this.SpaceAfterTryFinally
- ];
-
- if (Debug.isDebugging) {
- const o: ts.MapLike = this;
- for (const name in o) {
- const rule = o[name];
- if (rule instanceof Rule) {
- rule.debugName = name;
- }
- }
+ function tokenRangeFromRange(from: SyntaxKind, to: SyntaxKind, except: ReadonlyArray = []): TokenRange {
+ const tokens: SyntaxKind[] = [];
+ for (let token = from; token <= to; token++) {
+ if (!contains(except, token)) {
+ tokens.push(token);
}
}
+ return tokenRangeFrom(tokens);
+ }
- ///
- /// Contexts
- ///
+ ///
+ /// Contexts
+ ///
- static IsOptionEnabled(optionName: keyof FormatCodeSettings): (context: FormattingContext) => boolean {
- return (context) => context.options && context.options.hasOwnProperty(optionName) && !!context.options[optionName];
- }
+ function isOptionEnabled(optionName: keyof FormatCodeSettings): (context: FormattingContext) => boolean {
+ return (context) => context.options && context.options.hasOwnProperty(optionName) && !!context.options[optionName];
+ }
- static IsOptionDisabled(optionName: keyof FormatCodeSettings): (context: FormattingContext) => boolean {
- return (context) => context.options && context.options.hasOwnProperty(optionName) && !context.options[optionName];
- }
+ function isOptionDisabled(optionName: keyof FormatCodeSettings): (context: FormattingContext) => boolean {
+ return (context) => context.options && context.options.hasOwnProperty(optionName) && !context.options[optionName];
+ }
- static IsOptionDisabledOrUndefined(optionName: keyof FormatCodeSettings): (context: FormattingContext) => boolean {
- return (context) => !context.options || !context.options.hasOwnProperty(optionName) || !context.options[optionName];
- }
+ function isOptionDisabledOrUndefined(optionName: keyof FormatCodeSettings): (context: FormattingContext) => boolean {
+ return (context) => !context.options || !context.options.hasOwnProperty(optionName) || !context.options[optionName];
+ }
- static isOptionDisabledOrUndefinedOrTokensOnSameLine(optionName: keyof FormatCodeSettings): (context: FormattingContext) => boolean {
- return (context) => !context.options || !context.options.hasOwnProperty(optionName) || !context.options[optionName] || context.TokensAreOnSameLine();
- }
+ function isOptionDisabledOrUndefinedOrTokensOnSameLine(optionName: keyof FormatCodeSettings): (context: FormattingContext) => boolean {
+ return (context) => !context.options || !context.options.hasOwnProperty(optionName) || !context.options[optionName] || context.TokensAreOnSameLine();
+ }
- static IsOptionEnabledOrUndefined(optionName: keyof FormatCodeSettings): (context: FormattingContext) => boolean {
- return (context) => !context.options || !context.options.hasOwnProperty(optionName) || !!context.options[optionName];
- }
+ function isOptionEnabledOrUndefined(optionName: keyof FormatCodeSettings): (context: FormattingContext) => boolean {
+ return (context) => !context.options || !context.options.hasOwnProperty(optionName) || !!context.options[optionName];
+ }
- static IsForContext(context: FormattingContext): boolean {
- return context.contextNode.kind === SyntaxKind.ForStatement;
- }
+ function isForContext(context: FormattingContext): boolean {
+ return context.contextNode.kind === SyntaxKind.ForStatement;
+ }
- static IsNotForContext(context: FormattingContext): boolean {
- return !Rules.IsForContext(context);
- }
+ function isNotForContext(context: FormattingContext): boolean {
+ return !isForContext(context);
+ }
- static IsBinaryOpContext(context: FormattingContext): boolean {
+ function isBinaryOpContext(context: FormattingContext): boolean {
- switch (context.contextNode.kind) {
- case SyntaxKind.BinaryExpression:
- case SyntaxKind.ConditionalExpression:
- case SyntaxKind.AsExpression:
- case SyntaxKind.ExportSpecifier:
- case SyntaxKind.ImportSpecifier:
- case SyntaxKind.TypePredicate:
- case SyntaxKind.UnionType:
- case SyntaxKind.IntersectionType:
- return true;
-
- // equals in binding elements: function foo([[x, y] = [1, 2]])
- case SyntaxKind.BindingElement:
- // equals in type X = ...
- case SyntaxKind.TypeAliasDeclaration:
- // equal in import a = module('a');
- case SyntaxKind.ImportEqualsDeclaration:
- // equal in let a = 0;
- case SyntaxKind.VariableDeclaration:
- // equal in p = 0;
- case SyntaxKind.Parameter:
- case SyntaxKind.EnumMember:
- case SyntaxKind.PropertyDeclaration:
- case SyntaxKind.PropertySignature:
- return context.currentTokenSpan.kind === SyntaxKind.EqualsToken || context.nextTokenSpan.kind === SyntaxKind.EqualsToken;
- // "in" keyword in for (let x in []) { }
- case SyntaxKind.ForInStatement:
- // "in" keyword in [P in keyof T]: T[P]
- case SyntaxKind.TypeParameter:
- return context.currentTokenSpan.kind === SyntaxKind.InKeyword || context.nextTokenSpan.kind === SyntaxKind.InKeyword;
- // Technically, "of" is not a binary operator, but format it the same way as "in"
- case SyntaxKind.ForOfStatement:
- return context.currentTokenSpan.kind === SyntaxKind.OfKeyword || context.nextTokenSpan.kind === SyntaxKind.OfKeyword;
- }
- return false;
- }
-
- static IsNotBinaryOpContext(context: FormattingContext): boolean {
- return !Rules.IsBinaryOpContext(context);
- }
-
- static IsConditionalOperatorContext(context: FormattingContext): boolean {
- return context.contextNode.kind === SyntaxKind.ConditionalExpression;
- }
-
- static IsSameLineTokenOrBeforeBlockContext(context: FormattingContext): boolean {
- return context.TokensAreOnSameLine() || Rules.IsBeforeBlockContext(context);
- }
-
- static IsBraceWrappedContext(context: FormattingContext): boolean {
- return context.contextNode.kind === SyntaxKind.ObjectBindingPattern || Rules.IsSingleLineBlockContext(context);
- }
-
- // This check is done before an open brace in a control construct, a function, or a typescript block declaration
- static IsBeforeMultilineBlockContext(context: FormattingContext): boolean {
- return Rules.IsBeforeBlockContext(context) && !(context.NextNodeAllOnSameLine() || context.NextNodeBlockIsOnOneLine());
- }
-
- static IsMultilineBlockContext(context: FormattingContext): boolean {
- return Rules.IsBlockContext(context) && !(context.ContextNodeAllOnSameLine() || context.ContextNodeBlockIsOnOneLine());
- }
-
- static IsSingleLineBlockContext(context: FormattingContext): boolean {
- return Rules.IsBlockContext(context) && (context.ContextNodeAllOnSameLine() || context.ContextNodeBlockIsOnOneLine());
- }
-
- static IsBlockContext(context: FormattingContext): boolean {
- return Rules.NodeIsBlockContext(context.contextNode);
- }
-
- static IsBeforeBlockContext(context: FormattingContext): boolean {
- return Rules.NodeIsBlockContext(context.nextTokenParent);
- }
-
- // IMPORTANT!!! This method must return true ONLY for nodes with open and close braces as immediate children
- static NodeIsBlockContext(node: Node): boolean {
- if (Rules.NodeIsTypeScriptDeclWithBlockContext(node)) {
- // This means we are in a context that looks like a block to the user, but in the grammar is actually not a node (it's a class, module, enum, object type literal, etc).
+ switch (context.contextNode.kind) {
+ case SyntaxKind.BinaryExpression:
+ case SyntaxKind.ConditionalExpression:
+ case SyntaxKind.AsExpression:
+ case SyntaxKind.ExportSpecifier:
+ case SyntaxKind.ImportSpecifier:
+ case SyntaxKind.TypePredicate:
+ case SyntaxKind.UnionType:
+ case SyntaxKind.IntersectionType:
return true;
- }
- switch (node.kind) {
- case SyntaxKind.Block:
- case SyntaxKind.CaseBlock:
- case SyntaxKind.ObjectLiteralExpression:
- case SyntaxKind.ModuleBlock:
+ // equals in binding elements: function foo([[x, y] = [1, 2]])
+ case SyntaxKind.BindingElement:
+ // equals in type X = ...
+ case SyntaxKind.TypeAliasDeclaration:
+ // equal in import a = module('a');
+ case SyntaxKind.ImportEqualsDeclaration:
+ // equal in let a = 0;
+ case SyntaxKind.VariableDeclaration:
+ // equal in p = 0;
+ case SyntaxKind.Parameter:
+ case SyntaxKind.EnumMember:
+ case SyntaxKind.PropertyDeclaration:
+ case SyntaxKind.PropertySignature:
+ return context.currentTokenSpan.kind === SyntaxKind.EqualsToken || context.nextTokenSpan.kind === SyntaxKind.EqualsToken;
+ // "in" keyword in for (let x in []) { }
+ case SyntaxKind.ForInStatement:
+ // "in" keyword in [P in keyof T]: T[P]
+ case SyntaxKind.TypeParameter:
+ return context.currentTokenSpan.kind === SyntaxKind.InKeyword || context.nextTokenSpan.kind === SyntaxKind.InKeyword;
+ // Technically, "of" is not a binary operator, but format it the same way as "in"
+ case SyntaxKind.ForOfStatement:
+ return context.currentTokenSpan.kind === SyntaxKind.OfKeyword || context.nextTokenSpan.kind === SyntaxKind.OfKeyword;
+ }
+ return false;
+ }
+
+ function isNotBinaryOpContext(context: FormattingContext): boolean {
+ return !isBinaryOpContext(context);
+ }
+
+ function isConditionalOperatorContext(context: FormattingContext): boolean {
+ return context.contextNode.kind === SyntaxKind.ConditionalExpression;
+ }
+
+ function isSameLineTokenOrBeforeBlockContext(context: FormattingContext): boolean {
+ return context.TokensAreOnSameLine() || isBeforeBlockContext(context);
+ }
+
+ function isBraceWrappedContext(context: FormattingContext): boolean {
+ return context.contextNode.kind === SyntaxKind.ObjectBindingPattern || isSingleLineBlockContext(context);
+ }
+
+ // This check is done before an open brace in a control construct, a function, or a typescript block declaration
+ function isBeforeMultilineBlockContext(context: FormattingContext): boolean {
+ return isBeforeBlockContext(context) && !(context.NextNodeAllOnSameLine() || context.NextNodeBlockIsOnOneLine());
+ }
+
+ function isMultilineBlockContext(context: FormattingContext): boolean {
+ return isBlockContext(context) && !(context.ContextNodeAllOnSameLine() || context.ContextNodeBlockIsOnOneLine());
+ }
+
+ function isSingleLineBlockContext(context: FormattingContext): boolean {
+ return isBlockContext(context) && (context.ContextNodeAllOnSameLine() || context.ContextNodeBlockIsOnOneLine());
+ }
+
+ function isBlockContext(context: FormattingContext): boolean {
+ return nodeIsBlockContext(context.contextNode);
+ }
+
+ function isBeforeBlockContext(context: FormattingContext): boolean {
+ return nodeIsBlockContext(context.nextTokenParent);
+ }
+
+ // IMPORTANT!!! This method must return true ONLY for nodes with open and close braces as immediate children
+ function nodeIsBlockContext(node: Node): boolean {
+ if (nodeIsTypeScriptDeclWithBlockContext(node)) {
+ // This means we are in a context that looks like a block to the user, but in the grammar is actually not a node (it's a class, module, enum, object type literal, etc).
+ return true;
+ }
+
+ switch (node.kind) {
+ case SyntaxKind.Block:
+ case SyntaxKind.CaseBlock:
+ case SyntaxKind.ObjectLiteralExpression:
+ case SyntaxKind.ModuleBlock:
+ return true;
+ }
+
+ return false;
+ }
+
+ function isFunctionDeclContext(context: FormattingContext): boolean {
+ switch (context.contextNode.kind) {
+ case SyntaxKind.FunctionDeclaration:
+ case SyntaxKind.MethodDeclaration:
+ case SyntaxKind.MethodSignature:
+ // case SyntaxKind.MemberFunctionDeclaration:
+ case SyntaxKind.GetAccessor:
+ case SyntaxKind.SetAccessor:
+ // case SyntaxKind.MethodSignature:
+ case SyntaxKind.CallSignature:
+ case SyntaxKind.FunctionExpression:
+ case SyntaxKind.Constructor:
+ case SyntaxKind.ArrowFunction:
+ // case SyntaxKind.ConstructorDeclaration:
+ // case SyntaxKind.SimpleArrowFunctionExpression:
+ // case SyntaxKind.ParenthesizedArrowFunctionExpression:
+ case SyntaxKind.InterfaceDeclaration: // This one is not truly a function, but for formatting purposes, it acts just like one
+ return true;
+ }
+
+ return false;
+ }
+
+ function isFunctionDeclarationOrFunctionExpressionContext(context: FormattingContext): boolean {
+ return context.contextNode.kind === SyntaxKind.FunctionDeclaration || context.contextNode.kind === SyntaxKind.FunctionExpression;
+ }
+
+ function isTypeScriptDeclWithBlockContext(context: FormattingContext): boolean {
+ return nodeIsTypeScriptDeclWithBlockContext(context.contextNode);
+ }
+
+ function nodeIsTypeScriptDeclWithBlockContext(node: Node): boolean {
+ switch (node.kind) {
+ case SyntaxKind.ClassDeclaration:
+ case SyntaxKind.ClassExpression:
+ case SyntaxKind.InterfaceDeclaration:
+ case SyntaxKind.EnumDeclaration:
+ case SyntaxKind.TypeLiteral:
+ case SyntaxKind.ModuleDeclaration:
+ case SyntaxKind.ExportDeclaration:
+ case SyntaxKind.NamedExports:
+ case SyntaxKind.ImportDeclaration:
+ case SyntaxKind.NamedImports:
+ return true;
+ }
+
+ return false;
+ }
+
+ function isAfterCodeBlockContext(context: FormattingContext): boolean {
+ switch (context.currentTokenParent.kind) {
+ case SyntaxKind.ClassDeclaration:
+ case SyntaxKind.ModuleDeclaration:
+ case SyntaxKind.EnumDeclaration:
+ case SyntaxKind.CatchClause:
+ case SyntaxKind.ModuleBlock:
+ case SyntaxKind.SwitchStatement:
+ return true;
+ case SyntaxKind.Block: {
+ const blockParent = context.currentTokenParent.parent;
+ // In a codefix scenario, we can't rely on parents being set. So just always return true.
+ if (!blockParent || blockParent.kind !== SyntaxKind.ArrowFunction && blockParent.kind !== SyntaxKind.FunctionExpression) {
return true;
- }
-
- return false;
- }
-
- static IsFunctionDeclContext(context: FormattingContext): boolean {
- switch (context.contextNode.kind) {
- case SyntaxKind.FunctionDeclaration:
- case SyntaxKind.MethodDeclaration:
- case SyntaxKind.MethodSignature:
- // case SyntaxKind.MemberFunctionDeclaration:
- case SyntaxKind.GetAccessor:
- case SyntaxKind.SetAccessor:
- // case SyntaxKind.MethodSignature:
- case SyntaxKind.CallSignature:
- case SyntaxKind.FunctionExpression:
- case SyntaxKind.Constructor:
- case SyntaxKind.ArrowFunction:
- // case SyntaxKind.ConstructorDeclaration:
- // case SyntaxKind.SimpleArrowFunctionExpression:
- // case SyntaxKind.ParenthesizedArrowFunctionExpression:
- case SyntaxKind.InterfaceDeclaration: // This one is not truly a function, but for formatting purposes, it acts just like one
- return true;
- }
-
- return false;
- }
-
- static IsFunctionDeclarationOrFunctionExpressionContext(context: FormattingContext): boolean {
- return context.contextNode.kind === SyntaxKind.FunctionDeclaration || context.contextNode.kind === SyntaxKind.FunctionExpression;
- }
-
- static IsTypeScriptDeclWithBlockContext(context: FormattingContext): boolean {
- return Rules.NodeIsTypeScriptDeclWithBlockContext(context.contextNode);
- }
-
- static NodeIsTypeScriptDeclWithBlockContext(node: Node): boolean {
- switch (node.kind) {
- case SyntaxKind.ClassDeclaration:
- case SyntaxKind.ClassExpression:
- case SyntaxKind.InterfaceDeclaration:
- case SyntaxKind.EnumDeclaration:
- case SyntaxKind.TypeLiteral:
- case SyntaxKind.ModuleDeclaration:
- case SyntaxKind.ExportDeclaration:
- case SyntaxKind.NamedExports:
- case SyntaxKind.ImportDeclaration:
- case SyntaxKind.NamedImports:
- return true;
- }
-
- return false;
- }
-
- static IsAfterCodeBlockContext(context: FormattingContext): boolean {
- switch (context.currentTokenParent.kind) {
- case SyntaxKind.ClassDeclaration:
- case SyntaxKind.ModuleDeclaration:
- case SyntaxKind.EnumDeclaration:
- case SyntaxKind.CatchClause:
- case SyntaxKind.ModuleBlock:
- case SyntaxKind.SwitchStatement:
- return true;
- case SyntaxKind.Block: {
- const blockParent = context.currentTokenParent.parent;
- // In a codefix scenario, we can't rely on parents being set. So just always return true.
- if (!blockParent || blockParent.kind !== SyntaxKind.ArrowFunction && blockParent.kind !== SyntaxKind.FunctionExpression) {
- return true;
- }
}
}
- return false;
}
+ return false;
+ }
- static IsControlDeclContext(context: FormattingContext): boolean {
- switch (context.contextNode.kind) {
- case SyntaxKind.IfStatement:
- case SyntaxKind.SwitchStatement:
- case SyntaxKind.ForStatement:
- case SyntaxKind.ForInStatement:
- case SyntaxKind.ForOfStatement:
- case SyntaxKind.WhileStatement:
- case SyntaxKind.TryStatement:
- case SyntaxKind.DoStatement:
- case SyntaxKind.WithStatement:
- // TODO
- // case SyntaxKind.ElseClause:
- case SyntaxKind.CatchClause:
- return true;
+ function isControlDeclContext(context: FormattingContext): boolean {
+ switch (context.contextNode.kind) {
+ case SyntaxKind.IfStatement:
+ case SyntaxKind.SwitchStatement:
+ case SyntaxKind.ForStatement:
+ case SyntaxKind.ForInStatement:
+ case SyntaxKind.ForOfStatement:
+ case SyntaxKind.WhileStatement:
+ case SyntaxKind.TryStatement:
+ case SyntaxKind.DoStatement:
+ case SyntaxKind.WithStatement:
+ // TODO
+ // case SyntaxKind.ElseClause:
+ case SyntaxKind.CatchClause:
+ return true;
- default:
- return false;
- }
- }
-
- static IsObjectContext(context: FormattingContext): boolean {
- return context.contextNode.kind === SyntaxKind.ObjectLiteralExpression;
- }
-
- static IsFunctionCallContext(context: FormattingContext): boolean {
- return context.contextNode.kind === SyntaxKind.CallExpression;
- }
-
- static IsNewContext(context: FormattingContext): boolean {
- return context.contextNode.kind === SyntaxKind.NewExpression;
- }
-
- static IsFunctionCallOrNewContext(context: FormattingContext): boolean {
- return Rules.IsFunctionCallContext(context) || Rules.IsNewContext(context);
- }
-
- static IsPreviousTokenNotComma(context: FormattingContext): boolean {
- return context.currentTokenSpan.kind !== SyntaxKind.CommaToken;
- }
-
- static IsNextTokenNotCloseBracket(context: FormattingContext): boolean {
- return context.nextTokenSpan.kind !== SyntaxKind.CloseBracketToken;
- }
-
- static IsArrowFunctionContext(context: FormattingContext): boolean {
- return context.contextNode.kind === SyntaxKind.ArrowFunction;
- }
-
- static IsNonJsxSameLineTokenContext(context: FormattingContext): boolean {
- return context.TokensAreOnSameLine() && context.contextNode.kind !== SyntaxKind.JsxText;
- }
-
- static IsNonJsxElementContext(context: FormattingContext): boolean {
- return context.contextNode.kind !== SyntaxKind.JsxElement;
- }
-
- static IsJsxExpressionContext(context: FormattingContext): boolean {
- return context.contextNode.kind === SyntaxKind.JsxExpression;
- }
-
- static IsNextTokenParentJsxAttribute(context: FormattingContext): boolean {
- return context.nextTokenParent.kind === SyntaxKind.JsxAttribute;
- }
-
- static IsJsxAttributeContext(context: FormattingContext): boolean {
- return context.contextNode.kind === SyntaxKind.JsxAttribute;
- }
-
- static IsJsxSelfClosingElementContext(context: FormattingContext): boolean {
- return context.contextNode.kind === SyntaxKind.JsxSelfClosingElement;
- }
-
- static IsNotBeforeBlockInFunctionDeclarationContext(context: FormattingContext): boolean {
- return !Rules.IsFunctionDeclContext(context) && !Rules.IsBeforeBlockContext(context);
- }
-
- static IsEndOfDecoratorContextOnSameLine(context: FormattingContext): boolean {
- return context.TokensAreOnSameLine() &&
- context.contextNode.decorators &&
- Rules.NodeIsInDecoratorContext(context.currentTokenParent) &&
- !Rules.NodeIsInDecoratorContext(context.nextTokenParent);
- }
-
- static NodeIsInDecoratorContext(node: Node): boolean {
- while (isExpressionNode(node)) {
- node = node.parent;
- }
- return node.kind === SyntaxKind.Decorator;
- }
-
- static IsStartOfVariableDeclarationList(context: FormattingContext): boolean {
- return context.currentTokenParent.kind === SyntaxKind.VariableDeclarationList &&
- context.currentTokenParent.getStart(context.sourceFile) === context.currentTokenSpan.pos;
- }
-
- static IsNotFormatOnEnter(context: FormattingContext): boolean {
- return context.formattingRequestKind !== FormattingRequestKind.FormatOnEnter;
- }
-
- static IsModuleDeclContext(context: FormattingContext): boolean {
- return context.contextNode.kind === SyntaxKind.ModuleDeclaration;
- }
-
- static IsObjectTypeContext(context: FormattingContext): boolean {
- return context.contextNode.kind === SyntaxKind.TypeLiteral; // && context.contextNode.parent.kind !== SyntaxKind.InterfaceDeclaration;
- }
-
- static IsConstructorSignatureContext(context: FormattingContext): boolean {
- return context.contextNode.kind === SyntaxKind.ConstructSignature;
- }
-
- static IsTypeArgumentOrParameterOrAssertion(token: TextRangeWithKind, parent: Node): boolean {
- if (token.kind !== SyntaxKind.LessThanToken && token.kind !== SyntaxKind.GreaterThanToken) {
+ default:
return false;
- }
- switch (parent.kind) {
- case SyntaxKind.TypeReference:
- case SyntaxKind.TypeAssertionExpression:
- case SyntaxKind.TypeAliasDeclaration:
- case SyntaxKind.ClassDeclaration:
- case SyntaxKind.ClassExpression:
- case SyntaxKind.InterfaceDeclaration:
- case SyntaxKind.FunctionDeclaration:
- case SyntaxKind.FunctionExpression:
- case SyntaxKind.ArrowFunction:
- case SyntaxKind.MethodDeclaration:
- case SyntaxKind.MethodSignature:
- case SyntaxKind.CallSignature:
- case SyntaxKind.ConstructSignature:
- case SyntaxKind.CallExpression:
- case SyntaxKind.NewExpression:
- case SyntaxKind.ExpressionWithTypeArguments:
- return true;
- default:
- return false;
-
- }
- }
-
- static IsTypeArgumentOrParameterOrAssertionContext(context: FormattingContext): boolean {
- return Rules.IsTypeArgumentOrParameterOrAssertion(context.currentTokenSpan, context.currentTokenParent) ||
- Rules.IsTypeArgumentOrParameterOrAssertion(context.nextTokenSpan, context.nextTokenParent);
- }
-
- static IsTypeAssertionContext(context: FormattingContext): boolean {
- return context.contextNode.kind === SyntaxKind.TypeAssertionExpression;
- }
-
- static IsVoidOpContext(context: FormattingContext): boolean {
- return context.currentTokenSpan.kind === SyntaxKind.VoidKeyword && context.currentTokenParent.kind === SyntaxKind.VoidExpression;
- }
-
- static IsYieldOrYieldStarWithOperand(context: FormattingContext): boolean {
- return context.contextNode.kind === SyntaxKind.YieldExpression && (context.contextNode).expression !== undefined;
- }
-
- static IsNonNullAssertionContext(context: FormattingContext): boolean {
- return context.contextNode.kind === SyntaxKind.NonNullExpression;
}
}
-}
\ No newline at end of file
+
+ function isObjectContext(context: FormattingContext): boolean {
+ return context.contextNode.kind === SyntaxKind.ObjectLiteralExpression;
+ }
+
+ function isFunctionCallContext(context: FormattingContext): boolean {
+ return context.contextNode.kind === SyntaxKind.CallExpression;
+ }
+
+ function isNewContext(context: FormattingContext): boolean {
+ return context.contextNode.kind === SyntaxKind.NewExpression;
+ }
+
+ function isFunctionCallOrNewContext(context: FormattingContext): boolean {
+ return isFunctionCallContext(context) || isNewContext(context);
+ }
+
+ function isPreviousTokenNotComma(context: FormattingContext): boolean {
+ return context.currentTokenSpan.kind !== SyntaxKind.CommaToken;
+ }
+
+ function isNextTokenNotCloseBracket(context: FormattingContext): boolean {
+ return context.nextTokenSpan.kind !== SyntaxKind.CloseBracketToken;
+ }
+
+ function isArrowFunctionContext(context: FormattingContext): boolean {
+ return context.contextNode.kind === SyntaxKind.ArrowFunction;
+ }
+
+ function isNonJsxSameLineTokenContext(context: FormattingContext): boolean {
+ return context.TokensAreOnSameLine() && context.contextNode.kind !== SyntaxKind.JsxText;
+ }
+
+ function isNonJsxElementContext(context: FormattingContext): boolean {
+ return context.contextNode.kind !== SyntaxKind.JsxElement;
+ }
+
+ function isJsxExpressionContext(context: FormattingContext): boolean {
+ return context.contextNode.kind === SyntaxKind.JsxExpression;
+ }
+
+ function isNextTokenParentJsxAttribute(context: FormattingContext): boolean {
+ return context.nextTokenParent.kind === SyntaxKind.JsxAttribute;
+ }
+
+ function isJsxAttributeContext(context: FormattingContext): boolean {
+ return context.contextNode.kind === SyntaxKind.JsxAttribute;
+ }
+
+ function isJsxSelfClosingElementContext(context: FormattingContext): boolean {
+ return context.contextNode.kind === SyntaxKind.JsxSelfClosingElement;
+ }
+
+ function isNotBeforeBlockInFunctionDeclarationContext(context: FormattingContext): boolean {
+ return !isFunctionDeclContext(context) && !isBeforeBlockContext(context);
+ }
+
+ function isEndOfDecoratorContextOnSameLine(context: FormattingContext): boolean {
+ return context.TokensAreOnSameLine() &&
+ context.contextNode.decorators &&
+ nodeIsInDecoratorContext(context.currentTokenParent) &&
+ !nodeIsInDecoratorContext(context.nextTokenParent);
+ }
+
+ function nodeIsInDecoratorContext(node: Node): boolean {
+ while (isExpressionNode(node)) {
+ node = node.parent;
+ }
+ return node.kind === SyntaxKind.Decorator;
+ }
+
+ function isStartOfVariableDeclarationList(context: FormattingContext): boolean {
+ return context.currentTokenParent.kind === SyntaxKind.VariableDeclarationList &&
+ context.currentTokenParent.getStart(context.sourceFile) === context.currentTokenSpan.pos;
+ }
+
+ function isNotFormatOnEnter(context: FormattingContext): boolean {
+ return context.formattingRequestKind !== FormattingRequestKind.FormatOnEnter;
+ }
+
+ function isModuleDeclContext(context: FormattingContext): boolean {
+ return context.contextNode.kind === SyntaxKind.ModuleDeclaration;
+ }
+
+ function isObjectTypeContext(context: FormattingContext): boolean {
+ return context.contextNode.kind === SyntaxKind.TypeLiteral; // && context.contextNode.parent.kind !== SyntaxKind.InterfaceDeclaration;
+ }
+
+ function isConstructorSignatureContext(context: FormattingContext): boolean {
+ return context.contextNode.kind === SyntaxKind.ConstructSignature;
+ }
+
+ function isTypeArgumentOrParameterOrAssertion(token: TextRangeWithKind, parent: Node): boolean {
+ if (token.kind !== SyntaxKind.LessThanToken && token.kind !== SyntaxKind.GreaterThanToken) {
+ return false;
+ }
+ switch (parent.kind) {
+ case SyntaxKind.TypeReference:
+ case SyntaxKind.TypeAssertionExpression:
+ case SyntaxKind.TypeAliasDeclaration:
+ case SyntaxKind.ClassDeclaration:
+ case SyntaxKind.ClassExpression:
+ case SyntaxKind.InterfaceDeclaration:
+ case SyntaxKind.FunctionDeclaration:
+ case SyntaxKind.FunctionExpression:
+ case SyntaxKind.ArrowFunction:
+ case SyntaxKind.MethodDeclaration:
+ case SyntaxKind.MethodSignature:
+ case SyntaxKind.CallSignature:
+ case SyntaxKind.ConstructSignature:
+ case SyntaxKind.CallExpression:
+ case SyntaxKind.NewExpression:
+ case SyntaxKind.ExpressionWithTypeArguments:
+ return true;
+ default:
+ return false;
+
+ }
+ }
+
+ function isTypeArgumentOrParameterOrAssertionContext(context: FormattingContext): boolean {
+ return isTypeArgumentOrParameterOrAssertion(context.currentTokenSpan, context.currentTokenParent) ||
+ isTypeArgumentOrParameterOrAssertion(context.nextTokenSpan, context.nextTokenParent);
+ }
+
+ function isTypeAssertionContext(context: FormattingContext): boolean {
+ return context.contextNode.kind === SyntaxKind.TypeAssertionExpression;
+ }
+
+ function isVoidOpContext(context: FormattingContext): boolean {
+ return context.currentTokenSpan.kind === SyntaxKind.VoidKeyword && context.currentTokenParent.kind === SyntaxKind.VoidExpression;
+ }
+
+ function isYieldOrYieldStarWithOperand(context: FormattingContext): boolean {
+ return context.contextNode.kind === SyntaxKind.YieldExpression && (context.contextNode).expression !== undefined;
+ }
+
+ function isNonNullAssertionContext(context: FormattingContext): boolean {
+ return context.contextNode.kind === SyntaxKind.NonNullExpression;
+ }
+}
diff --git a/src/services/formatting/rulesMap.ts b/src/services/formatting/rulesMap.ts
index 3b04308ebe8..d44e47a763a 100644
--- a/src/services/formatting/rulesMap.ts
+++ b/src/services/formatting/rulesMap.ts
@@ -1,60 +1,59 @@
-///
+///
/* @internal */
namespace ts.formatting {
- export class RulesMap {
- public map: RulesBucket[];
- public mapRowLength: number;
+ export function getFormatContext(options: FormatCodeSettings): formatting.FormatContext {
+ return { options, getRule: getRulesMap() };
+ }
- constructor(rules: ReadonlyArray) {
- this.mapRowLength = SyntaxKind.LastToken + 1;
- this.map = new Array(this.mapRowLength * this.mapRowLength);
+ let rulesMapCache: RulesMap | undefined;
- // This array is used only during construction of the rulesbucket in the map
- const rulesBucketConstructionStateList: RulesBucketConstructionState[] = new Array(this.map.length);
- for (const rule of rules) {
- this.FillRule(rule, rulesBucketConstructionStateList);
- }
+ function getRulesMap(): RulesMap {
+ if (rulesMapCache === undefined) {
+ rulesMapCache = createRulesMap(getAllRules());
}
+ return rulesMapCache;
+ }
- private GetRuleBucketIndex(row: number, column: number): number {
- Debug.assert(row <= SyntaxKind.LastKeyword && column <= SyntaxKind.LastKeyword, "Must compute formatting context from tokens");
- return (row * this.mapRowLength) + column;
- }
+ export type RulesMap = (context: FormattingContext) => Rule | undefined;
+ function createRulesMap(rules: ReadonlyArray): RulesMap {
+ const map = buildMap(rules);
+ return context => {
+ const bucket = map[getRuleBucketIndex(context.currentTokenSpan.kind, context.nextTokenSpan.kind)];
+ return bucket && find(bucket, rule => every(rule.context, c => c(context)));
+ };
+ }
- private FillRule(rule: Rule, rulesBucketConstructionStateList: RulesBucketConstructionState[]): void {
- const specificRule = rule.descriptor.leftTokenRange.isSpecific() && rule.descriptor.rightTokenRange.isSpecific();
+ function buildMap(rules: ReadonlyArray): ReadonlyArray> {
+ // Map from bucket index to array of rules
+ const map: Rule[][] = new Array(mapRowLength * mapRowLength);
+ // This array is used only during construction of the rulesbucket in the map
+ const rulesBucketConstructionStateList = new Array(map.length);
+ for (const rule of rules) {
+ const specificRule = rule.leftTokenRange.isSpecific && rule.rightTokenRange.isSpecific;
- rule.descriptor.leftTokenRange.GetTokens().forEach((left) => {
- rule.descriptor.rightTokenRange.GetTokens().forEach((right) => {
- const rulesBucketIndex = this.GetRuleBucketIndex(left, right);
-
- let rulesBucket = this.map[rulesBucketIndex];
+ for (const left of rule.leftTokenRange.tokens) {
+ for (const right of rule.rightTokenRange.tokens) {
+ const index = getRuleBucketIndex(left, right);
+ let rulesBucket = map[index];
if (rulesBucket === undefined) {
- rulesBucket = this.map[rulesBucketIndex] = new RulesBucket();
- }
-
- rulesBucket.AddRule(rule, specificRule, rulesBucketConstructionStateList, rulesBucketIndex);
- });
- });
- }
-
- public GetRule(context: FormattingContext): Rule | undefined {
- const bucketIndex = this.GetRuleBucketIndex(context.currentTokenSpan.kind, context.nextTokenSpan.kind);
- const bucket = this.map[bucketIndex];
- if (bucket) {
- for (const rule of bucket.Rules()) {
- if (rule.operation.context.InContext(context)) {
- return rule;
+ rulesBucket = map[index] = [];
}
+ addRule(rulesBucket, rule.rule, specificRule, rulesBucketConstructionStateList, index);
}
}
- return undefined;
}
+ return map;
+ }
+
+ function getRuleBucketIndex(row: number, column: number): number {
+ Debug.assert(row <= SyntaxKind.LastKeyword && column <= SyntaxKind.LastKeyword, "Must compute formatting context from tokens");
+ return (row * mapRowLength) + column;
}
const maskBitSize = 5;
- const mask = 0x1f;
+ const mask = 0b11111; // MaskBitSize bits
+ const mapRowLength = SyntaxKind.LastToken + 1;
enum RulesPosition {
IgnoreRulesSpecific = 0,
@@ -65,92 +64,44 @@ namespace ts.formatting {
NoContextRulesAny = maskBitSize * 5
}
- export class RulesBucketConstructionState {
- private rulesInsertionIndexBitmap: number;
-
- constructor() {
- //// The Rules list contains all the inserted rules into a rulebucket in the following order:
- //// 1- Ignore rules with specific token combination
- //// 2- Ignore rules with any token combination
- //// 3- Context rules with specific token combination
- //// 4- Context rules with any token combination
- //// 5- Non-context rules with specific token combination
- //// 6- Non-context rules with any token combination
- ////
- //// The member rulesInsertionIndexBitmap is used to describe the number of rules
- //// in each sub-bucket (above) hence can be used to know the index of where to insert
- //// the next rule. It's a bitmap which contains 6 different sections each is given 5 bits.
- ////
- //// Example:
- //// In order to insert a rule to the end of sub-bucket (3), we get the index by adding
- //// the values in the bitmap segments 3rd, 2nd, and 1st.
- this.rulesInsertionIndexBitmap = 0;
- }
-
- public GetInsertionIndex(maskPosition: RulesPosition): number {
- let index = 0;
-
- let pos = 0;
- let indexBitmap = this.rulesInsertionIndexBitmap;
-
- while (pos <= maskPosition) {
- index += (indexBitmap & mask);
- indexBitmap >>= maskBitSize;
- pos += maskBitSize;
- }
-
- return index;
- }
-
- public IncreaseInsertionIndex(maskPosition: RulesPosition): void {
- let value = (this.rulesInsertionIndexBitmap >> maskPosition) & mask;
- value++;
- Debug.assert((value & mask) === value, "Adding more rules into the sub-bucket than allowed. Maximum allowed is 32 rules.");
-
- let temp = this.rulesInsertionIndexBitmap & ~(mask << maskPosition);
- temp |= value << maskPosition;
-
- this.rulesInsertionIndexBitmap = temp;
- }
+ // The Rules list contains all the inserted rules into a rulebucket in the following order:
+ // 1- Ignore rules with specific token combination
+ // 2- Ignore rules with any token combination
+ // 3- Context rules with specific token combination
+ // 4- Context rules with any token combination
+ // 5- Non-context rules with specific token combination
+ // 6- Non-context rules with any token combination
+ //
+ // The member rulesInsertionIndexBitmap is used to describe the number of rules
+ // in each sub-bucket (above) hence can be used to know the index of where to insert
+ // the next rule. It's a bitmap which contains 6 different sections each is given 5 bits.
+ //
+ // Example:
+ // In order to insert a rule to the end of sub-bucket (3), we get the index by adding
+ // the values in the bitmap segments 3rd, 2nd, and 1st.
+ function addRule(rules: Rule[], rule: Rule, specificTokens: boolean, constructionState: number[], rulesBucketIndex: number): void {
+ const position = rule.action === RuleAction.Ignore
+ ? specificTokens ? RulesPosition.IgnoreRulesSpecific : RulesPosition.IgnoreRulesAny
+ : rule.context !== anyContext
+ ? specificTokens ? RulesPosition.ContextRulesSpecific : RulesPosition.ContextRulesAny
+ : specificTokens ? RulesPosition.NoContextRulesSpecific : RulesPosition.NoContextRulesAny;
+ const state = constructionState[rulesBucketIndex] || 0;
+ rules.splice(getInsertionIndex(state, position), 0, rule);
+ constructionState[rulesBucketIndex] = increaseInsertionIndex(state, position);
}
- export class RulesBucket {
- private rules: Rule[];
-
- constructor() {
- this.rules = [];
+ function getInsertionIndex(indexBitmap: number, maskPosition: RulesPosition) {
+ let index = 0;
+ for (let pos = 0; pos <= maskPosition; pos += maskBitSize) {
+ index += indexBitmap & mask;
+ indexBitmap >>= maskBitSize;
}
+ return index;
+ }
- public Rules(): Rule[] {
- return this.rules;
- }
-
- public AddRule(rule: Rule, specificTokens: boolean, constructionState: RulesBucketConstructionState[], rulesBucketIndex: number): void {
- let position: RulesPosition;
-
- if (rule.operation.action === RuleAction.Ignore) {
- position = specificTokens ?
- RulesPosition.IgnoreRulesSpecific :
- RulesPosition.IgnoreRulesAny;
- }
- else if (!rule.operation.context.IsAny()) {
- position = specificTokens ?
- RulesPosition.ContextRulesSpecific :
- RulesPosition.ContextRulesAny;
- }
- else {
- position = specificTokens ?
- RulesPosition.NoContextRulesSpecific :
- RulesPosition.NoContextRulesAny;
- }
-
- let state = constructionState[rulesBucketIndex];
- if (state === undefined) {
- state = constructionState[rulesBucketIndex] = new RulesBucketConstructionState();
- }
- const index = state.GetInsertionIndex(position);
- this.rules.splice(index, 0, rule);
- state.IncreaseInsertionIndex(position);
- }
+ function increaseInsertionIndex(indexBitmap: number, maskPosition: RulesPosition): number {
+ const value = ((indexBitmap >> maskPosition) & mask) + 1;
+ Debug.assert((value & mask) === value, "Adding more rules into the sub-bucket than allowed. Maximum allowed is 32 rules.");
+ return (indexBitmap & ~(mask << maskPosition)) | (value << maskPosition);
}
}
\ No newline at end of file
diff --git a/src/services/formatting/rulesProvider.ts b/src/services/formatting/rulesProvider.ts
deleted file mode 100644
index fcf08541890..00000000000
--- a/src/services/formatting/rulesProvider.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-///
-
-/* @internal */
-namespace ts.formatting {
- export class RulesProvider {
- private globalRules: Rules;
- private options: ts.FormatCodeSettings;
- private rulesMap: RulesMap;
-
- constructor() {
- this.globalRules = new Rules();
- const activeRules = this.globalRules.HighPriorityCommonRules.concat(this.globalRules.UserConfigurableRules).concat(this.globalRules.LowPriorityCommonRules);
- this.rulesMap = new RulesMap(activeRules);
- }
-
- public getRulesMap() {
- return this.rulesMap;
- }
-
- public getFormatOptions(): Readonly {
- return this.options;
- }
-
- public ensureUpToDate(options: ts.FormatCodeSettings) {
- if (!this.options || !ts.compareDataObjects(this.options, options)) {
- this.options = ts.clone(options);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts
index 7701cff182c..5afe4cb1d31 100644
--- a/src/services/formatting/smartIndenter.ts
+++ b/src/services/formatting/smartIndenter.ts
@@ -1,5 +1,3 @@
-///
-
/* @internal */
namespace ts.formatting {
export namespace SmartIndenter {
diff --git a/src/services/formatting/tokenRange.ts b/src/services/formatting/tokenRange.ts
deleted file mode 100644
index 31e15bc738d..00000000000
--- a/src/services/formatting/tokenRange.ts
+++ /dev/null
@@ -1,124 +0,0 @@
-///
-
-/* @internal */
-namespace ts.formatting {
- export namespace Shared {
- const allTokens: SyntaxKind[] = [];
- for (let token = SyntaxKind.FirstToken; token <= SyntaxKind.LastToken; token++) {
- allTokens.push(token);
- }
-
- class TokenValuesAccess implements TokenRange {
- constructor(private readonly tokens: SyntaxKind[] = []) { }
-
- public GetTokens(): SyntaxKind[] {
- return this.tokens;
- }
-
- public Contains(token: SyntaxKind): boolean {
- return this.tokens.indexOf(token) >= 0;
- }
-
- public isSpecific() { return true; }
- }
-
- class TokenSingleValueAccess implements TokenRange {
- constructor(private readonly token: SyntaxKind) {}
-
- public GetTokens(): SyntaxKind[] {
- return [this.token];
- }
-
- public Contains(tokenValue: SyntaxKind): boolean {
- return tokenValue === this.token;
- }
-
- public isSpecific() { return true; }
- }
-
- class TokenAllAccess implements TokenRange {
- public GetTokens(): SyntaxKind[] {
- return allTokens;
- }
-
- public Contains(): boolean {
- return true;
- }
-
- public toString(): string {
- return "[allTokens]";
- }
-
- public isSpecific() { return false; }
- }
-
- class TokenAllExceptAccess implements TokenRange {
- constructor(private readonly except: SyntaxKind) {}
-
- public GetTokens(): SyntaxKind[] {
- return allTokens.filter(t => t !== this.except);
- }
-
- public Contains(token: SyntaxKind): boolean {
- return token !== this.except;
- }
-
- public isSpecific() { return false; }
- }
-
- export interface TokenRange {
- GetTokens(): SyntaxKind[];
- Contains(token: SyntaxKind): boolean;
- isSpecific(): boolean;
- }
-
- export namespace TokenRange {
- export function FromToken(token: SyntaxKind): TokenRange {
- return new TokenSingleValueAccess(token);
- }
-
- export function FromTokens(tokens: SyntaxKind[]): TokenRange {
- return new TokenValuesAccess(tokens);
- }
-
- export function FromRange(from: SyntaxKind, to: SyntaxKind, except: SyntaxKind[] = []): TokenRange {
- const tokens: SyntaxKind[] = [];
- for (let token = from; token <= to; token++) {
- if (ts.indexOf(except, token) < 0) {
- tokens.push(token);
- }
- }
- return new TokenValuesAccess(tokens);
- }
-
- export function AnyExcept(token: SyntaxKind): TokenRange {
- return new TokenAllExceptAccess(token);
- }
-
- // tslint:disable variable-name (TODO)
- export const Any: TokenRange = new TokenAllAccess();
- export const AnyIncludingMultilineComments = TokenRange.FromTokens([...allTokens, SyntaxKind.MultiLineCommentTrivia]);
- export const Keywords = TokenRange.FromRange(SyntaxKind.FirstKeyword, SyntaxKind.LastKeyword);
- export const BinaryOperators = TokenRange.FromRange(SyntaxKind.FirstBinaryOperator, SyntaxKind.LastBinaryOperator);
- export const BinaryKeywordOperators = TokenRange.FromTokens([
- SyntaxKind.InKeyword, SyntaxKind.InstanceOfKeyword, SyntaxKind.OfKeyword, SyntaxKind.AsKeyword, SyntaxKind.IsKeyword]);
- export const UnaryPrefixOperators = TokenRange.FromTokens([
- SyntaxKind.PlusPlusToken, SyntaxKind.MinusMinusToken, SyntaxKind.TildeToken, SyntaxKind.ExclamationToken]);
- export const UnaryPrefixExpressions = TokenRange.FromTokens([
- SyntaxKind.NumericLiteral, SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.OpenBracketToken,
- SyntaxKind.OpenBraceToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword]);
- export const UnaryPreincrementExpressions = TokenRange.FromTokens([
- SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword]);
- export const UnaryPostincrementExpressions = TokenRange.FromTokens([
- SyntaxKind.Identifier, SyntaxKind.CloseParenToken, SyntaxKind.CloseBracketToken, SyntaxKind.NewKeyword]);
- export const UnaryPredecrementExpressions = TokenRange.FromTokens([
- SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword]);
- export const UnaryPostdecrementExpressions = TokenRange.FromTokens([
- SyntaxKind.Identifier, SyntaxKind.CloseParenToken, SyntaxKind.CloseBracketToken, SyntaxKind.NewKeyword]);
- export const Comments = TokenRange.FromTokens([SyntaxKind.SingleLineCommentTrivia, SyntaxKind.MultiLineCommentTrivia]);
- export const TypeNames = TokenRange.FromTokens([
- SyntaxKind.Identifier, SyntaxKind.NumberKeyword, SyntaxKind.StringKeyword, SyntaxKind.BooleanKeyword,
- SyntaxKind.SymbolKeyword, SyntaxKind.VoidKeyword, SyntaxKind.AnyKeyword]);
- }
- }
-}
diff --git a/src/services/jsTyping.ts b/src/services/jsTyping.ts
index 99942674a51..1c2f87fa428 100644
--- a/src/services/jsTyping.ts
+++ b/src/services/jsTyping.ts
@@ -183,7 +183,7 @@ namespace ts.JsTyping {
if (!hasJavaScriptFileExtension(j)) return undefined;
const inferredTypingName = removeFileExtension(getBaseFileName(j.toLowerCase()));
- const cleanedTypingName = inferredTypingName.replace(/((?:\.|-)min(?=\.|$))|((?:-|\.)\d+)/g, "");
+ const cleanedTypingName = removeMinAndVersionNumbers(inferredTypingName);
return safeList.get(cleanedTypingName);
});
if (fromFileNames.length) {
diff --git a/src/services/refactors/convertFunctionToEs6Class.ts b/src/services/refactors/convertFunctionToEs6Class.ts
index f5951bd26e4..b66d14ee449 100644
--- a/src/services/refactors/convertFunctionToEs6Class.ts
+++ b/src/services/refactors/convertFunctionToEs6Class.ts
@@ -50,7 +50,7 @@ namespace ts.refactor.convertFunctionToES6Class {
const { file: sourceFile } = context;
const ctorSymbol = getConstructorSymbol(context);
- const newLine = context.rulesProvider.getFormatOptions().newLineCharacter;
+ const newLine = context.formatContext.options.newLineCharacter;
const deletedNodes: Node[] = [];
const deletes: (() => any)[] = [];
diff --git a/src/services/services.ts b/src/services/services.ts
index 04a8e148b73..95e23a708a3 100644
--- a/src/services/services.ts
+++ b/src/services/services.ts
@@ -33,9 +33,6 @@ namespace ts {
/** The version of the language service API */
export const servicesVersion = "0.7";
- /* @internal */
- let ruleProvider: formatting.RulesProvider;
-
function createNode(kind: TKind, pos: number, end: number, parent?: Node): NodeObject | TokenObject | IdentifierObject {
const node = isNodeKind(kind) ? new NodeObject(kind, pos, end) :
kind === SyntaxKind.Identifier ? new IdentifierObject(SyntaxKind.Identifier, pos, end) :
@@ -65,39 +62,52 @@ namespace ts {
this.kind = kind;
}
+ private assertHasRealPosition(message?: string) {
+ // tslint:disable-next-line:debug-assert
+ Debug.assert(!positionIsSynthesized(this.pos) && !positionIsSynthesized(this.end), message || "Node must have a real position for this operation");
+ }
+
public getSourceFile(): SourceFile {
return getSourceFileOfNode(this);
}
public getStart(sourceFile?: SourceFileLike, includeJsDocComment?: boolean): number {
+ this.assertHasRealPosition();
return getTokenPosOfNode(this, sourceFile, includeJsDocComment);
}
public getFullStart(): number {
+ this.assertHasRealPosition();
return this.pos;
}
public getEnd(): number {
+ this.assertHasRealPosition();
return this.end;
}
public getWidth(sourceFile?: SourceFile): number {
+ this.assertHasRealPosition();
return this.getEnd() - this.getStart(sourceFile);
}
public getFullWidth(): number {
+ this.assertHasRealPosition();
return this.end - this.pos;
}
public getLeadingTriviaWidth(sourceFile?: SourceFile): number {
+ this.assertHasRealPosition();
return this.getStart(sourceFile) - this.pos;
}
public getFullText(sourceFile?: SourceFile): string {
+ this.assertHasRealPosition();
return (sourceFile || this.getSourceFile()).text.substring(this.pos, this.end);
}
public getText(sourceFile?: SourceFile): string {
+ this.assertHasRealPosition();
if (!sourceFile) {
sourceFile = this.getSourceFile();
}
@@ -186,21 +196,25 @@ namespace ts {
}
public getChildCount(sourceFile?: SourceFile): number {
+ this.assertHasRealPosition();
if (!this._children) this.createChildren(sourceFile);
return this._children.length;
}
public getChildAt(index: number, sourceFile?: SourceFile): Node {
+ this.assertHasRealPosition();
if (!this._children) this.createChildren(sourceFile);
return this._children[index];
}
public getChildren(sourceFile?: SourceFileLike): Node[] {
+ this.assertHasRealPosition("Node without a real position cannot be scanned and thus has no token nodes - use forEachChild and collect the result if that's fine");
if (!this._children) this.createChildren(sourceFile);
return this._children;
}
public getFirstToken(sourceFile?: SourceFile): Node {
+ this.assertHasRealPosition();
const children = this.getChildren(sourceFile);
if (!children.length) {
return undefined;
@@ -213,6 +227,7 @@ namespace ts {
}
public getLastToken(sourceFile?: SourceFile): Node {
+ this.assertHasRealPosition();
const children = this.getChildren(sourceFile);
const child = lastOrUndefined(children);
@@ -1157,7 +1172,6 @@ namespace ts {
documentRegistry: DocumentRegistry = createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory())): LanguageService {
const syntaxTreeCache: SyntaxTreeCache = new SyntaxTreeCache(host);
- ruleProvider = ruleProvider || new formatting.RulesProvider();
let program: Program;
let lastProjectVersion: string;
let lastTypesRootVersion = 0;
@@ -1187,11 +1201,6 @@ namespace ts {
return sourceFile;
}
- function getRuleProvider(options: FormatCodeSettings) {
- ruleProvider.ensureUpToDate(options);
- return ruleProvider;
- }
-
function synchronizeHostData(): void {
// perform fast check if host supports it
if (host.getProjectVersion) {
@@ -1429,7 +1438,6 @@ namespace ts {
function getCompletionEntryDetails(fileName: string, position: number, name: string, formattingOptions?: FormatCodeSettings, source?: string): CompletionEntryDetails {
synchronizeHostData();
- const ruleProvider = formattingOptions ? getRuleProvider(formattingOptions) : undefined;
return Completions.getCompletionEntryDetails(
program.getTypeChecker(),
log,
@@ -1439,7 +1447,7 @@ namespace ts {
{ name, source },
program.getSourceFiles(),
host,
- ruleProvider);
+ formattingOptions && formatting.getFormatContext(formattingOptions));
}
function getCompletionEntrySymbol(fileName: string, position: number, name: string, source?: string): Symbol {
@@ -1838,32 +1846,27 @@ namespace ts {
function getFormattingEditsForRange(fileName: string, start: number, end: number, options: FormatCodeOptions | FormatCodeSettings): TextChange[] {
const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
- const settings = toEditorSettings(options);
- return formatting.formatSelection(start, end, sourceFile, getRuleProvider(settings), settings);
+ return formatting.formatSelection(start, end, sourceFile, formatting.getFormatContext(toEditorSettings(options)));
}
function getFormattingEditsForDocument(fileName: string, options: FormatCodeOptions | FormatCodeSettings): TextChange[] {
- const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
- const settings = toEditorSettings(options);
- return formatting.formatDocument(sourceFile, getRuleProvider(settings), settings);
+ return formatting.formatDocument(syntaxTreeCache.getCurrentSourceFile(fileName), formatting.getFormatContext(toEditorSettings(options)));
}
function getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: FormatCodeOptions | FormatCodeSettings): TextChange[] {
const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
- const settings = toEditorSettings(options);
+ const formatContext = formatting.getFormatContext(toEditorSettings(options));
if (!isInComment(sourceFile, position)) {
- if (key === "{") {
- return formatting.formatOnOpeningCurly(position, sourceFile, getRuleProvider(settings), settings);
- }
- else if (key === "}") {
- return formatting.formatOnClosingCurly(position, sourceFile, getRuleProvider(settings), settings);
- }
- else if (key === ";") {
- return formatting.formatOnSemicolon(position, sourceFile, getRuleProvider(settings), settings);
- }
- else if (key === "\n") {
- return formatting.formatOnEnter(position, sourceFile, getRuleProvider(settings), settings);
+ switch (key) {
+ case "{":
+ return formatting.formatOnOpeningCurly(position, sourceFile, formatContext);
+ case "}":
+ return formatting.formatOnClosingCurly(position, sourceFile, formatContext);
+ case ";":
+ return formatting.formatOnSemicolon(position, sourceFile, formatContext);
+ case "\n":
+ return formatting.formatOnEnter(position, sourceFile, formatContext);
}
}
@@ -1875,16 +1878,22 @@ namespace ts {
const sourceFile = getValidSourceFile(fileName);
const span = createTextSpanFromBounds(start, end);
const newLineCharacter = getNewLineOrDefaultFromHost(host);
- const rulesProvider = getRuleProvider(formatOptions);
+ const formatContext = formatting.getFormatContext(formatOptions);
return flatMap(deduplicate(errorCodes, equateValues, compareValues), errorCode => {
cancellationToken.throwIfCancellationRequested();
- return codefix.getFixes({ errorCode, sourceFile, span, program, newLineCharacter, host, cancellationToken, rulesProvider });
+ return codefix.getFixes({ errorCode, sourceFile, span, program, newLineCharacter, host, cancellationToken, formatContext });
});
}
- function applyCodeActionCommand(fileName: Path, action: CodeActionCommand): Promise {
- fileName = toPath(fileName, currentDirectory, getCanonicalFileName);
+ function applyCodeActionCommand(fileName: Path, action: CodeActionCommand): Promise;
+ function applyCodeActionCommand(fileName: Path, action: CodeActionCommand[]): Promise;
+ function applyCodeActionCommand(fileName: Path, action: CodeActionCommand | CodeActionCommand[]): Promise {
+ const path = toPath(fileName, currentDirectory, getCanonicalFileName);
+ return isArray(action) ? Promise.all(action.map(a => applySingleCodeActionCommand(path, a))) : applySingleCodeActionCommand(path, action);
+ }
+
+ function applySingleCodeActionCommand(fileName: Path, action: CodeActionCommand): Promise {
switch (action.type) {
case "install package":
return host.installPackage
@@ -2104,7 +2113,7 @@ namespace ts {
program: getProgram(),
newLineCharacter: formatOptions ? formatOptions.newLineCharacter : host.getNewLine(),
host,
- rulesProvider: getRuleProvider(formatOptions),
+ formatContext: formatting.getFormatContext(formatOptions),
cancellationToken,
};
}
diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts
index ad9ac88bdfc..fe04342b8f7 100644
--- a/src/services/symbolDisplay.ts
+++ b/src/services/symbolDisplay.ts
@@ -191,13 +191,14 @@ namespace ts.SymbolDisplay {
// If it is call or construct signature of lambda's write type name
displayParts.push(punctuationPart(SyntaxKind.ColonToken));
displayParts.push(spacePart());
+ if (!(type.flags & TypeFlags.Object && (type).objectFlags & ObjectFlags.Anonymous) && type.symbol) {
+ addRange(displayParts, symbolToDisplayParts(typeChecker, type.symbol, enclosingDeclaration, /*meaning*/ undefined, SymbolFormatFlags.WriteTypeParametersOrArguments));
+ displayParts.push(lineBreakPart());
+ }
if (useConstructSignatures) {
displayParts.push(keywordPart(SyntaxKind.NewKeyword));
displayParts.push(spacePart());
}
- if (!(type.flags & TypeFlags.Object && (type).objectFlags & ObjectFlags.Anonymous) && type.symbol) {
- addRange(displayParts, symbolToDisplayParts(typeChecker, type.symbol, enclosingDeclaration, /*meaning*/ undefined, SymbolFormatFlags.WriteTypeParametersOrArguments));
- }
addSignatureDisplayParts(signature, allSignatures, TypeFormatFlags.WriteArrowStyleSignature);
break;
diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts
index bc3a8e27ef0..7c4e25537ef 100644
--- a/src/services/textChanges.ts
+++ b/src/services/textChanges.ts
@@ -188,7 +188,7 @@ namespace ts.textChanges {
export interface TextChangesContext {
newLineCharacter: string;
- rulesProvider: formatting.RulesProvider;
+ formatContext: ts.formatting.FormatContext;
}
export class ChangeTracker {
@@ -196,7 +196,7 @@ namespace ts.textChanges {
private readonly newLineCharacter: string;
public static fromContext(context: TextChangesContext): ChangeTracker {
- return new ChangeTracker(context.newLineCharacter === "\n" ? NewLineKind.LineFeed : NewLineKind.CarriageReturnLineFeed, context.rulesProvider);
+ return new ChangeTracker(context.newLineCharacter === "\n" ? NewLineKind.LineFeed : NewLineKind.CarriageReturnLineFeed, context.formatContext);
}
public static with(context: TextChangesContext, cb: (tracker: ChangeTracker) => void): FileTextChanges[] {
@@ -207,7 +207,7 @@ namespace ts.textChanges {
constructor(
private readonly newLine: NewLineKind,
- private readonly rulesProvider: formatting.RulesProvider,
+ private readonly formatContext: ts.formatting.FormatContext,
private readonly validator?: (text: NonFormattedText) => void) {
this.newLineCharacter = getNewLineCharacter({ newLine });
}
@@ -475,7 +475,7 @@ namespace ts.textChanges {
options: {}
});
// use the same indentation as 'after' item
- const indentation = formatting.SmartIndenter.findFirstNonWhitespaceColumn(afterStartLinePosition, afterStart, sourceFile, this.rulesProvider.getFormatOptions());
+ const indentation = formatting.SmartIndenter.findFirstNonWhitespaceColumn(afterStartLinePosition, afterStart, sourceFile, this.formatContext.options);
// insert element before the line break on the line that contains 'after' element
let insertPos = skipTrivia(sourceFile.text, end, /*stopAfterLineBreak*/ true, /*stopAtComments*/ false);
if (insertPos !== end && isLineBreak(sourceFile.text.charCodeAt(insertPos - 1))) {
@@ -562,7 +562,7 @@ namespace ts.textChanges {
this.validator(nonformattedText);
}
- const formatOptions = this.rulesProvider.getFormatOptions();
+ const { options: formatOptions } = this.formatContext;
const posStartsLine = getLineStartPositionForPosition(pos, sourceFile) === pos;
const initialIndentation =
@@ -578,7 +578,7 @@ namespace ts.textChanges {
? (formatOptions.indentSize || 0)
: 0;
- return applyFormatting(nonformattedText, sourceFile, initialIndentation, delta, this.rulesProvider);
+ return applyFormatting(nonformattedText, sourceFile, initialIndentation, delta, this.formatContext);
}
private static normalize(changes: Change[]): Change[] {
@@ -605,14 +605,14 @@ namespace ts.textChanges {
return { text: writer.getText(), node: assignPositionsToNode(node) };
}
- function applyFormatting(nonFormattedText: NonFormattedText, sourceFile: SourceFile, initialIndentation: number, delta: number, rulesProvider: formatting.RulesProvider) {
+ function applyFormatting(nonFormattedText: NonFormattedText, sourceFile: SourceFile, initialIndentation: number, delta: number, formatContext: ts.formatting.FormatContext) {
const lineMap = computeLineStarts(nonFormattedText.text);
const file: SourceFileLike = {
text: nonFormattedText.text,
lineMap,
getLineAndCharacterOfPosition: pos => computeLineAndCharacterOfPosition(lineMap, pos)
};
- const changes = formatting.formatNodeGivenIndentation(nonFormattedText.node, file, sourceFile.languageVariant, initialIndentation, delta, rulesProvider);
+ const changes = formatting.formatNodeGivenIndentation(nonFormattedText.node, file, sourceFile.languageVariant, initialIndentation, delta, formatContext);
return applyChanges(nonFormattedText.text, changes);
}
diff --git a/src/services/types.ts b/src/services/types.ts
index a9244982fbb..bcebc437892 100644
--- a/src/services/types.ts
+++ b/src/services/types.ts
@@ -294,6 +294,8 @@ namespace ts {
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[];
applyCodeActionCommand(fileName: string, action: CodeActionCommand): Promise;
+ applyCodeActionCommand(fileName: string, action: CodeActionCommand[]): Promise;
+ applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise;
getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[];
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined;
diff --git a/src/services/utilities.ts b/src/services/utilities.ts
index f59f6e56e91..cf71118292a 100644
--- a/src/services/utilities.ts
+++ b/src/services/utilities.ts
@@ -3,6 +3,7 @@
interface PromiseConstructor {
new (executor: (resolve: (value?: T | PromiseLike) => void, reject: (reason?: any) => void) => void): Promise;
reject(reason: any): Promise;
+ all(values: (T | PromiseLike)[]): Promise;
}
/* @internal */
declare var Promise: PromiseConstructor;
@@ -1068,20 +1069,19 @@ namespace ts {
return createTextSpanFromBounds(range.pos, range.end);
}
+ export const typeKeywords: ReadonlyArray = [
+ SyntaxKind.AnyKeyword,
+ SyntaxKind.BooleanKeyword,
+ SyntaxKind.NeverKeyword,
+ SyntaxKind.NumberKeyword,
+ SyntaxKind.ObjectKeyword,
+ SyntaxKind.StringKeyword,
+ SyntaxKind.SymbolKeyword,
+ SyntaxKind.VoidKeyword,
+ ];
+
export function isTypeKeyword(kind: SyntaxKind): boolean {
- switch (kind) {
- case SyntaxKind.AnyKeyword:
- case SyntaxKind.BooleanKeyword:
- case SyntaxKind.NeverKeyword:
- case SyntaxKind.NumberKeyword:
- case SyntaxKind.ObjectKeyword:
- case SyntaxKind.StringKeyword:
- case SyntaxKind.SymbolKeyword:
- case SyntaxKind.VoidKeyword:
- return true;
- default:
- return false;
- }
+ return contains(typeKeywords, kind);
}
/** True if the symbol is for an external module, as opposed to a namespace. */
diff --git a/tests/baselines/reference/abstractClassInLocalScopeIsAbstract.errors.txt b/tests/baselines/reference/abstractClassInLocalScopeIsAbstract.errors.txt
index f5c5b417ea3..fa02cb21d34 100644
--- a/tests/baselines/reference/abstractClassInLocalScopeIsAbstract.errors.txt
+++ b/tests/baselines/reference/abstractClassInLocalScopeIsAbstract.errors.txt
@@ -1,4 +1,4 @@
-tests/cases/compiler/abstractClassInLocalScopeIsAbstract.ts(4,5): error TS2511: Cannot create an instance of the abstract class 'A'.
+tests/cases/compiler/abstractClassInLocalScopeIsAbstract.ts(4,5): error TS2511: Cannot create an instance of an abstract class.
==== tests/cases/compiler/abstractClassInLocalScopeIsAbstract.ts (1 errors) ====
@@ -7,7 +7,7 @@ tests/cases/compiler/abstractClassInLocalScopeIsAbstract.ts(4,5): error TS2511:
class B extends A {}
new A();
~~~~~~~
-!!! error TS2511: Cannot create an instance of the abstract class 'A'.
+!!! error TS2511: Cannot create an instance of an abstract class.
new B();
})()
\ No newline at end of file
diff --git a/tests/baselines/reference/ambientDeclarationsExternal.js b/tests/baselines/reference/ambientDeclarationsExternal.js
index fb531586467..ed413fb0d8e 100644
--- a/tests/baselines/reference/ambientDeclarationsExternal.js
+++ b/tests/baselines/reference/ambientDeclarationsExternal.js
@@ -24,7 +24,7 @@ var n: number;
//// [decls.js]
-// Ambient external import declaration referencing ambient external module using top level module name
+// Ambient external import declaration referencing ambient external module using top level module name
//// [consumer.js]
"use strict";
exports.__esModule = true;
diff --git a/tests/baselines/reference/anyAssignableToEveryType.js b/tests/baselines/reference/anyAssignableToEveryType.js
index d6b2303de48..eff97905e4f 100644
--- a/tests/baselines/reference/anyAssignableToEveryType.js
+++ b/tests/baselines/reference/anyAssignableToEveryType.js
@@ -87,4 +87,4 @@ function foo(x, y, z) {
// x = a;
// y = a;
// z = a;
-//}
+//}
diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts
index a3499de08ab..096ad71c894 100644
--- a/tests/baselines/reference/api/tsserverlibrary.d.ts
+++ b/tests/baselines/reference/api/tsserverlibrary.d.ts
@@ -2142,6 +2142,7 @@ declare namespace ts {
NakedTypeVariable = 2,
MappedType = 4,
ReturnType = 8,
+ NeverType = 16,
}
interface InferenceInfo {
typeParameter: TypeParameter;
@@ -3965,6 +3966,8 @@ declare namespace ts {
getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan;
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[];
applyCodeActionCommand(fileName: string, action: CodeActionCommand): Promise;
+ applyCodeActionCommand(fileName: string, action: CodeActionCommand[]): Promise;
+ applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise;
getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[];
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined;
getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean): EmitOutput;
@@ -5263,6 +5266,7 @@ declare namespace ts.server.protocol {
errorCodes?: number[];
}
interface ApplyCodeActionCommandRequestArgs extends FileRequestArgs {
+ /** May also be an array of commands. */
command: {};
}
/**
@@ -7429,7 +7433,9 @@ declare namespace ts.server {
}
interface TypesMapFile {
typesMap: SafeList;
- simpleMap: string[];
+ simpleMap: {
+ [libName: string]: string;
+ };
}
function convertFormatOptions(protocolOptions: protocol.FormatCodeSettings): FormatCodeSettings;
function convertCompilerOptions(protocolOptions: protocol.ExternalProjectCompilerOptions): CompilerOptions & protocol.CompileOnSaveMixin;
@@ -7510,6 +7516,7 @@ declare namespace ts.server {
private readonly throttledOperations;
private readonly hostConfiguration;
private safelist;
+ private legacySafelist;
private changedFiles;
private pendingProjectUpdates;
private pendingInferredProjectUpdate;
@@ -7618,7 +7625,7 @@ declare namespace ts.server {
private findExternalProjectByProjectName(projectFileName);
private convertConfigFileContentToProjectOptions(configFilename, cachedDirectoryStructureHost);
private exceededTotalSizeLimitForNonTsFiles(name, options, fileNames, propertyReader);
- private createExternalProject(projectFileName, files, options, typeAcquisition);
+ private createExternalProject(projectFileName, files, options, typeAcquisition, excludedFiles);
private sendProjectTelemetry(projectKey, project, projectOptions?);
private addFilesToNonInferredProjectAndUpdateGraph(project, files, propertyReader, typeAcquisition);
private createConfiguredProject(configFileName);
diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts
index 98d7137ddeb..dcc077d2cd7 100644
--- a/tests/baselines/reference/api/typescript.d.ts
+++ b/tests/baselines/reference/api/typescript.d.ts
@@ -2142,6 +2142,7 @@ declare namespace ts {
NakedTypeVariable = 2,
MappedType = 4,
ReturnType = 8,
+ NeverType = 16,
}
interface InferenceInfo {
typeParameter: TypeParameter;
@@ -3965,6 +3966,8 @@ declare namespace ts {
getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan;
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[];
applyCodeActionCommand(fileName: string, action: CodeActionCommand): Promise;
+ applyCodeActionCommand(fileName: string, action: CodeActionCommand[]): Promise;
+ applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise;
getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[];
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined;
getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean): EmitOutput;
diff --git a/tests/baselines/reference/arityAndOrderCompatibility01.errors.txt b/tests/baselines/reference/arityAndOrderCompatibility01.errors.txt
index 5a367a4122f..4d6fbd063ae 100644
--- a/tests/baselines/reference/arityAndOrderCompatibility01.errors.txt
+++ b/tests/baselines/reference/arityAndOrderCompatibility01.errors.txt
@@ -1,52 +1,49 @@
-tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(13,12): error TS2493: Tuple type '[string, number]' with length '2' cannot be assigned to tuple with length '3'.
-tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(14,12): error TS2460: Type 'StrNum' has no property '2'.
-tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(15,5): error TS2461: Type '{ 0: string; 1: number; }' is not an array type.
-tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(15,12): error TS2460: Type '{ 0: string; 1: number; }' has no property '2'.
-tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(16,5): error TS2322: Type '[string, number]' is not assignable to type '[number, number, number]'.
+tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(15,12): error TS2493: Tuple type '[string, number]' with length '2' cannot be assigned to tuple with length '3'.
+tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(16,12): error TS2460: Type 'StrNum' has no property '2'.
+tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(17,5): error TS2461: Type '{ 0: string; 1: number; length: 2; }' is not an array type.
+tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(17,12): error TS2460: Type '{ 0: string; 1: number; length: 2; }' has no property '2'.
+tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(18,5): error TS2322: Type '[string, number]' is not assignable to type '[number, number, number]'.
Property '2' is missing in type '[string, number]'.
-tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(17,5): error TS2322: Type 'StrNum' is not assignable to type '[number, number, number]'.
+tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(19,5): error TS2322: Type 'StrNum' is not assignable to type '[number, number, number]'.
Property '2' is missing in type 'StrNum'.
-tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(18,5): error TS2322: Type '{ 0: string; 1: number; }' is not assignable to type '[number, number, number]'.
- Property '2' is missing in type '{ 0: string; 1: number; }'.
-tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(19,5): error TS2322: Type '[string, number]' is not assignable to type '[string, number, number]'.
+tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(20,5): error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[number, number, number]'.
+ Property '2' is missing in type '{ 0: string; 1: number; length: 2; }'.
+tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(21,5): error TS2322: Type '[string, number]' is not assignable to type '[string, number, number]'.
Property '2' is missing in type '[string, number]'.
-tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(20,5): error TS2322: Type 'StrNum' is not assignable to type '[string, number, number]'.
+tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(22,5): error TS2322: Type 'StrNum' is not assignable to type '[string, number, number]'.
Property '2' is missing in type 'StrNum'.
-tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(21,5): error TS2322: Type '{ 0: string; 1: number; }' is not assignable to type '[string, number, number]'.
- Property '2' is missing in type '{ 0: string; 1: number; }'.
-tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(22,5): error TS2322: Type '[string, number]' is not assignable to type '[number]'.
+tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(23,5): error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[string, number, number]'.
+ Property '2' is missing in type '{ 0: string; 1: number; length: 2; }'.
+tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(24,5): error TS2322: Type '[string, number]' is not assignable to type '[number]'.
Types of property '0' are incompatible.
Type 'string' is not assignable to type 'number'.
-tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(23,5): error TS2322: Type 'StrNum' is not assignable to type '[number]'.
+tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(25,5): error TS2322: Type 'StrNum' is not assignable to type '[number]'.
Types of property '0' are incompatible.
Type 'string' is not assignable to type 'number'.
-tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(24,5): error TS2322: Type '{ 0: string; 1: number; }' is not assignable to type '[number]'.
- Property 'length' is missing in type '{ 0: string; 1: number; }'.
-tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(25,5): error TS2322: Type '[string, number]' is not assignable to type '[string]'.
- Types of property 'pop' are incompatible.
- Type '() => string | number' is not assignable to type '() => string'.
- Type 'string | number' is not assignable to type 'string'.
- Type 'number' is not assignable to type 'string'.
-tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(26,5): error TS2322: Type 'StrNum' is not assignable to type '[string]'.
- Types of property 'pop' are incompatible.
- Type '() => string | number' is not assignable to type '() => string'.
- Type 'string | number' is not assignable to type 'string'.
- Type 'number' is not assignable to type 'string'.
-tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(27,5): error TS2322: Type '{ 0: string; 1: number; }' is not assignable to type '[string]'.
- Property 'length' is missing in type '{ 0: string; 1: number; }'.
-tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(28,5): error TS2322: Type '[string, number]' is not assignable to type '[number, string]'.
+tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(26,5): error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[number]'.
+ Property 'push' is missing in type '{ 0: string; 1: number; length: 2; }'.
+tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(27,5): error TS2322: Type '[string, number]' is not assignable to type '[string]'.
+ Types of property 'length' are incompatible.
+ Type '2' is not assignable to type '1'.
+tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(28,5): error TS2322: Type 'StrNum' is not assignable to type '[string]'.
+ Types of property 'length' are incompatible.
+ Type '2' is not assignable to type '1'.
+tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(29,5): error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[string]'.
+ Property 'push' is missing in type '{ 0: string; 1: number; length: 2; }'.
+tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(30,5): error TS2322: Type '[string, number]' is not assignable to type '[number, string]'.
Type 'string' is not assignable to type 'number'.
-tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(29,5): error TS2322: Type 'StrNum' is not assignable to type '[number, string]'.
+tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(31,5): error TS2322: Type 'StrNum' is not assignable to type '[number, string]'.
Types of property '0' are incompatible.
Type 'string' is not assignable to type 'number'.
-tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(30,5): error TS2322: Type '{ 0: string; 1: number; }' is not assignable to type '[number, string]'.
- Property 'length' is missing in type '{ 0: string; 1: number; }'.
+tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(32,5): error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[number, string]'.
+ Property 'push' is missing in type '{ 0: string; 1: number; length: 2; }'.
==== tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts (19 errors) ====
interface StrNum extends Array {
0: string;
1: number;
+ length: 2;
}
var x: [string, number];
@@ -54,6 +51,7 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(30,5): error
var z: {
0: string;
1: number;
+ length: 2;
}
var [a, b, c] = x;
@@ -64,9 +62,9 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(30,5): error
!!! error TS2460: Type 'StrNum' has no property '2'.
var [g, h, i] = z;
~~~~~~~~~
-!!! error TS2461: Type '{ 0: string; 1: number; }' is not an array type.
+!!! error TS2461: Type '{ 0: string; 1: number; length: 2; }' is not an array type.
~
-!!! error TS2460: Type '{ 0: string; 1: number; }' has no property '2'.
+!!! error TS2460: Type '{ 0: string; 1: number; length: 2; }' has no property '2'.
var j1: [number, number, number] = x;
~~
!!! error TS2322: Type '[string, number]' is not assignable to type '[number, number, number]'.
@@ -77,8 +75,8 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(30,5): error
!!! error TS2322: Property '2' is missing in type 'StrNum'.
var j3: [number, number, number] = z;
~~
-!!! error TS2322: Type '{ 0: string; 1: number; }' is not assignable to type '[number, number, number]'.
-!!! error TS2322: Property '2' is missing in type '{ 0: string; 1: number; }'.
+!!! error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[number, number, number]'.
+!!! error TS2322: Property '2' is missing in type '{ 0: string; 1: number; length: 2; }'.
var k1: [string, number, number] = x;
~~
!!! error TS2322: Type '[string, number]' is not assignable to type '[string, number, number]'.
@@ -89,8 +87,8 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(30,5): error
!!! error TS2322: Property '2' is missing in type 'StrNum'.
var k3: [string, number, number] = z;
~~
-!!! error TS2322: Type '{ 0: string; 1: number; }' is not assignable to type '[string, number, number]'.
-!!! error TS2322: Property '2' is missing in type '{ 0: string; 1: number; }'.
+!!! error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[string, number, number]'.
+!!! error TS2322: Property '2' is missing in type '{ 0: string; 1: number; length: 2; }'.
var l1: [number] = x;
~~
!!! error TS2322: Type '[string, number]' is not assignable to type '[number]'.
@@ -103,26 +101,22 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(30,5): error
!!! error TS2322: Type 'string' is not assignable to type 'number'.
var l3: [number] = z;
~~
-!!! error TS2322: Type '{ 0: string; 1: number; }' is not assignable to type '[number]'.
-!!! error TS2322: Property 'length' is missing in type '{ 0: string; 1: number; }'.
+!!! error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[number]'.
+!!! error TS2322: Property 'push' is missing in type '{ 0: string; 1: number; length: 2; }'.
var m1: [string] = x;
~~
!!! error TS2322: Type '[string, number]' is not assignable to type '[string]'.
-!!! error TS2322: Types of property 'pop' are incompatible.
-!!! error TS2322: Type '() => string | number' is not assignable to type '() => string'.
-!!! error TS2322: Type 'string | number' is not assignable to type 'string'.
-!!! error TS2322: Type 'number' is not assignable to type 'string'.
+!!! error TS2322: Types of property 'length' are incompatible.
+!!! error TS2322: Type '2' is not assignable to type '1'.
var m2: [string] = y;
~~
!!! error TS2322: Type 'StrNum' is not assignable to type '[string]'.
-!!! error TS2322: Types of property 'pop' are incompatible.
-!!! error TS2322: Type '() => string | number' is not assignable to type '() => string'.
-!!! error TS2322: Type 'string | number' is not assignable to type 'string'.
-!!! error TS2322: Type 'number' is not assignable to type 'string'.
+!!! error TS2322: Types of property 'length' are incompatible.
+!!! error TS2322: Type '2' is not assignable to type '1'.
var m3: [string] = z;
~~
-!!! error TS2322: Type '{ 0: string; 1: number; }' is not assignable to type '[string]'.
-!!! error TS2322: Property 'length' is missing in type '{ 0: string; 1: number; }'.
+!!! error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[string]'.
+!!! error TS2322: Property 'push' is missing in type '{ 0: string; 1: number; length: 2; }'.
var n1: [number, string] = x;
~~
!!! error TS2322: Type '[string, number]' is not assignable to type '[number, string]'.
@@ -134,8 +128,8 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(30,5): error
!!! error TS2322: Type 'string' is not assignable to type 'number'.
var n3: [number, string] = z;
~~
-!!! error TS2322: Type '{ 0: string; 1: number; }' is not assignable to type '[number, string]'.
-!!! error TS2322: Property 'length' is missing in type '{ 0: string; 1: number; }'.
+!!! error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[number, string]'.
+!!! error TS2322: Property 'push' is missing in type '{ 0: string; 1: number; length: 2; }'.
var o1: [string, number] = x;
var o2: [string, number] = y;
var o3: [string, number] = y;
diff --git a/tests/baselines/reference/arityAndOrderCompatibility01.js b/tests/baselines/reference/arityAndOrderCompatibility01.js
index 2eb1bcf8bd8..bf7736a80c9 100644
--- a/tests/baselines/reference/arityAndOrderCompatibility01.js
+++ b/tests/baselines/reference/arityAndOrderCompatibility01.js
@@ -2,6 +2,7 @@
interface StrNum extends Array {
0: string;
1: number;
+ length: 2;
}
var x: [string, number];
@@ -9,6 +10,7 @@ var y: StrNum
var z: {
0: string;
1: number;
+ length: 2;
}
var [a, b, c] = x;
diff --git a/tests/baselines/reference/arityAndOrderCompatibility01.symbols b/tests/baselines/reference/arityAndOrderCompatibility01.symbols
index c6ef08a845b..3a5d55dc1e6 100644
--- a/tests/baselines/reference/arityAndOrderCompatibility01.symbols
+++ b/tests/baselines/reference/arityAndOrderCompatibility01.symbols
@@ -5,109 +5,113 @@ interface StrNum extends Array {
0: string;
1: number;
+ length: 2;
+>length : Symbol(StrNum.length, Decl(arityAndOrderCompatibility01.ts, 2, 14))
}
var x: [string, number];
->x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 5, 3))
+>x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 6, 3))
var y: StrNum
->y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 6, 3))
+>y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 7, 3))
>StrNum : Symbol(StrNum, Decl(arityAndOrderCompatibility01.ts, 0, 0))
var z: {
->z : Symbol(z, Decl(arityAndOrderCompatibility01.ts, 7, 3))
+>z : Symbol(z, Decl(arityAndOrderCompatibility01.ts, 8, 3))
0: string;
1: number;
+ length: 2;
+>length : Symbol(length, Decl(arityAndOrderCompatibility01.ts, 10, 14))
}
var [a, b, c] = x;
->a : Symbol(a, Decl(arityAndOrderCompatibility01.ts, 12, 5))
->b : Symbol(b, Decl(arityAndOrderCompatibility01.ts, 12, 7))
->c : Symbol(c, Decl(arityAndOrderCompatibility01.ts, 12, 10))
->x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 5, 3))
+>a : Symbol(a, Decl(arityAndOrderCompatibility01.ts, 14, 5))
+>b : Symbol(b, Decl(arityAndOrderCompatibility01.ts, 14, 7))
+>c : Symbol(c, Decl(arityAndOrderCompatibility01.ts, 14, 10))
+>x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 6, 3))
var [d, e, f] = y;
->d : Symbol(d, Decl(arityAndOrderCompatibility01.ts, 13, 5))
->e : Symbol(e, Decl(arityAndOrderCompatibility01.ts, 13, 7))
->f : Symbol(f, Decl(arityAndOrderCompatibility01.ts, 13, 10))
->y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 6, 3))
+>d : Symbol(d, Decl(arityAndOrderCompatibility01.ts, 15, 5))
+>e : Symbol(e, Decl(arityAndOrderCompatibility01.ts, 15, 7))
+>f : Symbol(f, Decl(arityAndOrderCompatibility01.ts, 15, 10))
+>y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 7, 3))
var [g, h, i] = z;
->g : Symbol(g, Decl(arityAndOrderCompatibility01.ts, 14, 5))
->h : Symbol(h, Decl(arityAndOrderCompatibility01.ts, 14, 7))
->i : Symbol(i, Decl(arityAndOrderCompatibility01.ts, 14, 10))
->z : Symbol(z, Decl(arityAndOrderCompatibility01.ts, 7, 3))
+>g : Symbol(g, Decl(arityAndOrderCompatibility01.ts, 16, 5))
+>h : Symbol(h, Decl(arityAndOrderCompatibility01.ts, 16, 7))
+>i : Symbol(i, Decl(arityAndOrderCompatibility01.ts, 16, 10))
+>z : Symbol(z, Decl(arityAndOrderCompatibility01.ts, 8, 3))
var j1: [number, number, number] = x;
->j1 : Symbol(j1, Decl(arityAndOrderCompatibility01.ts, 15, 3))
->x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 5, 3))
+>j1 : Symbol(j1, Decl(arityAndOrderCompatibility01.ts, 17, 3))
+>x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 6, 3))
var j2: [number, number, number] = y;
->j2 : Symbol(j2, Decl(arityAndOrderCompatibility01.ts, 16, 3))
->y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 6, 3))
+>j2 : Symbol(j2, Decl(arityAndOrderCompatibility01.ts, 18, 3))
+>y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 7, 3))
var j3: [number, number, number] = z;
->j3 : Symbol(j3, Decl(arityAndOrderCompatibility01.ts, 17, 3))
->z : Symbol(z, Decl(arityAndOrderCompatibility01.ts, 7, 3))
+>j3 : Symbol(j3, Decl(arityAndOrderCompatibility01.ts, 19, 3))
+>z : Symbol(z, Decl(arityAndOrderCompatibility01.ts, 8, 3))
var k1: [string, number, number] = x;
->k1 : Symbol(k1, Decl(arityAndOrderCompatibility01.ts, 18, 3))
->x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 5, 3))
+>k1 : Symbol(k1, Decl(arityAndOrderCompatibility01.ts, 20, 3))
+>x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 6, 3))
var k2: [string, number, number] = y;
->k2 : Symbol(k2, Decl(arityAndOrderCompatibility01.ts, 19, 3))
->y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 6, 3))
+>k2 : Symbol(k2, Decl(arityAndOrderCompatibility01.ts, 21, 3))
+>y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 7, 3))
var k3: [string, number, number] = z;
->k3 : Symbol(k3, Decl(arityAndOrderCompatibility01.ts, 20, 3))
->z : Symbol(z, Decl(arityAndOrderCompatibility01.ts, 7, 3))
+>k3 : Symbol(k3, Decl(arityAndOrderCompatibility01.ts, 22, 3))
+>z : Symbol(z, Decl(arityAndOrderCompatibility01.ts, 8, 3))
var l1: [number] = x;
->l1 : Symbol(l1, Decl(arityAndOrderCompatibility01.ts, 21, 3))
->x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 5, 3))
+>l1 : Symbol(l1, Decl(arityAndOrderCompatibility01.ts, 23, 3))
+>x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 6, 3))
var l2: [number] = y;
->l2 : Symbol(l2, Decl(arityAndOrderCompatibility01.ts, 22, 3))
->y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 6, 3))
+>l2 : Symbol(l2, Decl(arityAndOrderCompatibility01.ts, 24, 3))
+>y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 7, 3))
var l3: [number] = z;
->l3 : Symbol(l3, Decl(arityAndOrderCompatibility01.ts, 23, 3))
->z : Symbol(z, Decl(arityAndOrderCompatibility01.ts, 7, 3))
+>l3 : Symbol(l3, Decl(arityAndOrderCompatibility01.ts, 25, 3))
+>z : Symbol(z, Decl(arityAndOrderCompatibility01.ts, 8, 3))
var m1: [string] = x;
->m1 : Symbol(m1, Decl(arityAndOrderCompatibility01.ts, 24, 3))
->x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 5, 3))
+>m1 : Symbol(m1, Decl(arityAndOrderCompatibility01.ts, 26, 3))
+>x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 6, 3))
var m2: [string] = y;
->m2 : Symbol(m2, Decl(arityAndOrderCompatibility01.ts, 25, 3))
->y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 6, 3))
+>m2 : Symbol(m2, Decl(arityAndOrderCompatibility01.ts, 27, 3))
+>y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 7, 3))
var m3: [string] = z;
->m3 : Symbol(m3, Decl(arityAndOrderCompatibility01.ts, 26, 3))
->z : Symbol(z, Decl(arityAndOrderCompatibility01.ts, 7, 3))
+>m3 : Symbol(m3, Decl(arityAndOrderCompatibility01.ts, 28, 3))
+>z : Symbol(z, Decl(arityAndOrderCompatibility01.ts, 8, 3))
var n1: [number, string] = x;
->n1 : Symbol(n1, Decl(arityAndOrderCompatibility01.ts, 27, 3))
->x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 5, 3))
+>n1 : Symbol(n1, Decl(arityAndOrderCompatibility01.ts, 29, 3))
+>x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 6, 3))
var n2: [number, string] = y;
->n2 : Symbol(n2, Decl(arityAndOrderCompatibility01.ts, 28, 3))
->y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 6, 3))
+>n2 : Symbol(n2, Decl(arityAndOrderCompatibility01.ts, 30, 3))
+>y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 7, 3))
var n3: [number, string] = z;
->n3 : Symbol(n3, Decl(arityAndOrderCompatibility01.ts, 29, 3))
->z : Symbol(z, Decl(arityAndOrderCompatibility01.ts, 7, 3))
+>n3 : Symbol(n3, Decl(arityAndOrderCompatibility01.ts, 31, 3))
+>z : Symbol(z, Decl(arityAndOrderCompatibility01.ts, 8, 3))
var o1: [string, number] = x;
->o1 : Symbol(o1, Decl(arityAndOrderCompatibility01.ts, 30, 3))
->x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 5, 3))
+>o1 : Symbol(o1, Decl(arityAndOrderCompatibility01.ts, 32, 3))
+>x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 6, 3))
var o2: [string, number] = y;
->o2 : Symbol(o2, Decl(arityAndOrderCompatibility01.ts, 31, 3))
->y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 6, 3))
+>o2 : Symbol(o2, Decl(arityAndOrderCompatibility01.ts, 33, 3))
+>y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 7, 3))
var o3: [string, number] = y;
->o3 : Symbol(o3, Decl(arityAndOrderCompatibility01.ts, 32, 3))
->y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 6, 3))
+>o3 : Symbol(o3, Decl(arityAndOrderCompatibility01.ts, 34, 3))
+>y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 7, 3))
diff --git a/tests/baselines/reference/arityAndOrderCompatibility01.types b/tests/baselines/reference/arityAndOrderCompatibility01.types
index 934c5c6966d..80e91fbd2e7 100644
--- a/tests/baselines/reference/arityAndOrderCompatibility01.types
+++ b/tests/baselines/reference/arityAndOrderCompatibility01.types
@@ -5,6 +5,8 @@ interface StrNum extends Array {
0: string;
1: number;
+ length: 2;
+>length : 2
}
var x: [string, number];
@@ -15,10 +17,12 @@ var y: StrNum
>StrNum : StrNum
var z: {
->z : { 0: string; 1: number; }
+>z : { 0: string; 1: number; length: 2; }
0: string;
1: number;
+ length: 2;
+>length : 2
}
var [a, b, c] = x;
@@ -37,7 +41,7 @@ var [g, h, i] = z;
>g : string
>h : number
>i : any
->z : { 0: string; 1: number; }
+>z : { 0: string; 1: number; length: 2; }
var j1: [number, number, number] = x;
>j1 : [number, number, number]
@@ -49,7 +53,7 @@ var j2: [number, number, number] = y;
var j3: [number, number, number] = z;
>j3 : [number, number, number]
->z : { 0: string; 1: number; }
+>z : { 0: string; 1: number; length: 2; }
var k1: [string, number, number] = x;
>k1 : [string, number, number]
@@ -61,7 +65,7 @@ var k2: [string, number, number] = y;
var k3: [string, number, number] = z;
>k3 : [string, number, number]
->z : { 0: string; 1: number; }
+>z : { 0: string; 1: number; length: 2; }
var l1: [number] = x;
>l1 : [number]
@@ -73,7 +77,7 @@ var l2: [number] = y;
var l3: [number] = z;
>l3 : [number]
->z : { 0: string; 1: number; }
+>z : { 0: string; 1: number; length: 2; }
var m1: [string] = x;
>m1 : [string]
@@ -85,7 +89,7 @@ var m2: [string] = y;
var m3: [string] = z;
>m3 : [string]
->z : { 0: string; 1: number; }
+>z : { 0: string; 1: number; length: 2; }
var n1: [number, string] = x;
>n1 : [number, string]
@@ -97,7 +101,7 @@ var n2: [number, string] = y;
var n3: [number, string] = z;
>n3 : [number, string]
->z : { 0: string; 1: number; }
+>z : { 0: string; 1: number; length: 2; }
var o1: [string, number] = x;
>o1 : [string, number]
diff --git a/tests/baselines/reference/arrayLiteralExpressionContextualTyping.errors.txt b/tests/baselines/reference/arrayLiteralExpressionContextualTyping.errors.txt
index 3e9777aea7c..8cb36b113a7 100644
--- a/tests/baselines/reference/arrayLiteralExpressionContextualTyping.errors.txt
+++ b/tests/baselines/reference/arrayLiteralExpressionContextualTyping.errors.txt
@@ -1,27 +1,37 @@
+tests/cases/conformance/expressions/contextualTyping/arrayLiteralExpressionContextualTyping.ts(6,5): error TS2322: Type '[number, number, number, number]' is not assignable to type '[number, number, number]'.
+ Types of property 'length' are incompatible.
+ Type '4' is not assignable to type '3'.
+tests/cases/conformance/expressions/contextualTyping/arrayLiteralExpressionContextualTyping.ts(7,5): error TS2322: Type '[number, number, number, string]' is not assignable to type '[string | number, string | number, string | number]'.
+ Types of property 'length' are incompatible.
+ Type '4' is not assignable to type '3'.
tests/cases/conformance/expressions/contextualTyping/arrayLiteralExpressionContextualTyping.ts(8,5): error TS2322: Type '[number, number, number, string]' is not assignable to type '[number, number, number]'.
- Types of property 'pop' are incompatible.
- Type '() => string | number' is not assignable to type '() => number'.
- Type 'string | number' is not assignable to type 'number'.
- Type 'string' is not assignable to type 'number'.
+ Types of property 'length' are incompatible.
+ Type '4' is not assignable to type '3'.
tests/cases/conformance/expressions/contextualTyping/arrayLiteralExpressionContextualTyping.ts(14,5): error TS2322: Type 'number[]' is not assignable to type '[number, number, number]'.
Property '0' is missing in type 'number[]'.
-==== tests/cases/conformance/expressions/contextualTyping/arrayLiteralExpressionContextualTyping.ts (2 errors) ====
+==== tests/cases/conformance/expressions/contextualTyping/arrayLiteralExpressionContextualTyping.ts (4 errors) ====
// In a contextually typed array literal expression containing no spread elements, an element expression at index N is contextually typed by
// the type of the property with the numeric name N in the contextual type, if any, or otherwise
// the numeric index type of the contextual type, if any.
var array = [1, 2, 3];
var array1 = [true, 2, 3]; // Contextual type by the numeric index type of the contextual type
var tup: [number, number, number] = [1, 2, 3, 4];
+ ~~~
+!!! error TS2322: Type '[number, number, number, number]' is not assignable to type '[number, number, number]'.
+!!! error TS2322: Types of property 'length' are incompatible.
+!!! error TS2322: Type '4' is not assignable to type '3'.
var tup1: [number|string, number|string, number|string] = [1, 2, 3, "string"];
+ ~~~~
+!!! error TS2322: Type '[number, number, number, string]' is not assignable to type '[string | number, string | number, string | number]'.
+!!! error TS2322: Types of property 'length' are incompatible.
+!!! error TS2322: Type '4' is not assignable to type '3'.
var tup2: [number, number, number] = [1, 2, 3, "string"]; // Error
~~~~
!!! error TS2322: Type '[number, number, number, string]' is not assignable to type '[number, number, number]'.
-!!! error TS2322: Types of property 'pop' are incompatible.
-!!! error TS2322: Type '() => string | number' is not assignable to type '() => number'.
-!!! error TS2322: Type 'string | number' is not assignable to type 'number'.
-!!! error TS2322: Type 'string' is not assignable to type 'number'.
+!!! error TS2322: Types of property 'length' are incompatible.
+!!! error TS2322: Type '4' is not assignable to type '3'.
// In a contextually typed array literal expression containing one or more spread elements,
// an element expression at index N is contextually typed by the numeric index type of the contextual type, if any.
diff --git a/tests/baselines/reference/arrayLiterals3.errors.txt b/tests/baselines/reference/arrayLiterals3.errors.txt
index 3ebf4174f51..8c36d7d59c1 100644
--- a/tests/baselines/reference/arrayLiterals3.errors.txt
+++ b/tests/baselines/reference/arrayLiterals3.errors.txt
@@ -3,10 +3,8 @@ tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(10,5): error
tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(11,5): error TS2322: Type '["string", number, boolean]' is not assignable to type '[boolean, string, number]'.
Type '"string"' is not assignable to type 'boolean'.
tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(17,5): error TS2322: Type '[number, number, string, boolean]' is not assignable to type '[number, number]'.
- Types of property 'pop' are incompatible.
- Type '() => string | number | boolean' is not assignable to type '() => number'.
- Type 'string | number | boolean' is not assignable to type 'number'.
- Type 'string' is not assignable to type 'number'.
+ Types of property 'length' are incompatible.
+ Type '4' is not assignable to type '2'.
tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(32,5): error TS2322: Type '(number[] | string[])[]' is not assignable to type 'tup'.
Property '0' is missing in type '(number[] | string[])[]'.
tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(33,5): error TS2322: Type 'number[]' is not assignable to type '[number, number, number]'.
@@ -46,10 +44,8 @@ tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(34,5): error
var [b1, b2]: [number, number] = [1, 2, "string", true];
~~~~~~~~
!!! error TS2322: Type '[number, number, string, boolean]' is not assignable to type '[number, number]'.
-!!! error TS2322: Types of property 'pop' are incompatible.
-!!! error TS2322: Type '() => string | number | boolean' is not assignable to type '() => number'.
-!!! error TS2322: Type 'string | number | boolean' is not assignable to type 'number'.
-!!! error TS2322: Type 'string' is not assignable to type 'number'.
+!!! error TS2322: Types of property 'length' are incompatible.
+!!! error TS2322: Type '4' is not assignable to type '2'.
// The resulting type an array literal expression is determined as follows:
// - the resulting type is an array type with an element type that is the union of the types of the
diff --git a/tests/baselines/reference/augmentedTypesClass3.js b/tests/baselines/reference/augmentedTypesClass3.js
index d2ad63161b5..045109f8587 100644
--- a/tests/baselines/reference/augmentedTypesClass3.js
+++ b/tests/baselines/reference/augmentedTypesClass3.js
@@ -46,4 +46,4 @@ var c5c = /** @class */ (function () {
c5c.prototype.foo = function () { };
return c5c;
}());
-//import c5c = require('');
+//import c5c = require('');
diff --git a/tests/baselines/reference/augmentedTypesEnum.js b/tests/baselines/reference/augmentedTypesEnum.js
index ff0ad93f817..edd4a92d767 100644
--- a/tests/baselines/reference/augmentedTypesEnum.js
+++ b/tests/baselines/reference/augmentedTypesEnum.js
@@ -100,4 +100,4 @@ var e6b;
})(e6b || (e6b = {})); // should be error
// enum then import, messes with error reporting
//enum e7 { One }
-//import e7 = require(''); // should be error
+//import e7 = require(''); // should be error
diff --git a/tests/baselines/reference/augmentedTypesEnum2.js b/tests/baselines/reference/augmentedTypesEnum2.js
index 66fc96b62a0..0e6e70df263 100644
--- a/tests/baselines/reference/augmentedTypesEnum2.js
+++ b/tests/baselines/reference/augmentedTypesEnum2.js
@@ -41,4 +41,4 @@ var e2 = /** @class */ (function () {
return e2;
}());
//enum then enum - covered
-//enum then import - covered
+//enum then import - covered
diff --git a/tests/baselines/reference/augmentedTypesFunction.js b/tests/baselines/reference/augmentedTypesFunction.js
index 3c6066e5bb4..a2dd4a664a3 100644
--- a/tests/baselines/reference/augmentedTypesFunction.js
+++ b/tests/baselines/reference/augmentedTypesFunction.js
@@ -79,4 +79,4 @@ function y5b() { }
function y5c() { }
// function then import, messes with other errors
//function y6() { }
-//import y6 = require('');
+//import y6 = require('');
diff --git a/tests/baselines/reference/augmentedTypesInterface.js b/tests/baselines/reference/augmentedTypesInterface.js
index b74da5bbfee..0409e157584 100644
--- a/tests/baselines/reference/augmentedTypesInterface.js
+++ b/tests/baselines/reference/augmentedTypesInterface.js
@@ -48,4 +48,4 @@ var i3;
i3[i3["One"] = 0] = "One";
})(i3 || (i3 = {}));
; // error
-//import i4 = require(''); // error
+//import i4 = require(''); // error
diff --git a/tests/baselines/reference/castingTuple.errors.txt b/tests/baselines/reference/castingTuple.errors.txt
index eb6aac5f463..a17f8c2b082 100644
--- a/tests/baselines/reference/castingTuple.errors.txt
+++ b/tests/baselines/reference/castingTuple.errors.txt
@@ -1,13 +1,21 @@
-tests/cases/conformance/types/tuple/castingTuple.ts(28,10): error TS2352: Type '[number, string]' cannot be converted to type '[number, number]'.
+tests/cases/conformance/types/tuple/castingTuple.ts(13,23): error TS2352: Type '[number, string]' cannot be converted to type '[number, string, boolean]'.
+ Property '2' is missing in type '[number, string]'.
+tests/cases/conformance/types/tuple/castingTuple.ts(14,15): error TS2352: Type '[number, string, boolean]' cannot be converted to type '[number, string]'.
+ Types of property 'length' are incompatible.
+ Type '3' is not comparable to type '2'.
+tests/cases/conformance/types/tuple/castingTuple.ts(15,14): error TS2352: Type '[number, string]' cannot be converted to type '[number, string, boolean]'.
+tests/cases/conformance/types/tuple/castingTuple.ts(18,21): error TS2352: Type '[C, D]' cannot be converted to type '[C, D, A]'.
+ Property '2' is missing in type '[C, D]'.
+tests/cases/conformance/types/tuple/castingTuple.ts(30,10): error TS2352: Type '[number, string]' cannot be converted to type '[number, number]'.
Type 'string' is not comparable to type 'number'.
-tests/cases/conformance/types/tuple/castingTuple.ts(29,10): error TS2352: Type '[C, D]' cannot be converted to type '[A, I]'.
+tests/cases/conformance/types/tuple/castingTuple.ts(31,10): error TS2352: Type '[C, D]' cannot be converted to type '[A, I]'.
Type 'C' is not comparable to type 'A'.
Property 'a' is missing in type 'C'.
-tests/cases/conformance/types/tuple/castingTuple.ts(30,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'array1' has type '{}[]' at tests/cases/conformance/types/tuple/castingTuple.ts 20:4, but here has type 'number[]'.
-tests/cases/conformance/types/tuple/castingTuple.ts(31,1): error TS2304: Cannot find name 't4'.
+tests/cases/conformance/types/tuple/castingTuple.ts(32,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'array1' has type '{}[]' at tests/cases/conformance/types/tuple/castingTuple.ts 22:4, but here has type 'number[]'.
+tests/cases/conformance/types/tuple/castingTuple.ts(33,1): error TS2304: Cannot find name 't4'.
-==== tests/cases/conformance/types/tuple/castingTuple.ts (4 errors) ====
+==== tests/cases/conformance/types/tuple/castingTuple.ts (8 errors) ====
interface I { }
class A { a = 10; }
class C implements I { c };
@@ -21,9 +29,23 @@ tests/cases/conformance/types/tuple/castingTuple.ts(31,1): error TS2304: Cannot
var numStrTuple: [number, string] = [5, "foo"];
var emptyObjTuple = <[{}, {}]>numStrTuple;
var numStrBoolTuple = <[number, string, boolean]>numStrTuple;
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+!!! error TS2352: Type '[number, string]' cannot be converted to type '[number, string, boolean]'.
+!!! error TS2352: Property '2' is missing in type '[number, string]'.
+ var shorter = numStrBoolTuple as [number, string]
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+!!! error TS2352: Type '[number, string, boolean]' cannot be converted to type '[number, string]'.
+!!! error TS2352: Types of property 'length' are incompatible.
+!!! error TS2352: Type '3' is not comparable to type '2'.
+ var longer = numStrTuple as [number, string, boolean]
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+!!! error TS2352: Type '[number, string]' cannot be converted to type '[number, string, boolean]'.
var classCDTuple: [C, D] = [new C(), new D()];
var interfaceIITuple = <[I, I]>classCDTuple;
var classCDATuple = <[C, D, A]>classCDTuple;
+ ~~~~~~~~~~~~~~~~~~~~~~~
+!!! error TS2352: Type '[C, D]' cannot be converted to type '[C, D, A]'.
+!!! error TS2352: Property '2' is missing in type '[C, D]'.
var eleFromCDA1 = classCDATuple[2]; // A
var eleFromCDA2 = classCDATuple[5]; // C | D | A
var t10: [E1, E2] = [E1.one, E2.one];
@@ -46,7 +68,7 @@ tests/cases/conformance/types/tuple/castingTuple.ts(31,1): error TS2304: Cannot
!!! error TS2352: Property 'a' is missing in type 'C'.
var array1 = numStrTuple;
~~~~~~
-!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'array1' has type '{}[]' at tests/cases/conformance/types/tuple/castingTuple.ts 20:4, but here has type 'number[]'.
+!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'array1' has type '{}[]' at tests/cases/conformance/types/tuple/castingTuple.ts 22:4, but here has type 'number[]'.
t4[2] = 10;
~~
!!! error TS2304: Cannot find name 't4'.
diff --git a/tests/baselines/reference/castingTuple.js b/tests/baselines/reference/castingTuple.js
index 3744d40d8a5..a94246a19b8 100644
--- a/tests/baselines/reference/castingTuple.js
+++ b/tests/baselines/reference/castingTuple.js
@@ -12,6 +12,8 @@ enum E2 { one }
var numStrTuple: [number, string] = [5, "foo"];
var emptyObjTuple = <[{}, {}]>numStrTuple;
var numStrBoolTuple = <[number, string, boolean]>numStrTuple;
+var shorter = numStrBoolTuple as [number, string]
+var longer = numStrTuple as [number, string, boolean]
var classCDTuple: [C, D] = [new C(), new D()];
var interfaceIITuple = <[I, I]>classCDTuple;
var classCDATuple = <[C, D, A]>classCDTuple;
@@ -89,6 +91,8 @@ var E2;
var numStrTuple = [5, "foo"];
var emptyObjTuple = numStrTuple;
var numStrBoolTuple = numStrTuple;
+var shorter = numStrBoolTuple;
+var longer = numStrTuple;
var classCDTuple = [new C(), new D()];
var interfaceIITuple = classCDTuple;
var classCDATuple = classCDTuple;
diff --git a/tests/baselines/reference/castingTuple.symbols b/tests/baselines/reference/castingTuple.symbols
index 61edfb4b376..3cf5face2a6 100644
--- a/tests/baselines/reference/castingTuple.symbols
+++ b/tests/baselines/reference/castingTuple.symbols
@@ -46,37 +46,45 @@ var numStrBoolTuple = <[number, string, boolean]>numStrTuple;
>numStrBoolTuple : Symbol(numStrBoolTuple, Decl(castingTuple.ts, 12, 3))
>numStrTuple : Symbol(numStrTuple, Decl(castingTuple.ts, 10, 3))
+var shorter = numStrBoolTuple as [number, string]
+>shorter : Symbol(shorter, Decl(castingTuple.ts, 13, 3))
+>numStrBoolTuple : Symbol(numStrBoolTuple, Decl(castingTuple.ts, 12, 3))
+
+var longer = numStrTuple as [number, string, boolean]
+>longer : Symbol(longer, Decl(castingTuple.ts, 14, 3))
+>numStrTuple : Symbol(numStrTuple, Decl(castingTuple.ts, 10, 3))
+
var classCDTuple: [C, D] = [new C(), new D()];
->classCDTuple : Symbol(classCDTuple, Decl(castingTuple.ts, 13, 3))
+>classCDTuple : Symbol(classCDTuple, Decl(castingTuple.ts, 15, 3))
>C : Symbol(C, Decl(castingTuple.ts, 1, 19))
>D : Symbol(D, Decl(castingTuple.ts, 2, 27))
>C : Symbol(C, Decl(castingTuple.ts, 1, 19))
>D : Symbol(D, Decl(castingTuple.ts, 2, 27))
var interfaceIITuple = <[I, I]>classCDTuple;
->interfaceIITuple : Symbol(interfaceIITuple, Decl(castingTuple.ts, 14, 3))
+>interfaceIITuple : Symbol(interfaceIITuple, Decl(castingTuple.ts, 16, 3))
>I : Symbol(I, Decl(castingTuple.ts, 0, 0))
>I : Symbol(I, Decl(castingTuple.ts, 0, 0))
->classCDTuple : Symbol(classCDTuple, Decl(castingTuple.ts, 13, 3))
+>classCDTuple : Symbol(classCDTuple, Decl(castingTuple.ts, 15, 3))
var classCDATuple = <[C, D, A]>classCDTuple;
->classCDATuple : Symbol(classCDATuple, Decl(castingTuple.ts, 15, 3))
+>classCDATuple : Symbol(classCDATuple, Decl(castingTuple.ts, 17, 3))
>C : Symbol(C, Decl(castingTuple.ts, 1, 19))
>D : Symbol(D, Decl(castingTuple.ts, 2, 27))
>A : Symbol(A, Decl(castingTuple.ts, 0, 15))
->classCDTuple : Symbol(classCDTuple, Decl(castingTuple.ts, 13, 3))
+>classCDTuple : Symbol(classCDTuple, Decl(castingTuple.ts, 15, 3))
var eleFromCDA1 = classCDATuple[2]; // A
->eleFromCDA1 : Symbol(eleFromCDA1, Decl(castingTuple.ts, 16, 3))
->classCDATuple : Symbol(classCDATuple, Decl(castingTuple.ts, 15, 3))
+>eleFromCDA1 : Symbol(eleFromCDA1, Decl(castingTuple.ts, 18, 3))
+>classCDATuple : Symbol(classCDATuple, Decl(castingTuple.ts, 17, 3))
>2 : Symbol(2)
var eleFromCDA2 = classCDATuple[5]; // C | D | A
->eleFromCDA2 : Symbol(eleFromCDA2, Decl(castingTuple.ts, 17, 3))
->classCDATuple : Symbol(classCDATuple, Decl(castingTuple.ts, 15, 3))
+>eleFromCDA2 : Symbol(eleFromCDA2, Decl(castingTuple.ts, 19, 3))
+>classCDATuple : Symbol(classCDATuple, Decl(castingTuple.ts, 17, 3))
var t10: [E1, E2] = [E1.one, E2.one];
->t10 : Symbol(t10, Decl(castingTuple.ts, 18, 3))
+>t10 : Symbol(t10, Decl(castingTuple.ts, 20, 3))
>E1 : Symbol(E1, Decl(castingTuple.ts, 5, 24))
>E2 : Symbol(E2, Decl(castingTuple.ts, 6, 15))
>E1.one : Symbol(E1.one, Decl(castingTuple.ts, 6, 9))
@@ -87,45 +95,45 @@ var t10: [E1, E2] = [E1.one, E2.one];
>one : Symbol(E2.one, Decl(castingTuple.ts, 7, 9))
var t11 = <[number, number]>t10;
->t11 : Symbol(t11, Decl(castingTuple.ts, 19, 3))
->t10 : Symbol(t10, Decl(castingTuple.ts, 18, 3))
+>t11 : Symbol(t11, Decl(castingTuple.ts, 21, 3))
+>t10 : Symbol(t10, Decl(castingTuple.ts, 20, 3))
var array1 = <{}[]>emptyObjTuple;
->array1 : Symbol(array1, Decl(castingTuple.ts, 20, 3), Decl(castingTuple.ts, 29, 3))
+>array1 : Symbol(array1, Decl(castingTuple.ts, 22, 3), Decl(castingTuple.ts, 31, 3))
>emptyObjTuple : Symbol(emptyObjTuple, Decl(castingTuple.ts, 11, 3))
var unionTuple: [C, string | number] = [new C(), "foo"];
->unionTuple : Symbol(unionTuple, Decl(castingTuple.ts, 21, 3))
+>unionTuple : Symbol(unionTuple, Decl(castingTuple.ts, 23, 3))
>C : Symbol(C, Decl(castingTuple.ts, 1, 19))
>C : Symbol(C, Decl(castingTuple.ts, 1, 19))
var unionTuple2: [C, string | number, D] = [new C(), "foo", new D()];
->unionTuple2 : Symbol(unionTuple2, Decl(castingTuple.ts, 22, 3))
+>unionTuple2 : Symbol(unionTuple2, Decl(castingTuple.ts, 24, 3))
>C : Symbol(C, Decl(castingTuple.ts, 1, 19))
>D : Symbol(D, Decl(castingTuple.ts, 2, 27))
>C : Symbol(C, Decl(castingTuple.ts, 1, 19))
>D : Symbol(D, Decl(castingTuple.ts, 2, 27))
var unionTuple3: [number, string| number] = [10, "foo"];
->unionTuple3 : Symbol(unionTuple3, Decl(castingTuple.ts, 23, 3))
+>unionTuple3 : Symbol(unionTuple3, Decl(castingTuple.ts, 25, 3))
var unionTuple4 = <[number, number]>unionTuple3;
->unionTuple4 : Symbol(unionTuple4, Decl(castingTuple.ts, 24, 3))
->unionTuple3 : Symbol(unionTuple3, Decl(castingTuple.ts, 23, 3))
+>unionTuple4 : Symbol(unionTuple4, Decl(castingTuple.ts, 26, 3))
+>unionTuple3 : Symbol(unionTuple3, Decl(castingTuple.ts, 25, 3))
// error
var t3 = <[number, number]>numStrTuple;
->t3 : Symbol(t3, Decl(castingTuple.ts, 27, 3))
+>t3 : Symbol(t3, Decl(castingTuple.ts, 29, 3))
>numStrTuple : Symbol(numStrTuple, Decl(castingTuple.ts, 10, 3))
var t9 = <[A, I]>classCDTuple;
->t9 : Symbol(t9, Decl(castingTuple.ts, 28, 3))
+>t9 : Symbol(t9, Decl(castingTuple.ts, 30, 3))
>A : Symbol(A, Decl(castingTuple.ts, 0, 15))
>I : Symbol(I, Decl(castingTuple.ts, 0, 0))
->classCDTuple : Symbol(classCDTuple, Decl(castingTuple.ts, 13, 3))
+>classCDTuple : Symbol(classCDTuple, Decl(castingTuple.ts, 15, 3))
var array1 = numStrTuple;
->array1 : Symbol(array1, Decl(castingTuple.ts, 20, 3), Decl(castingTuple.ts, 29, 3))
+>array1 : Symbol(array1, Decl(castingTuple.ts, 22, 3), Decl(castingTuple.ts, 31, 3))
>numStrTuple : Symbol(numStrTuple, Decl(castingTuple.ts, 10, 3))
t4[2] = 10;
diff --git a/tests/baselines/reference/castingTuple.types b/tests/baselines/reference/castingTuple.types
index 23d2e51a576..0b9aa0a1487 100644
--- a/tests/baselines/reference/castingTuple.types
+++ b/tests/baselines/reference/castingTuple.types
@@ -52,6 +52,16 @@ var numStrBoolTuple = <[number, string, boolean]>numStrTuple;
><[number, string, boolean]>numStrTuple : [number, string, boolean]
>numStrTuple : [number, string]
+var shorter = numStrBoolTuple as [number, string]
+>shorter : [number, string]
+>numStrBoolTuple as [number, string] : [number, string]
+>numStrBoolTuple : [number, string, boolean]
+
+var longer = numStrTuple as [number, string, boolean]
+>longer : [number, string, boolean]
+>numStrTuple as [number, string, boolean] : [number, string, boolean]
+>numStrTuple : [number, string]
+
var classCDTuple: [C, D] = [new C(), new D()];
>classCDTuple : [C, D]
>C : C
diff --git a/tests/baselines/reference/classAbstractConstructorAssignability.errors.txt b/tests/baselines/reference/classAbstractConstructorAssignability.errors.txt
index 0f834665346..3ad45cc2b04 100644
--- a/tests/baselines/reference/classAbstractConstructorAssignability.errors.txt
+++ b/tests/baselines/reference/classAbstractConstructorAssignability.errors.txt
@@ -2,7 +2,7 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst
Cannot assign an abstract constructor type to a non-abstract constructor type.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractConstructorAssignability.ts(9,5): error TS2322: Type 'typeof B' is not assignable to type 'typeof C'.
Cannot assign an abstract constructor type to a non-abstract constructor type.
-tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractConstructorAssignability.ts(12,1): error TS2511: Cannot create an instance of the abstract class 'B'.
+tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractConstructorAssignability.ts(12,1): error TS2511: Cannot create an instance of an abstract class.
==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractConstructorAssignability.ts (3 errors) ====
@@ -25,5 +25,5 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst
new AA;
new BB;
~~~~~~
-!!! error TS2511: Cannot create an instance of the abstract class 'B'.
+!!! error TS2511: Cannot create an instance of an abstract class.
new CC;
\ No newline at end of file
diff --git a/tests/baselines/reference/classAbstractFactoryFunction.errors.txt b/tests/baselines/reference/classAbstractFactoryFunction.errors.txt
index 1b281f35260..2e7b3ad8f46 100644
--- a/tests/baselines/reference/classAbstractFactoryFunction.errors.txt
+++ b/tests/baselines/reference/classAbstractFactoryFunction.errors.txt
@@ -1,4 +1,4 @@
-tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractFactoryFunction.ts(9,12): error TS2511: Cannot create an instance of the abstract class 'B'.
+tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractFactoryFunction.ts(9,12): error TS2511: Cannot create an instance of an abstract class.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractFactoryFunction.ts(13,6): error TS2345: Argument of type 'typeof B' is not assignable to parameter of type 'typeof A'.
Cannot assign an abstract constructor type to a non-abstract constructor type.
@@ -14,7 +14,7 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst
function NewB(Factory: typeof B) {
return new B;
~~~~~
-!!! error TS2511: Cannot create an instance of the abstract class 'B'.
+!!! error TS2511: Cannot create an instance of an abstract class.
}
NewA(A);
diff --git a/tests/baselines/reference/classAbstractImportInstantiation.errors.txt b/tests/baselines/reference/classAbstractImportInstantiation.errors.txt
index 76110afa4ff..a01c75b6dae 100644
--- a/tests/baselines/reference/classAbstractImportInstantiation.errors.txt
+++ b/tests/baselines/reference/classAbstractImportInstantiation.errors.txt
@@ -1,5 +1,5 @@
-tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractImportInstantiation.ts(4,5): error TS2511: Cannot create an instance of the abstract class 'A'.
-tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractImportInstantiation.ts(9,1): error TS2511: Cannot create an instance of the abstract class 'A'.
+tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractImportInstantiation.ts(4,5): error TS2511: Cannot create an instance of an abstract class.
+tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractImportInstantiation.ts(9,1): error TS2511: Cannot create an instance of an abstract class.
==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractImportInstantiation.ts (2 errors) ====
@@ -8,12 +8,12 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst
new A;
~~~~~
-!!! error TS2511: Cannot create an instance of the abstract class 'A'.
+!!! error TS2511: Cannot create an instance of an abstract class.
}
import myA = M.A;
new myA;
~~~~~~~
-!!! error TS2511: Cannot create an instance of the abstract class 'A'.
+!!! error TS2511: Cannot create an instance of an abstract class.
\ No newline at end of file
diff --git a/tests/baselines/reference/classAbstractInAModule.errors.txt b/tests/baselines/reference/classAbstractInAModule.errors.txt
index 426da866087..18bb6d4391e 100644
--- a/tests/baselines/reference/classAbstractInAModule.errors.txt
+++ b/tests/baselines/reference/classAbstractInAModule.errors.txt
@@ -1,4 +1,4 @@
-tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInAModule.ts(6,1): error TS2511: Cannot create an instance of the abstract class 'A'.
+tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInAModule.ts(6,1): error TS2511: Cannot create an instance of an abstract class.
==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInAModule.ts (1 errors) ====
@@ -9,5 +9,5 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst
new M.A;
~~~~~~~
-!!! error TS2511: Cannot create an instance of the abstract class 'A'.
+!!! error TS2511: Cannot create an instance of an abstract class.
new M.B;
\ No newline at end of file
diff --git a/tests/baselines/reference/classAbstractInstantiations1.errors.txt b/tests/baselines/reference/classAbstractInstantiations1.errors.txt
index d1c159858a4..bc696ce19db 100644
--- a/tests/baselines/reference/classAbstractInstantiations1.errors.txt
+++ b/tests/baselines/reference/classAbstractInstantiations1.errors.txt
@@ -1,6 +1,6 @@
-tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations1.ts(11,1): error TS2511: Cannot create an instance of the abstract class 'A'.
-tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations1.ts(12,1): error TS2511: Cannot create an instance of the abstract class 'A'.
-tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations1.ts(14,1): error TS2511: Cannot create an instance of the abstract class 'C'.
+tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations1.ts(11,1): error TS2511: Cannot create an instance of an abstract class.
+tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations1.ts(12,1): error TS2511: Cannot create an instance of an abstract class.
+tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations1.ts(14,1): error TS2511: Cannot create an instance of an abstract class.
==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations1.ts (3 errors) ====
@@ -16,14 +16,14 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst
new A;
~~~~~
-!!! error TS2511: Cannot create an instance of the abstract class 'A'.
+!!! error TS2511: Cannot create an instance of an abstract class.
new A(1); // should report 1 error
~~~~~~~~
-!!! error TS2511: Cannot create an instance of the abstract class 'A'.
+!!! error TS2511: Cannot create an instance of an abstract class.
new B;
new C;
~~~~~
-!!! error TS2511: Cannot create an instance of the abstract class 'C'.
+!!! error TS2511: Cannot create an instance of an abstract class.
var a : A;
var b : B;
diff --git a/tests/baselines/reference/classAbstractInstantiations2.errors.txt b/tests/baselines/reference/classAbstractInstantiations2.errors.txt
index 15b63a6d3e8..d05e05517b2 100644
--- a/tests/baselines/reference/classAbstractInstantiations2.errors.txt
+++ b/tests/baselines/reference/classAbstractInstantiations2.errors.txt
@@ -1,8 +1,8 @@
-tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(10,1): error TS2511: Cannot create an instance of the abstract class 'B'.
+tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(10,1): error TS2511: Cannot create an instance of an abstract class.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(13,5): error TS2322: Type 'typeof B' is not assignable to type 'typeof A'.
Cannot assign an abstract constructor type to a non-abstract constructor type.
-tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(17,5): error TS2511: Cannot create an instance of the abstract class 'B'.
-tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(21,1): error TS2511: Cannot create an instance of the abstract class 'B'.
+tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(17,5): error TS2511: Cannot create an instance of an abstract class.
+tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(21,1): error TS2511: Cannot create an instance of an abstract class.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(23,15): error TS2449: Class 'C' used before its declaration.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(26,7): error TS2515: Non-abstract class 'C' does not implement inherited abstract member 'bar' from class 'B'.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(46,5): error TS2391: Function implementation is missing or not immediately following the declaration.
@@ -22,7 +22,7 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst
new B; // error
~~~~~
-!!! error TS2511: Cannot create an instance of the abstract class 'B'.
+!!! error TS2511: Cannot create an instance of an abstract class.
var BB: typeof B = B;
var AA: typeof A = BB; // error, AA is not of abstract type.
@@ -34,13 +34,13 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst
function constructB(Factory : typeof B) {
new Factory; // error -- Factory is of type typeof B.
~~~~~~~~~~~
-!!! error TS2511: Cannot create an instance of the abstract class 'B'.
+!!! error TS2511: Cannot create an instance of an abstract class.
}
var BB = B;
new BB; // error -- BB is of type typeof B.
~~~~~~
-!!! error TS2511: Cannot create an instance of the abstract class 'B'.
+!!! error TS2511: Cannot create an instance of an abstract class.
var x : any = C;
~
diff --git a/tests/baselines/reference/classAbstractMergedDeclaration.errors.txt b/tests/baselines/reference/classAbstractMergedDeclaration.errors.txt
index 3e18d8796fb..fc15ca410e8 100644
--- a/tests/baselines/reference/classAbstractMergedDeclaration.errors.txt
+++ b/tests/baselines/reference/classAbstractMergedDeclaration.errors.txt
@@ -6,14 +6,14 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(26,15): error TS2300: Duplicate identifier 'DCC1'.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(28,15): error TS2300: Duplicate identifier 'DCC2'.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(29,24): error TS2300: Duplicate identifier 'DCC2'.
-tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(31,1): error TS2511: Cannot create an instance of the abstract class 'CM'.
-tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(32,1): error TS2511: Cannot create an instance of the abstract class 'MC'.
-tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(33,1): error TS2511: Cannot create an instance of the abstract class 'CI'.
-tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(34,1): error TS2511: Cannot create an instance of the abstract class 'IC'.
-tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(35,1): error TS2511: Cannot create an instance of the abstract class 'CC1'.
-tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(37,1): error TS2511: Cannot create an instance of the abstract class 'DCI'.
-tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(38,1): error TS2511: Cannot create an instance of the abstract class 'DIC'.
-tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(39,1): error TS2511: Cannot create an instance of the abstract class 'DCC1'.
+tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(31,1): error TS2511: Cannot create an instance of an abstract class.
+tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(32,1): error TS2511: Cannot create an instance of an abstract class.
+tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(33,1): error TS2511: Cannot create an instance of an abstract class.
+tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(34,1): error TS2511: Cannot create an instance of an abstract class.
+tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(35,1): error TS2511: Cannot create an instance of an abstract class.
+tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(37,1): error TS2511: Cannot create an instance of an abstract class.
+tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(38,1): error TS2511: Cannot create an instance of an abstract class.
+tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(39,1): error TS2511: Cannot create an instance of an abstract class.
==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts (16 errors) ====
@@ -65,27 +65,27 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst
new CM;
~~~~~~
-!!! error TS2511: Cannot create an instance of the abstract class 'CM'.
+!!! error TS2511: Cannot create an instance of an abstract class.
new MC;
~~~~~~
-!!! error TS2511: Cannot create an instance of the abstract class 'MC'.
+!!! error TS2511: Cannot create an instance of an abstract class.
new CI;
~~~~~~
-!!! error TS2511: Cannot create an instance of the abstract class 'CI'.
+!!! error TS2511: Cannot create an instance of an abstract class.
new IC;
~~~~~~
-!!! error TS2511: Cannot create an instance of the abstract class 'IC'.
+!!! error TS2511: Cannot create an instance of an abstract class.
new CC1;
~~~~~~~
-!!! error TS2511: Cannot create an instance of the abstract class 'CC1'.
+!!! error TS2511: Cannot create an instance of an abstract class.
new CC2;
new DCI;
~~~~~~~
-!!! error TS2511: Cannot create an instance of the abstract class 'DCI'.
+!!! error TS2511: Cannot create an instance of an abstract class.
new DIC;
~~~~~~~
-!!! error TS2511: Cannot create an instance of the abstract class 'DIC'.
+!!! error TS2511: Cannot create an instance of an abstract class.
new DCC1;
~~~~~~~~
-!!! error TS2511: Cannot create an instance of the abstract class 'DCC1'.
+!!! error TS2511: Cannot create an instance of an abstract class.
new DCC2;
\ No newline at end of file
diff --git a/tests/baselines/reference/classAbstractSingleLineDecl.errors.txt b/tests/baselines/reference/classAbstractSingleLineDecl.errors.txt
index 0670ea108ea..1bdabfefe6d 100644
--- a/tests/baselines/reference/classAbstractSingleLineDecl.errors.txt
+++ b/tests/baselines/reference/classAbstractSingleLineDecl.errors.txt
@@ -1,6 +1,6 @@
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractSingleLineDecl.ts(3,1): error TS2304: Cannot find name 'abstract'.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractSingleLineDecl.ts(6,1): error TS2304: Cannot find name 'abstract'.
-tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractSingleLineDecl.ts(10,1): error TS2511: Cannot create an instance of the abstract class 'A'.
+tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractSingleLineDecl.ts(10,1): error TS2511: Cannot create an instance of an abstract class.
==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractSingleLineDecl.ts (3 errors) ====
@@ -19,6 +19,6 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst
new A;
~~~~~
-!!! error TS2511: Cannot create an instance of the abstract class 'A'.
+!!! error TS2511: Cannot create an instance of an abstract class.
new B;
new C;
\ No newline at end of file
diff --git a/tests/baselines/reference/classAbstractUsingAbstractMethod1.errors.txt b/tests/baselines/reference/classAbstractUsingAbstractMethod1.errors.txt
index df3682a36af..282fa3a53aa 100644
--- a/tests/baselines/reference/classAbstractUsingAbstractMethod1.errors.txt
+++ b/tests/baselines/reference/classAbstractUsingAbstractMethod1.errors.txt
@@ -1,4 +1,4 @@
-tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractUsingAbstractMethod1.ts(16,5): error TS2511: Cannot create an instance of the abstract class 'C'.
+tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractUsingAbstractMethod1.ts(16,5): error TS2511: Cannot create an instance of an abstract class.
==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractUsingAbstractMethod1.ts (1 errors) ====
@@ -19,5 +19,5 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst
a = new C; // error, cannot instantiate abstract class.
~~~~~
-!!! error TS2511: Cannot create an instance of the abstract class 'C'.
+!!! error TS2511: Cannot create an instance of an abstract class.
a.foo();
\ No newline at end of file
diff --git a/tests/baselines/reference/commentEmitAtEndOfFile1.js b/tests/baselines/reference/commentEmitAtEndOfFile1.js
index 1be031fa84a..d6ba7b158d6 100644
--- a/tests/baselines/reference/commentEmitAtEndOfFile1.js
+++ b/tests/baselines/reference/commentEmitAtEndOfFile1.js
@@ -18,4 +18,4 @@ var foo;
(function (foo) {
function bar() { }
})(foo || (foo = {}));
-// test #4
+// test #4
diff --git a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnCallSignature.js b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnCallSignature.js
index 079a1e276fb..bcd87998f83 100644
--- a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnCallSignature.js
+++ b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnCallSignature.js
@@ -505,4 +505,4 @@ var r8b8 = b8 !== a8;
var r8b9 = b9 !== a9;
var r8b10 = b10 !== a10;
var r8b11 = b11 !== a11;
-//var r8b12 = b12 !== a12;
+//var r8b12 = b12 !== a12;
diff --git a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnConstructorSignature.js b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnConstructorSignature.js
index 38097a936e3..1721f564865 100644
--- a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnConstructorSignature.js
+++ b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnConstructorSignature.js
@@ -431,4 +431,4 @@ var r8b6 = b6 !== a6;
var r8b7 = b7 !== a7;
var r8b8 = b8 !== a8;
var r8b9 = b9 !== a9;
-//var r8b10 = b10 !== a10;
+//var r8b10 = b10 !== a10;
diff --git a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedCallSignature.js b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedCallSignature.js
index 87359ea0074..72dd4be0afc 100644
--- a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedCallSignature.js
+++ b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedCallSignature.js
@@ -320,4 +320,4 @@ var r8b3 = b3 !== a3;
var r8b4 = b4 !== a4;
var r8b5 = b5 !== a5;
var r8b6 = b6 !== a6;
-//var r8b7 = b7 !== a7;
+//var r8b7 = b7 !== a7;
diff --git a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedConstructorSignature.js b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedConstructorSignature.js
index fcfbfa4bfbc..19183773406 100644
--- a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedConstructorSignature.js
+++ b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedConstructorSignature.js
@@ -320,4 +320,4 @@ var r8b3 = b3 !== a3;
var r8b4 = b4 !== a4;
var r8b5 = b5 !== a5;
var r8b6 = b6 !== a6;
-//var r8b7 = b7 !== a7;
+//var r8b7 = b7 !== a7;
diff --git a/tests/baselines/reference/contextualTypeWithTuple.errors.txt b/tests/baselines/reference/contextualTypeWithTuple.errors.txt
index a488d8c7648..58a90919c5b 100644
--- a/tests/baselines/reference/contextualTypeWithTuple.errors.txt
+++ b/tests/baselines/reference/contextualTypeWithTuple.errors.txt
@@ -1,8 +1,6 @@
tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(3,5): error TS2322: Type '[number, string, boolean]' is not assignable to type '[number, string]'.
- Types of property 'pop' are incompatible.
- Type '() => string | number | boolean' is not assignable to type '() => string | number'.
- Type 'string | number | boolean' is not assignable to type 'string | number'.
- Type 'true' is not assignable to type 'string | number'.
+ Types of property 'length' are incompatible.
+ Type '3' is not assignable to type '2'.
tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(15,1): error TS2322: Type '[number, string, boolean]' is not assignable to type '[number, string]'.
tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(18,1): error TS2322: Type '[{}, number]' is not assignable to type '[{ a: string; }, number]'.
Type '{}' is not assignable to type '{ a: string; }'.
@@ -10,10 +8,11 @@ tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(18,1): error TS23
tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(19,1): error TS2322: Type '[number, string]' is not assignable to type '[number, string, boolean]'.
Property '2' is missing in type '[number, string]'.
tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(20,5): error TS2322: Type '[string, string, number]' is not assignable to type '[string, string]'.
- Types of property 'pop' are incompatible.
- Type '() => string | number' is not assignable to type '() => string'.
- Type 'string | number' is not assignable to type 'string'.
- Type 'number' is not assignable to type 'string'.
+ Types of property 'length' are incompatible.
+ Type '3' is not assignable to type '2'.
+tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(23,1): error TS2322: Type '[C, string | number, D]' is not assignable to type '[C, string | number]'.
+ Types of property 'length' are incompatible.
+ Type '3' is not assignable to type '2'.
tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(24,1): error TS2322: Type '[C, string | number]' is not assignable to type '[C, string | number, D]'.
Property '2' is missing in type '[C, string | number]'.
tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(25,1): error TS2322: Type '[number, string | number]' is not assignable to type '[number, string]'.
@@ -21,16 +20,14 @@ tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(25,1): error TS23
Type 'number' is not assignable to type 'string'.
-==== tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts (7 errors) ====
+==== tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts (8 errors) ====
// no error
var numStrTuple: [number, string] = [5, "hello"];
var numStrTuple2: [number, string] = [5, "foo", true];
~~~~~~~~~~~~
!!! error TS2322: Type '[number, string, boolean]' is not assignable to type '[number, string]'.
-!!! error TS2322: Types of property 'pop' are incompatible.
-!!! error TS2322: Type '() => string | number | boolean' is not assignable to type '() => string | number'.
-!!! error TS2322: Type 'string | number | boolean' is not assignable to type 'string | number'.
-!!! error TS2322: Type 'true' is not assignable to type 'string | number'.
+!!! error TS2322: Types of property 'length' are incompatible.
+!!! error TS2322: Type '3' is not assignable to type '2'.
var numStrBoolTuple: [number, string, boolean] = [5, "foo", true];
var objNumTuple: [{ a: string }, number] = [{ a: "world" }, 5];
var strTupleTuple: [string, [number, {}]] = ["bar", [5, { x: 1, y: 1 }]];
@@ -59,13 +56,15 @@ tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(25,1): error TS23
var strStrTuple: [string, string] = ["foo", "bar", 5];
~~~~~~~~~~~
!!! error TS2322: Type '[string, string, number]' is not assignable to type '[string, string]'.
-!!! error TS2322: Types of property 'pop' are incompatible.
-!!! error TS2322: Type '() => string | number' is not assignable to type '() => string'.
-!!! error TS2322: Type 'string | number' is not assignable to type 'string'.
-!!! error TS2322: Type 'number' is not assignable to type 'string'.
+!!! error TS2322: Types of property 'length' are incompatible.
+!!! error TS2322: Type '3' is not assignable to type '2'.
unionTuple = unionTuple1;
unionTuple = unionTuple2;
+ ~~~~~~~~~~
+!!! error TS2322: Type '[C, string | number, D]' is not assignable to type '[C, string | number]'.
+!!! error TS2322: Types of property 'length' are incompatible.
+!!! error TS2322: Type '3' is not assignable to type '2'.
unionTuple2 = unionTuple;
~~~~~~~~~~~
!!! error TS2322: Type '[C, string | number]' is not assignable to type '[C, string | number, D]'.
diff --git a/tests/baselines/reference/controlFlowStringIndex.js b/tests/baselines/reference/controlFlowStringIndex.js
new file mode 100644
index 00000000000..db4d4a30ab9
--- /dev/null
+++ b/tests/baselines/reference/controlFlowStringIndex.js
@@ -0,0 +1,20 @@
+//// [controlFlowStringIndex.ts]
+type A = {
+ other: number | null;
+ [index: string]: number | null
+};
+declare const value: A;
+if (value.foo !== null) {
+ value.foo.toExponential()
+ value.other // should still be number | null
+ value.bar // should still be number | null
+}
+
+
+//// [controlFlowStringIndex.js]
+"use strict";
+if (value.foo !== null) {
+ value.foo.toExponential();
+ value.other; // should still be number | null
+ value.bar; // should still be number | null
+}
diff --git a/tests/baselines/reference/controlFlowStringIndex.symbols b/tests/baselines/reference/controlFlowStringIndex.symbols
new file mode 100644
index 00000000000..5c7d626d4a7
--- /dev/null
+++ b/tests/baselines/reference/controlFlowStringIndex.symbols
@@ -0,0 +1,32 @@
+=== tests/cases/conformance/controlFlow/controlFlowStringIndex.ts ===
+type A = {
+>A : Symbol(A, Decl(controlFlowStringIndex.ts, 0, 0))
+
+ other: number | null;
+>other : Symbol(other, Decl(controlFlowStringIndex.ts, 0, 10))
+
+ [index: string]: number | null
+>index : Symbol(index, Decl(controlFlowStringIndex.ts, 2, 5))
+
+};
+declare const value: A;
+>value : Symbol(value, Decl(controlFlowStringIndex.ts, 4, 13))
+>A : Symbol(A, Decl(controlFlowStringIndex.ts, 0, 0))
+
+if (value.foo !== null) {
+>value : Symbol(value, Decl(controlFlowStringIndex.ts, 4, 13))
+
+ value.foo.toExponential()
+>value.foo.toExponential : Symbol(Number.toExponential, Decl(lib.d.ts, --, --))
+>value : Symbol(value, Decl(controlFlowStringIndex.ts, 4, 13))
+>toExponential : Symbol(Number.toExponential, Decl(lib.d.ts, --, --))
+
+ value.other // should still be number | null
+>value.other : Symbol(other, Decl(controlFlowStringIndex.ts, 0, 10))
+>value : Symbol(value, Decl(controlFlowStringIndex.ts, 4, 13))
+>other : Symbol(other, Decl(controlFlowStringIndex.ts, 0, 10))
+
+ value.bar // should still be number | null
+>value : Symbol(value, Decl(controlFlowStringIndex.ts, 4, 13))
+}
+
diff --git a/tests/baselines/reference/controlFlowStringIndex.types b/tests/baselines/reference/controlFlowStringIndex.types
new file mode 100644
index 00000000000..8c5f82cbf80
--- /dev/null
+++ b/tests/baselines/reference/controlFlowStringIndex.types
@@ -0,0 +1,43 @@
+=== tests/cases/conformance/controlFlow/controlFlowStringIndex.ts ===
+type A = {
+>A : A
+
+ other: number | null;
+>other : number | null
+>null : null
+
+ [index: string]: number | null
+>index : string
+>null : null
+
+};
+declare const value: A;
+>value : A
+>A : A
+
+if (value.foo !== null) {
+>value.foo !== null : boolean
+>value.foo : number | null
+>value : A
+>foo : number | null
+>null : null
+
+ value.foo.toExponential()
+>value.foo.toExponential() : string
+>value.foo.toExponential : (fractionDigits?: number | undefined) => string
+>value.foo : number
+>value : A
+>foo : number
+>toExponential : (fractionDigits?: number | undefined) => string
+
+ value.other // should still be number | null
+>value.other : number | null
+>value : A
+>other : number | null
+
+ value.bar // should still be number | null
+>value.bar : number | null
+>value : A
+>bar : number | null
+}
+
diff --git a/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.errors.txt b/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.errors.txt
index 771960ba788..4ea18c15901 100644
--- a/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.errors.txt
+++ b/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.errors.txt
@@ -1,13 +1,13 @@
-tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(15,21): error TS4043: Return type of public property getter from exported class has or is using private name 'private1'.
-tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(20,13): error TS4043: Return type of public property getter from exported class has or is using private name 'private1'.
-tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(25,25): error TS4037: Parameter 'foo3' of public property setter from exported class has or is using private name 'private1'.
-tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(32,25): error TS4037: Parameter 'foo4' of public property setter from exported class has or is using private name 'private1'.
-tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(36,21): error TS4043: Return type of public property getter from exported class has or is using private name 'private1'.
-tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(71,23): error TS4043: Return type of public property getter from exported class has or is using private name 'm2'.
-tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(76,13): error TS4042: Return type of public property getter from exported class has or is using name 'm2.public2' from private module 'm2'.
-tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(81,27): error TS4037: Parameter 'foo113' of public property setter from exported class has or is using private name 'm2'.
-tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(88,27): error TS4037: Parameter 'foo114' of public property setter from exported class has or is using private name 'm2'.
-tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(92,23): error TS4043: Return type of public property getter from exported class has or is using private name 'm2'.
+tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(15,21): error TS4043: Return type of public getter 'foo1' from exported class has or is using private name 'private1'.
+tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(20,13): error TS4043: Return type of public getter 'foo2' from exported class has or is using private name 'private1'.
+tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(25,25): error TS4037: Parameter type of public setter 'foo3' from exported class has or is using private name 'private1'.
+tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(32,25): error TS4037: Parameter type of public setter 'foo4' from exported class has or is using private name 'private1'.
+tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(36,21): error TS4043: Return type of public getter 'foo5' from exported class has or is using private name 'private1'.
+tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(71,23): error TS4043: Return type of public getter 'foo111' from exported class has or is using private name 'm2'.
+tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(76,13): error TS4042: Return type of public getter 'foo112' from exported class has or is using name 'm2.public2' from private module 'm2'.
+tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(81,27): error TS4037: Parameter type of public setter 'foo113' from exported class has or is using private name 'm2'.
+tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(88,27): error TS4037: Parameter type of public setter 'foo114' from exported class has or is using private name 'm2'.
+tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(92,23): error TS4043: Return type of public getter 'foo115' from exported class has or is using private name 'm2'.
==== tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts (10 errors) ====
@@ -22,26 +22,26 @@ tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(92,23): e
export class public2 {
}
}
-
+
export class c {
// getter with annotation
get foo1(): private1 {
~~~~~~~~
-!!! error TS4043: Return type of public property getter from exported class has or is using private name 'private1'.
+!!! error TS4043: Return type of public getter 'foo1' from exported class has or is using private name 'private1'.
return;
}
// getter without annotation
get foo2() {
~~~~
-!!! error TS4043: Return type of public property getter from exported class has or is using private name 'private1'.
+!!! error TS4043: Return type of public getter 'foo2' from exported class has or is using private name 'private1'.
return new private1();
}
// setter with annotation
set foo3(param: private1) {
~~~~~~~~
-!!! error TS4037: Parameter 'foo3' of public property setter from exported class has or is using private name 'private1'.
+!!! error TS4037: Parameter type of public setter 'foo3' from exported class has or is using private name 'private1'.
}
// Both - getter without annotation, setter with annotation
@@ -50,18 +50,18 @@ tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(92,23): e
}
set foo4(param: private1) {
~~~~~~~~
-!!! error TS4037: Parameter 'foo4' of public property setter from exported class has or is using private name 'private1'.
+!!! error TS4037: Parameter type of public setter 'foo4' from exported class has or is using private name 'private1'.
}
// Both - with annotation
get foo5(): private1 {
~~~~~~~~
-!!! error TS4043: Return type of public property getter from exported class has or is using private name 'private1'.
+!!! error TS4043: Return type of public getter 'foo5' from exported class has or is using private name 'private1'.
return;
}
set foo5(param: private1) {
}
-
+
// getter with annotation
get foo11(): public1 {
return;
@@ -93,21 +93,21 @@ tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(92,23): e
// getter with annotation
get foo111(): m2.public2 {
~~
-!!! error TS4043: Return type of public property getter from exported class has or is using private name 'm2'.
+!!! error TS4043: Return type of public getter 'foo111' from exported class has or is using private name 'm2'.
return;
}
// getter without annotation
get foo112() {
~~~~~~
-!!! error TS4042: Return type of public property getter from exported class has or is using name 'm2.public2' from private module 'm2'.
+!!! error TS4042: Return type of public getter 'foo112' from exported class has or is using name 'm2.public2' from private module 'm2'.
return new m2.public2();
}
// setter with annotation
set foo113(param: m2.public2) {
~~
-!!! error TS4037: Parameter 'foo113' of public property setter from exported class has or is using private name 'm2'.
+!!! error TS4037: Parameter type of public setter 'foo113' from exported class has or is using private name 'm2'.
}
// Both - getter without annotation, setter with annotation
@@ -116,13 +116,13 @@ tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(92,23): e
}
set foo114(param: m2.public2) {
~~
-!!! error TS4037: Parameter 'foo114' of public property setter from exported class has or is using private name 'm2'.
+!!! error TS4037: Parameter type of public setter 'foo114' from exported class has or is using private name 'm2'.
}
// Both - with annotation
get foo115(): m2.public2 {
~~
-!!! error TS4043: Return type of public property getter from exported class has or is using private name 'm2'.
+!!! error TS4043: Return type of public getter 'foo115' from exported class has or is using private name 'm2'.
return;
}
set foo115(param: m2.public2) {
diff --git a/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.js b/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.js
index 2d4d948668a..c02807207ca 100644
--- a/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.js
+++ b/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.js
@@ -10,7 +10,7 @@ module m {
export class public2 {
}
}
-
+
export class c {
// getter with annotation
get foo1(): private1 {
@@ -39,7 +39,7 @@ module m {
}
set foo5(param: private1) {
}
-
+
// getter with annotation
get foo11(): public1 {
return;
diff --git a/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.symbols b/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.symbols
index 503fa75ff97..25b8adca4ac 100644
--- a/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.symbols
+++ b/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.symbols
@@ -17,7 +17,7 @@ module m {
>public2 : Symbol(public2, Decl(declFileTypeAnnotationVisibilityErrorAccessors.ts, 7, 15))
}
}
-
+
export class c {
>c : Symbol(c, Decl(declFileTypeAnnotationVisibilityErrorAccessors.ts, 10, 5))
@@ -69,7 +69,7 @@ module m {
>param : Symbol(param, Decl(declFileTypeAnnotationVisibilityErrorAccessors.ts, 38, 17))
>private1 : Symbol(private1, Decl(declFileTypeAnnotationVisibilityErrorAccessors.ts, 0, 10))
}
-
+
// getter with annotation
get foo11(): public1 {
>foo11 : Symbol(c.foo11, Decl(declFileTypeAnnotationVisibilityErrorAccessors.ts, 39, 9))
diff --git a/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.types b/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.types
index c82794f2764..a05a00908d2 100644
--- a/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.types
+++ b/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.types
@@ -17,7 +17,7 @@ module m {
>public2 : public2
}
}
-
+
export class c {
>c : c
@@ -71,7 +71,7 @@ module m {
>param : private1
>private1 : private1
}
-
+
// getter with annotation
get foo11(): public1 {
>foo11 : public1
diff --git a/tests/baselines/reference/declarationEmitOfTypeofAliasedExport.js b/tests/baselines/reference/declarationEmitOfTypeofAliasedExport.js
new file mode 100644
index 00000000000..5f1f5743201
--- /dev/null
+++ b/tests/baselines/reference/declarationEmitOfTypeofAliasedExport.js
@@ -0,0 +1,35 @@
+//// [tests/cases/compiler/declarationEmitOfTypeofAliasedExport.ts] ////
+
+//// [a.ts]
+class C {}
+export { C as D }
+
+//// [b.ts]
+import * as a from "./a";
+export default a.D;
+
+
+//// [a.js]
+"use strict";
+exports.__esModule = true;
+var C = /** @class */ (function () {
+ function C() {
+ }
+ return C;
+}());
+exports.D = C;
+//// [b.js]
+"use strict";
+exports.__esModule = true;
+var a = require("./a");
+exports["default"] = a.D;
+
+
+//// [a.d.ts]
+declare class C {
+}
+export { C as D };
+//// [b.d.ts]
+import * as a from "./a";
+declare const _default: typeof a.D;
+export default _default;
diff --git a/tests/baselines/reference/declarationEmitOfTypeofAliasedExport.symbols b/tests/baselines/reference/declarationEmitOfTypeofAliasedExport.symbols
new file mode 100644
index 00000000000..d13d242105b
--- /dev/null
+++ b/tests/baselines/reference/declarationEmitOfTypeofAliasedExport.symbols
@@ -0,0 +1,17 @@
+=== /a.ts ===
+class C {}
+>C : Symbol(C, Decl(a.ts, 0, 0))
+
+export { C as D }
+>C : Symbol(D, Decl(a.ts, 1, 8))
+>D : Symbol(D, Decl(a.ts, 1, 8))
+
+=== /b.ts ===
+import * as a from "./a";
+>a : Symbol(a, Decl(b.ts, 0, 6))
+
+export default a.D;
+>a.D : Symbol(a.D, Decl(a.ts, 1, 8))
+>a : Symbol(a, Decl(b.ts, 0, 6))
+>D : Symbol(a.D, Decl(a.ts, 1, 8))
+
diff --git a/tests/baselines/reference/declarationEmitOfTypeofAliasedExport.types b/tests/baselines/reference/declarationEmitOfTypeofAliasedExport.types
new file mode 100644
index 00000000000..ccd13107166
--- /dev/null
+++ b/tests/baselines/reference/declarationEmitOfTypeofAliasedExport.types
@@ -0,0 +1,17 @@
+=== /a.ts ===
+class C {}
+>C : C
+
+export { C as D }
+>C : typeof C
+>D : typeof C
+
+=== /b.ts ===
+import * as a from "./a";
+>a : typeof a
+
+export default a.D;
+>a.D : typeof a.D
+>a : typeof a
+>D : typeof a.D
+
diff --git a/tests/baselines/reference/decoratorReferenceOnOtherProperty.js b/tests/baselines/reference/decoratorReferenceOnOtherProperty.js
new file mode 100644
index 00000000000..6313f339ba9
--- /dev/null
+++ b/tests/baselines/reference/decoratorReferenceOnOtherProperty.js
@@ -0,0 +1,109 @@
+//// [tests/cases/compiler/decoratorReferenceOnOtherProperty.ts] ////
+
+//// [yoha.ts]
+// https://github.com/Microsoft/TypeScript/issues/19799
+export class Yoha {}
+
+//// [index.ts]
+import {Yoha} from './yoha';
+
+function foo(...args: any[]) {}
+
+class Bar {
+ yoha(@foo yoha, bar: Yoha) {}
+ // ^^^^
+}
+
+//// [index2.ts]
+import {Yoha} from './yoha';
+
+function foo(...args: any[]) {}
+
+class Bar {
+ yoha(@foo yoha, ...bar: Yoha[]) {}
+ // ^^^^
+}
+
+//// [yoha.js]
+"use strict";
+exports.__esModule = true;
+// https://github.com/Microsoft/TypeScript/issues/19799
+var Yoha = /** @class */ (function () {
+ function Yoha() {
+ }
+ return Yoha;
+}());
+exports.Yoha = Yoha;
+//// [index.js]
+"use strict";
+var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
+};
+var __metadata = (this && this.__metadata) || function (k, v) {
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
+};
+var __param = (this && this.__param) || function (paramIndex, decorator) {
+ return function (target, key) { decorator(target, key, paramIndex); }
+};
+exports.__esModule = true;
+var yoha_1 = require("./yoha");
+function foo() {
+ var args = [];
+ for (var _i = 0; _i < arguments.length; _i++) {
+ args[_i] = arguments[_i];
+ }
+}
+var Bar = /** @class */ (function () {
+ function Bar() {
+ }
+ Bar.prototype.yoha = function (yoha, bar) { };
+ __decorate([
+ __param(0, foo),
+ __metadata("design:type", Function),
+ __metadata("design:paramtypes", [Object, yoha_1.Yoha]),
+ __metadata("design:returntype", void 0)
+ ], Bar.prototype, "yoha");
+ return Bar;
+}());
+//// [index2.js]
+"use strict";
+var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
+};
+var __metadata = (this && this.__metadata) || function (k, v) {
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
+};
+var __param = (this && this.__param) || function (paramIndex, decorator) {
+ return function (target, key) { decorator(target, key, paramIndex); }
+};
+exports.__esModule = true;
+var yoha_1 = require("./yoha");
+function foo() {
+ var args = [];
+ for (var _i = 0; _i < arguments.length; _i++) {
+ args[_i] = arguments[_i];
+ }
+}
+var Bar = /** @class */ (function () {
+ function Bar() {
+ }
+ Bar.prototype.yoha = function (yoha) {
+ var bar = [];
+ for (var _i = 1; _i < arguments.length; _i++) {
+ bar[_i - 1] = arguments[_i];
+ }
+ };
+ __decorate([
+ __param(0, foo),
+ __metadata("design:type", Function),
+ __metadata("design:paramtypes", [Object, yoha_1.Yoha]),
+ __metadata("design:returntype", void 0)
+ ], Bar.prototype, "yoha");
+ return Bar;
+}());
diff --git a/tests/baselines/reference/decoratorReferenceOnOtherProperty.symbols b/tests/baselines/reference/decoratorReferenceOnOtherProperty.symbols
new file mode 100644
index 00000000000..619e2afe4e9
--- /dev/null
+++ b/tests/baselines/reference/decoratorReferenceOnOtherProperty.symbols
@@ -0,0 +1,46 @@
+=== tests/cases/compiler/yoha.ts ===
+// https://github.com/Microsoft/TypeScript/issues/19799
+export class Yoha {}
+>Yoha : Symbol(Yoha, Decl(yoha.ts, 0, 0))
+
+=== tests/cases/compiler/index.ts ===
+import {Yoha} from './yoha';
+>Yoha : Symbol(Yoha, Decl(index.ts, 0, 8))
+
+function foo(...args: any[]) {}
+>foo : Symbol(foo, Decl(index.ts, 0, 28))
+>args : Symbol(args, Decl(index.ts, 2, 13))
+
+class Bar {
+>Bar : Symbol(Bar, Decl(index.ts, 2, 31))
+
+ yoha(@foo yoha, bar: Yoha) {}
+>yoha : Symbol(Bar.yoha, Decl(index.ts, 4, 11))
+>foo : Symbol(foo, Decl(index.ts, 0, 28))
+>yoha : Symbol(yoha, Decl(index.ts, 5, 7))
+>bar : Symbol(bar, Decl(index.ts, 5, 17))
+>Yoha : Symbol(Yoha, Decl(index.ts, 0, 8))
+
+ // ^^^^
+}
+
+=== tests/cases/compiler/index2.ts ===
+import {Yoha} from './yoha';
+>Yoha : Symbol(Yoha, Decl(index2.ts, 0, 8))
+
+function foo(...args: any[]) {}
+>foo : Symbol(foo, Decl(index2.ts, 0, 28))
+>args : Symbol(args, Decl(index2.ts, 2, 13))
+
+class Bar {
+>Bar : Symbol(Bar, Decl(index2.ts, 2, 31))
+
+ yoha(@foo yoha, ...bar: Yoha[]) {}
+>yoha : Symbol(Bar.yoha, Decl(index2.ts, 4, 11))
+>foo : Symbol(foo, Decl(index2.ts, 0, 28))
+>yoha : Symbol(yoha, Decl(index2.ts, 5, 7))
+>bar : Symbol(bar, Decl(index2.ts, 5, 17))
+>Yoha : Symbol(Yoha, Decl(index2.ts, 0, 8))
+
+ // ^^^^
+}
diff --git a/tests/baselines/reference/decoratorReferenceOnOtherProperty.types b/tests/baselines/reference/decoratorReferenceOnOtherProperty.types
new file mode 100644
index 00000000000..5994657aa31
--- /dev/null
+++ b/tests/baselines/reference/decoratorReferenceOnOtherProperty.types
@@ -0,0 +1,46 @@
+=== tests/cases/compiler/yoha.ts ===
+// https://github.com/Microsoft/TypeScript/issues/19799
+export class Yoha {}
+>Yoha : Yoha
+
+=== tests/cases/compiler/index.ts ===
+import {Yoha} from './yoha';
+>Yoha : typeof Yoha
+
+function foo(...args: any[]) {}
+>foo : (...args: any[]) => void
+>args : any[]
+
+class Bar {
+>Bar : Bar
+
+ yoha(@foo yoha, bar: Yoha) {}
+>yoha : (yoha: any, bar: Yoha) => void
+>foo : (...args: any[]) => void
+>yoha : any
+>bar : Yoha
+>Yoha : Yoha
+
+ // ^^^^
+}
+
+=== tests/cases/compiler/index2.ts ===
+import {Yoha} from './yoha';
+>Yoha : typeof Yoha
+
+function foo(...args: any[]) {}
+>foo : (...args: any[]) => void
+>args : any[]
+
+class Bar {
+>Bar : Bar
+
+ yoha(@foo yoha, ...bar: Yoha[]) {}
+>yoha : (yoha: any, ...bar: Yoha[]) => void
+>foo : (...args: any[]) => void
+>yoha : any
+>bar : Yoha[]
+>Yoha : Yoha
+
+ // ^^^^
+}
diff --git a/tests/baselines/reference/destructuringParameterDeclaration1ES5.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration1ES5.errors.txt
index 8e51c2b6111..fbbfc3b0d21 100644
--- a/tests/baselines/reference/destructuringParameterDeclaration1ES5.errors.txt
+++ b/tests/baselines/reference/destructuringParameterDeclaration1ES5.errors.txt
@@ -1,8 +1,14 @@
+tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts(12,4): error TS2345: Argument of type '[number, number, string[][], number]' is not assignable to parameter of type '[number, number, string[][]]'.
+ Types of property 'length' are incompatible.
+ Type '4' is not assignable to type '3'.
+tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts(57,4): error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'.
+ Types of property 'length' are incompatible.
+ Type '5' is not assignable to type '3'.
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts(62,10): error TS2393: Duplicate function implementation.
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts(63,10): error TS2393: Duplicate function implementation.
-==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts (2 errors) ====
+==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts (4 errors) ====
// A parameter declaration may specify either an identifier or a binding pattern.
// The identifiers specified in parameter declarations and binding patterns
// in a parameter list must be unique within that parameter list.
@@ -15,6 +21,10 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.
a1([1, 2, [["world"]]]);
a1([1, 2, [["world"]], 3]);
+ ~~~~~~~~~~~~~~~~~~~~~~
+!!! error TS2345: Argument of type '[number, number, string[][], number]' is not assignable to parameter of type '[number, number, string[][]]'.
+!!! error TS2345: Types of property 'length' are incompatible.
+!!! error TS2345: Type '4' is not assignable to type '3'.
// If the declaration includes an initializer expression (which is permitted only
// when the parameter list occurs in conjunction with a function body),
@@ -60,6 +70,10 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.
c5([1, 2, [["string"]]]); // Implied type is is [any, any, [[any]]]
c5([1, 2, [["string"]], false, true]); // Implied type is is [any, any, [[any]]]
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+!!! error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'.
+!!! error TS2345: Types of property 'length' are incompatible.
+!!! error TS2345: Type '5' is not assignable to type '3'.
// A parameter can be marked optional by following its name or binding pattern with a question mark (?)
// or by including an initializer.
diff --git a/tests/baselines/reference/destructuringParameterDeclaration1ES5.types b/tests/baselines/reference/destructuringParameterDeclaration1ES5.types
index a4b7e882298..c7a5c44f1d4 100644
--- a/tests/baselines/reference/destructuringParameterDeclaration1ES5.types
+++ b/tests/baselines/reference/destructuringParameterDeclaration1ES5.types
@@ -54,7 +54,7 @@ a1([1, 2, [["world"]]]);
a1([1, 2, [["world"]], 3]);
>a1([1, 2, [["world"]], 3]) : void
>a1 : ([a, b, [[c]]]: [number, number, string[][]]) => void
->[1, 2, [["world"]], 3] : [number, number, string[][], number]
+>[1, 2, [["world"]], 3] : (number | string[][])[]
>1 : 1
>2 : 2
>[["world"]] : string[][]
@@ -304,11 +304,11 @@ c5([1, 2, [["string"]]]); // Implied type is is [any, any, [[any]]
c5([1, 2, [["string"]], false, true]); // Implied type is is [any, any, [[any]]]
>c5([1, 2, [["string"]], false, true]) : void
>c5 : ([a, b, [[c]]]: [any, any, [[any]]]) => void
->[1, 2, [["string"]], false, true] : [number, number, [[string]], boolean, boolean]
+>[1, 2, [["string"]], false, true] : (number | boolean | string[][])[]
>1 : 1
>2 : 2
->[["string"]] : [[string]]
->["string"] : [string]
+>[["string"]] : string[][]
+>["string"] : string[]
>"string" : "string"
>false : false
>true : true
diff --git a/tests/baselines/reference/destructuringParameterDeclaration1ES5iterable.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration1ES5iterable.errors.txt
index 101a37fc84a..1dc3c61bb3a 100644
--- a/tests/baselines/reference/destructuringParameterDeclaration1ES5iterable.errors.txt
+++ b/tests/baselines/reference/destructuringParameterDeclaration1ES5iterable.errors.txt
@@ -1,8 +1,14 @@
+tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5iterable.ts(12,4): error TS2345: Argument of type '[number, number, string[][], number]' is not assignable to parameter of type '[number, number, string[][]]'.
+ Types of property 'length' are incompatible.
+ Type '4' is not assignable to type '3'.
+tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5iterable.ts(57,4): error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'.
+ Types of property 'length' are incompatible.
+ Type '5' is not assignable to type '3'.
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5iterable.ts(62,10): error TS2393: Duplicate function implementation.
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5iterable.ts(63,10): error TS2393: Duplicate function implementation.
-==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5iterable.ts (2 errors) ====
+==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5iterable.ts (4 errors) ====
// A parameter declaration may specify either an identifier or a binding pattern.
// The identifiers specified in parameter declarations and binding patterns
// in a parameter list must be unique within that parameter list.
@@ -15,6 +21,10 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5i
a1([1, 2, [["world"]]]);
a1([1, 2, [["world"]], 3]);
+ ~~~~~~~~~~~~~~~~~~~~~~
+!!! error TS2345: Argument of type '[number, number, string[][], number]' is not assignable to parameter of type '[number, number, string[][]]'.
+!!! error TS2345: Types of property 'length' are incompatible.
+!!! error TS2345: Type '4' is not assignable to type '3'.
// If the declaration includes an initializer expression (which is permitted only
// when the parameter list occurs in conjunction with a function body),
@@ -60,6 +70,10 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5i
c5([1, 2, [["string"]]]); // Implied type is is [any, any, [[any]]]
c5([1, 2, [["string"]], false, true]); // Implied type is is [any, any, [[any]]]
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+!!! error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'.
+!!! error TS2345: Types of property 'length' are incompatible.
+!!! error TS2345: Type '5' is not assignable to type '3'.
// A parameter can be marked optional by following its name or binding pattern with a question mark (?)
// or by including an initializer.
diff --git a/tests/baselines/reference/destructuringParameterDeclaration1ES5iterable.types b/tests/baselines/reference/destructuringParameterDeclaration1ES5iterable.types
index 9d72faf55b6..b41a2027586 100644
--- a/tests/baselines/reference/destructuringParameterDeclaration1ES5iterable.types
+++ b/tests/baselines/reference/destructuringParameterDeclaration1ES5iterable.types
@@ -54,7 +54,7 @@ a1([1, 2, [["world"]]]);
a1([1, 2, [["world"]], 3]);
>a1([1, 2, [["world"]], 3]) : void
>a1 : ([a, b, [[c]]]: [number, number, string[][]]) => void
->[1, 2, [["world"]], 3] : [number, number, string[][], number]
+>[1, 2, [["world"]], 3] : (number | string[][])[]
>1 : 1
>2 : 2
>[["world"]] : string[][]
@@ -304,11 +304,11 @@ c5([1, 2, [["string"]]]); // Implied type is is [any, any, [[any]]
c5([1, 2, [["string"]], false, true]); // Implied type is is [any, any, [[any]]]
>c5([1, 2, [["string"]], false, true]) : void
>c5 : ([a, b, [[c]]]: [any, any, [[any]]]) => void
->[1, 2, [["string"]], false, true] : [number, number, [[string]], boolean, boolean]
+>[1, 2, [["string"]], false, true] : (number | boolean | string[][])[]
>1 : 1
>2 : 2
->[["string"]] : [[string]]
->["string"] : [string]
+>[["string"]] : string[][]
+>["string"] : string[]
>"string" : "string"
>false : false
>true : true
diff --git a/tests/baselines/reference/destructuringParameterDeclaration1ES6.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration1ES6.errors.txt
index e900b9be393..f6c17a5c0ea 100644
--- a/tests/baselines/reference/destructuringParameterDeclaration1ES6.errors.txt
+++ b/tests/baselines/reference/destructuringParameterDeclaration1ES6.errors.txt
@@ -1,9 +1,15 @@
+tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES6.ts(14,4): error TS2345: Argument of type '[number, number, string[][], number]' is not assignable to parameter of type '[number, number, string[][]]'.
+ Types of property 'length' are incompatible.
+ Type '4' is not assignable to type '3'.
+tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES6.ts(58,4): error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'.
+ Types of property 'length' are incompatible.
+ Type '5' is not assignable to type '3'.
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES6.ts(96,18): error TS2300: Duplicate identifier 'number'.
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES6.ts(96,26): error TS2300: Duplicate identifier 'number'.
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES6.ts(96,34): error TS2300: Duplicate identifier 'number'.
-==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES6.ts (3 errors) ====
+==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES6.ts (5 errors) ====
// Conformance for emitting ES6
// A parameter declaration may specify either an identifier or a binding pattern.
@@ -18,6 +24,10 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES6.
a1([1, 2, [["world"]]]);
a1([1, 2, [["world"]], 3]);
+ ~~~~~~~~~~~~~~~~~~~~~~
+!!! error TS2345: Argument of type '[number, number, string[][], number]' is not assignable to parameter of type '[number, number, string[][]]'.
+!!! error TS2345: Types of property 'length' are incompatible.
+!!! error TS2345: Type '4' is not assignable to type '3'.
// If the declaration includes an initializer expression (which is permitted only
@@ -62,6 +72,10 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES6.
c5([1, 2, [["string"]]]); // Implied type is is [any, any, [[any]]]
c5([1, 2, [["string"]], false, true]); // Implied type is is [any, any, [[any]]]
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+!!! error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'.
+!!! error TS2345: Types of property 'length' are incompatible.
+!!! error TS2345: Type '5' is not assignable to type '3'.
// A parameter can be marked optional by following its name or binding pattern with a question mark (?)
diff --git a/tests/baselines/reference/destructuringParameterDeclaration1ES6.types b/tests/baselines/reference/destructuringParameterDeclaration1ES6.types
index b997dcf6017..9de904efdec 100644
--- a/tests/baselines/reference/destructuringParameterDeclaration1ES6.types
+++ b/tests/baselines/reference/destructuringParameterDeclaration1ES6.types
@@ -56,7 +56,7 @@ a1([1, 2, [["world"]]]);
a1([1, 2, [["world"]], 3]);
>a1([1, 2, [["world"]], 3]) : void
>a1 : ([a, b, [[c]]]: [number, number, string[][]]) => void
->[1, 2, [["world"]], 3] : [number, number, string[][], number]
+>[1, 2, [["world"]], 3] : (number | string[][])[]
>1 : 1
>2 : 2
>[["world"]] : string[][]
@@ -287,11 +287,11 @@ c5([1, 2, [["string"]]]); // Implied type is is [any, any, [[any]]
c5([1, 2, [["string"]], false, true]); // Implied type is is [any, any, [[any]]]
>c5([1, 2, [["string"]], false, true]) : void
>c5 : ([a, b, [[c]]]: [any, any, [[any]]]) => void
->[1, 2, [["string"]], false, true] : [number, number, [[string]], boolean, boolean]
+>[1, 2, [["string"]], false, true] : (number | boolean | string[][])[]
>1 : 1
>2 : 2
->[["string"]] : [[string]]
->["string"] : [string]
+>[["string"]] : string[][]
+>["string"] : string[]
>"string" : "string"
>false : false
>true : true
diff --git a/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt
index 81c85f7c42b..96b93423660 100644
--- a/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt
+++ b/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt
@@ -2,10 +2,8 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(
Type 'string' is not assignable to type 'number'.
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(7,29): error TS1005: ',' expected.
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(8,4): error TS2345: Argument of type '[number, number, string[][], string]' is not assignable to parameter of type '[number, number, string[][]]'.
- Types of property 'pop' are incompatible.
- Type '() => string | number | string[][]' is not assignable to type '() => number | string[][]'.
- Type 'string | number | string[][]' is not assignable to type 'number | string[][]'.
- Type 'string' is not assignable to type 'number | string[][]'.
+ Types of property 'length' are incompatible.
+ Type '4' is not assignable to type '3'.
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(16,8): error TS2371: A parameter initializer is only allowed in a function or constructor implementation.
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(16,16): error TS2371: A parameter initializer is only allowed in a function or constructor implementation.
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(23,14): error TS2345: Argument of type '{ x: string; y: boolean; }' is not assignable to parameter of type '{ x: number; y: any; }'.
@@ -64,10 +62,8 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(
a0([1, 2, [["world"]], "string"]); // Error
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2345: Argument of type '[number, number, string[][], string]' is not assignable to parameter of type '[number, number, string[][]]'.
-!!! error TS2345: Types of property 'pop' are incompatible.
-!!! error TS2345: Type '() => string | number | string[][]' is not assignable to type '() => number | string[][]'.
-!!! error TS2345: Type 'string | number | string[][]' is not assignable to type 'number | string[][]'.
-!!! error TS2345: Type 'string' is not assignable to type 'number | string[][]'.
+!!! error TS2345: Types of property 'length' are incompatible.
+!!! error TS2345: Type '4' is not assignable to type '3'.
// If the declaration includes an initializer expression (which is permitted only
diff --git a/tests/baselines/reference/destructuringParameterDeclaration3ES5.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration3ES5.errors.txt
new file mode 100644
index 00000000000..3b16993a047
--- /dev/null
+++ b/tests/baselines/reference/destructuringParameterDeclaration3ES5.errors.txt
@@ -0,0 +1,55 @@
+tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5.ts(26,4): error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'.
+ Types of property 'length' are incompatible.
+ Type '5' is not assignable to type '3'.
+
+
+==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5.ts (1 errors) ====
+ // If the parameter is a rest parameter, the parameter type is any[]
+ // A type annotation for a rest parameter must denote an array type.
+
+ // RestParameter:
+ // ... Identifier TypeAnnotation(opt)
+
+ type arrayString = Array
+ type someArray = Array | number[];
+ type stringOrNumArray = Array;
+
+ function a1(...x: (number|string)[]) { }
+ function a2(...a) { }
+ function a3(...a: Array) { }
+ function a4(...a: arrayString) { }
+ function a5(...a: stringOrNumArray) { }
+ function a9([a, b, [[c]]]) { }
+ function a10([a, b, [[c]], ...x]) { }
+ function a11([a, b, c, ...x]: number[]) { }
+
+
+ var array = [1, 2, 3];
+ var array2 = [true, false, "hello"];
+ a2([...array]);
+ a1(...array);
+
+ a9([1, 2, [["string"]], false, true]); // Parameter type is [any, any, [[any]]]
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+!!! error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'.
+!!! error TS2345: Types of property 'length' are incompatible.
+!!! error TS2345: Type '5' is not assignable to type '3'.
+
+ a10([1, 2, [["string"]], false, true]); // Parameter type is any[]
+ a10([1, 2, 3, false, true]); // Parameter type is any[]
+ a10([1, 2]); // Parameter type is any[]
+ a11([1, 2]); // Parameter type is number[]
+
+ // Rest parameter with generic
+ function foo(...a: T[]) { }
+ foo("hello", 1, 2);
+ foo("hello", "world");
+
+ enum E { a, b }
+ const enum E1 { a, b }
+ function foo1(...a: T[]) { }
+ foo1(1, 2, 3, E.a);
+ foo1(1, 2, 3, E1.a, E.b);
+
+
+
\ No newline at end of file
diff --git a/tests/baselines/reference/destructuringParameterDeclaration3ES5.types b/tests/baselines/reference/destructuringParameterDeclaration3ES5.types
index a91d54d5284..33e0d3b6bd8 100644
--- a/tests/baselines/reference/destructuringParameterDeclaration3ES5.types
+++ b/tests/baselines/reference/destructuringParameterDeclaration3ES5.types
@@ -96,11 +96,11 @@ a1(...array);
a9([1, 2, [["string"]], false, true]); // Parameter type is [any, any, [[any]]]
>a9([1, 2, [["string"]], false, true]) : void
>a9 : ([a, b, [[c]]]: [any, any, [[any]]]) => void
->[1, 2, [["string"]], false, true] : [number, number, [[string]], boolean, boolean]
+>[1, 2, [["string"]], false, true] : (number | boolean | string[][])[]
>1 : 1
>2 : 2
->[["string"]] : [[string]]
->["string"] : [string]
+>[["string"]] : string[][]
+>["string"] : string[]
>"string" : "string"
>false : false
>true : true
diff --git a/tests/baselines/reference/destructuringParameterDeclaration3ES5iterable.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration3ES5iterable.errors.txt
new file mode 100644
index 00000000000..f0dbf325ed4
--- /dev/null
+++ b/tests/baselines/reference/destructuringParameterDeclaration3ES5iterable.errors.txt
@@ -0,0 +1,55 @@
+tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5iterable.ts(26,4): error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'.
+ Types of property 'length' are incompatible.
+ Type '5' is not assignable to type '3'.
+
+
+==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5iterable.ts (1 errors) ====
+ // If the parameter is a rest parameter, the parameter type is any[]
+ // A type annotation for a rest parameter must denote an array type.
+
+ // RestParameter:
+ // ... Identifier TypeAnnotation(opt)
+
+ type arrayString = Array
+ type someArray = Array | number[];
+ type stringOrNumArray = Array;
+
+ function a1(...x: (number|string)[]) { }
+ function a2(...a) { }
+ function a3(...a: Array) { }
+ function a4(...a: arrayString) { }
+ function a5(...a: stringOrNumArray) { }
+ function a9([a, b, [[c]]]) { }
+ function a10([a, b, [[c]], ...x]) { }
+ function a11([a, b, c, ...x]: number[]) { }
+
+
+ var array = [1, 2, 3];
+ var array2 = [true, false, "hello"];
+ a2([...array]);
+ a1(...array);
+
+ a9([1, 2, [["string"]], false, true]); // Parameter type is [any, any, [[any]]]
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+!!! error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'.
+!!! error TS2345: Types of property 'length' are incompatible.
+!!! error TS2345: Type '5' is not assignable to type '3'.
+
+ a10([1, 2, [["string"]], false, true]); // Parameter type is any[]
+ a10([1, 2, 3, false, true]); // Parameter type is any[]
+ a10([1, 2]); // Parameter type is any[]
+ a11([1, 2]); // Parameter type is number[]
+
+ // Rest parameter with generic
+ function foo(...a: T[]) { }
+ foo("hello", 1, 2);
+ foo("hello", "world");
+
+ enum E { a, b }
+ const enum E1 { a, b }
+ function foo1(...a: T[]) { }
+ foo1(1, 2, 3, E.a);
+ foo1(1, 2, 3, E1.a, E.b);
+
+
+
\ No newline at end of file
diff --git a/tests/baselines/reference/destructuringParameterDeclaration3ES5iterable.types b/tests/baselines/reference/destructuringParameterDeclaration3ES5iterable.types
index 5f2963abe87..931e149ffe2 100644
--- a/tests/baselines/reference/destructuringParameterDeclaration3ES5iterable.types
+++ b/tests/baselines/reference/destructuringParameterDeclaration3ES5iterable.types
@@ -96,11 +96,11 @@ a1(...array);
a9([1, 2, [["string"]], false, true]); // Parameter type is [any, any, [[any]]]
>a9([1, 2, [["string"]], false, true]) : void
>a9 : ([a, b, [[c]]]: [any, any, [[any]]]) => void
->[1, 2, [["string"]], false, true] : [number, number, [[string]], boolean, boolean]
+>[1, 2, [["string"]], false, true] : (number | boolean | string[][])[]
>1 : 1
>2 : 2
->[["string"]] : [[string]]
->["string"] : [string]
+>[["string"]] : string[][]
+>["string"] : string[]
>"string" : "string"
>false : false
>true : true
diff --git a/tests/baselines/reference/destructuringParameterDeclaration3ES6.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration3ES6.errors.txt
new file mode 100644
index 00000000000..67a5c1bf87f
--- /dev/null
+++ b/tests/baselines/reference/destructuringParameterDeclaration3ES6.errors.txt
@@ -0,0 +1,55 @@
+tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES6.ts(26,4): error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'.
+ Types of property 'length' are incompatible.
+ Type '5' is not assignable to type '3'.
+
+
+==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES6.ts (1 errors) ====
+ // If the parameter is a rest parameter, the parameter type is any[]
+ // A type annotation for a rest parameter must denote an array type.
+
+ // RestParameter:
+ // ... Identifier TypeAnnotation(opt)
+
+ type arrayString = Array
+ type someArray = Array | number[];
+ type stringOrNumArray = Array;
+
+ function a1(...x: (number|string)[]) { }
+ function a2(...a) { }
+ function a3(...a: Array) { }
+ function a4(...a: arrayString) { }
+ function a5(...a: stringOrNumArray) { }
+ function a9([a, b, [[c]]]) { }
+ function a10([a, b, [[c]], ...x]) { }
+ function a11([a, b, c, ...x]: number[]) { }
+
+
+ var array = [1, 2, 3];
+ var array2 = [true, false, "hello"];
+ a2([...array]);
+ a1(...array);
+
+ a9([1, 2, [["string"]], false, true]); // Parameter type is [any, any, [[any]]]
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+!!! error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'.
+!!! error TS2345: Types of property 'length' are incompatible.
+!!! error TS2345: Type '5' is not assignable to type '3'.
+
+ a10([1, 2, [["string"]], false, true]); // Parameter type is any[]
+ a10([1, 2, 3, false, true]); // Parameter type is any[]
+ a10([1, 2]); // Parameter type is any[]
+ a11([1, 2]); // Parameter type is number[]
+
+ // Rest parameter with generic
+ function foo(...a: T[]) { }
+ foo("hello", 1, 2);
+ foo("hello", "world");
+
+ enum E { a, b }
+ const enum E1 { a, b }
+ function foo1(...a: T[]) { }
+ foo1(1, 2, 3, E.a);
+ foo1(1, 2, 3, E1.a, E.b);
+
+
+
\ No newline at end of file
diff --git a/tests/baselines/reference/destructuringParameterDeclaration3ES6.types b/tests/baselines/reference/destructuringParameterDeclaration3ES6.types
index 397ec934a2f..dc5e64d2c2c 100644
--- a/tests/baselines/reference/destructuringParameterDeclaration3ES6.types
+++ b/tests/baselines/reference/destructuringParameterDeclaration3ES6.types
@@ -96,11 +96,11 @@ a1(...array);
a9([1, 2, [["string"]], false, true]); // Parameter type is [any, any, [[any]]]
>a9([1, 2, [["string"]], false, true]) : void
>a9 : ([a, b, [[c]]]: [any, any, [[any]]]) => void
->[1, 2, [["string"]], false, true] : [number, number, [[string]], boolean, boolean]
+>[1, 2, [["string"]], false, true] : (number | boolean | string[][])[]
>1 : 1
>2 : 2
->[["string"]] : [[string]]
->["string"] : [string]
+>[["string"]] : string[][]
+>["string"] : string[]
>"string" : "string"
>false : false
>true : true
diff --git a/tests/baselines/reference/errorSupression1.js b/tests/baselines/reference/errorSupression1.js
index 2f467871434..4b635a0d660 100644
--- a/tests/baselines/reference/errorSupression1.js
+++ b/tests/baselines/reference/errorSupression1.js
@@ -17,4 +17,4 @@ var Foo = /** @class */ (function () {
var baz = Foo.b;
// Foo.b won't bind.
baz.concat("y");
-// So we don't want an error on 'concat'.
+// So we don't want an error on 'concat'.
diff --git a/tests/baselines/reference/es6ExportClauseWithoutModuleSpecifier.types b/tests/baselines/reference/es6ExportClauseWithoutModuleSpecifier.types
index abb1c3b69e2..acbe40fb9ab 100644
--- a/tests/baselines/reference/es6ExportClauseWithoutModuleSpecifier.types
+++ b/tests/baselines/reference/es6ExportClauseWithoutModuleSpecifier.types
@@ -30,8 +30,8 @@ export { c as c2 } from "server";
export { i, m as instantiatedModule } from "server";
>i : any
->m : typeof m
->instantiatedModule : typeof m
+>m : typeof instantiatedModule
+>instantiatedModule : typeof instantiatedModule
export { uninstantiated } from "server";
>uninstantiated : any
diff --git a/tests/baselines/reference/es6ExportClauseWithoutModuleSpecifierInEs5.types b/tests/baselines/reference/es6ExportClauseWithoutModuleSpecifierInEs5.types
index b407d9b16f5..8a7e9c29b10 100644
--- a/tests/baselines/reference/es6ExportClauseWithoutModuleSpecifierInEs5.types
+++ b/tests/baselines/reference/es6ExportClauseWithoutModuleSpecifierInEs5.types
@@ -30,8 +30,8 @@ export { c as c2 } from "./server";
export { i, m as instantiatedModule } from "./server";
>i : any
->m : typeof m
->instantiatedModule : typeof m
+>m : typeof instantiatedModule
+>instantiatedModule : typeof instantiatedModule
export { uninstantiated } from "./server";
>uninstantiated : any
diff --git a/tests/baselines/reference/everyTypeAssignableToAny.js b/tests/baselines/reference/everyTypeAssignableToAny.js
index 7f02badca00..fd71ec624be 100644
--- a/tests/baselines/reference/everyTypeAssignableToAny.js
+++ b/tests/baselines/reference/everyTypeAssignableToAny.js
@@ -117,4 +117,4 @@ function foo(x, y, z) {
// a = x;
// a = y;
// a = z;
-//}
+//}
diff --git a/tests/baselines/reference/exportDefaultAlias_excludesEverything.errors.txt b/tests/baselines/reference/exportDefaultAlias_excludesEverything.errors.txt
new file mode 100644
index 00000000000..9181278db20
--- /dev/null
+++ b/tests/baselines/reference/exportDefaultAlias_excludesEverything.errors.txt
@@ -0,0 +1,13 @@
+tests/cases/compiler/exportDefaultAlias_excludesEverything.ts(1,26): error TS2528: A module cannot have multiple default exports.
+tests/cases/compiler/exportDefaultAlias_excludesEverything.ts(3,16): error TS2528: A module cannot have multiple default exports.
+
+
+==== tests/cases/compiler/exportDefaultAlias_excludesEverything.ts (2 errors) ====
+ export default interface A {}
+ ~
+!!! error TS2528: A module cannot have multiple default exports.
+ interface B {}
+ export default B;
+ ~
+!!! error TS2528: A module cannot have multiple default exports.
+
\ No newline at end of file
diff --git a/tests/baselines/reference/exportDefaultAlias_excludesEverything.js b/tests/baselines/reference/exportDefaultAlias_excludesEverything.js
new file mode 100644
index 00000000000..27f75954c14
--- /dev/null
+++ b/tests/baselines/reference/exportDefaultAlias_excludesEverything.js
@@ -0,0 +1,9 @@
+//// [exportDefaultAlias_excludesEverything.ts]
+export default interface A {}
+interface B {}
+export default B;
+
+
+//// [exportDefaultAlias_excludesEverything.js]
+"use strict";
+exports.__esModule = true;
diff --git a/tests/baselines/reference/exportDefaultAlias_excludesEverything.symbols b/tests/baselines/reference/exportDefaultAlias_excludesEverything.symbols
new file mode 100644
index 00000000000..73b403e0da1
--- /dev/null
+++ b/tests/baselines/reference/exportDefaultAlias_excludesEverything.symbols
@@ -0,0 +1,10 @@
+=== tests/cases/compiler/exportDefaultAlias_excludesEverything.ts ===
+export default interface A {}
+>A : Symbol(A, Decl(exportDefaultAlias_excludesEverything.ts, 0, 0))
+
+interface B {}
+>B : Symbol(B, Decl(exportDefaultAlias_excludesEverything.ts, 0, 29))
+
+export default B;
+>B : Symbol(B, Decl(exportDefaultAlias_excludesEverything.ts, 0, 29))
+
diff --git a/tests/baselines/reference/exportDefaultAlias_excludesEverything.types b/tests/baselines/reference/exportDefaultAlias_excludesEverything.types
new file mode 100644
index 00000000000..cd9dd06f817
--- /dev/null
+++ b/tests/baselines/reference/exportDefaultAlias_excludesEverything.types
@@ -0,0 +1,10 @@
+=== tests/cases/compiler/exportDefaultAlias_excludesEverything.ts ===
+export default interface A {}
+>A : A
+
+interface B {}
+>B : B
+
+export default B;
+>B : B
+
diff --git a/tests/baselines/reference/exportSpecifierForAGlobal.errors.txt b/tests/baselines/reference/exportSpecifierForAGlobal.errors.txt
index d2f103a91fa..20a1c9a7d41 100644
--- a/tests/baselines/reference/exportSpecifierForAGlobal.errors.txt
+++ b/tests/baselines/reference/exportSpecifierForAGlobal.errors.txt
@@ -1,14 +1,17 @@
tests/cases/compiler/b.ts(1,9): error TS2661: Cannot export 'X'. Only local declarations can be exported from a module.
+tests/cases/compiler/b.ts(2,17): error TS4060: Return type of exported function has or is using private name 'X'.
==== tests/cases/compiler/a.d.ts (0 errors) ====
declare class X { }
-==== tests/cases/compiler/b.ts (1 errors) ====
+==== tests/cases/compiler/b.ts (2 errors) ====
export {X};
~
!!! error TS2661: Cannot export 'X'. Only local declarations can be exported from a module.
export function f() {
+ ~
+!!! error TS4060: Return type of exported function has or is using private name 'X'.
var x: X;
return x;
}
diff --git a/tests/baselines/reference/exportSpecifierForAGlobal.js b/tests/baselines/reference/exportSpecifierForAGlobal.js
index 6023b7c7f14..9f12241cbd1 100644
--- a/tests/baselines/reference/exportSpecifierForAGlobal.js
+++ b/tests/baselines/reference/exportSpecifierForAGlobal.js
@@ -19,8 +19,3 @@ function f() {
return x;
}
exports.f = f;
-
-
-//// [b.d.ts]
-export { X };
-export declare function f(): X;
diff --git a/tests/baselines/reference/exportsAndImports3-amd.symbols b/tests/baselines/reference/exportsAndImports3-amd.symbols
index f71014281c2..edc5d5c2e4e 100644
--- a/tests/baselines/reference/exportsAndImports3-amd.symbols
+++ b/tests/baselines/reference/exportsAndImports3-amd.symbols
@@ -15,17 +15,17 @@ export enum E {
>E : Symbol(E, Decl(t1.ts, 5, 1))
A, B, C
->A : Symbol(E.A, Decl(t1.ts, 6, 15))
->B : Symbol(E.B, Decl(t1.ts, 7, 6))
->C : Symbol(E.C, Decl(t1.ts, 7, 9))
+>A : Symbol(E1.A, Decl(t1.ts, 6, 15))
+>B : Symbol(E1.B, Decl(t1.ts, 7, 6))
+>C : Symbol(E1.C, Decl(t1.ts, 7, 9))
}
export const enum D {
>D : Symbol(D, Decl(t1.ts, 8, 1))
A, B, C
->A : Symbol(D.A, Decl(t1.ts, 9, 21))
->B : Symbol(D.B, Decl(t1.ts, 10, 6))
->C : Symbol(D.C, Decl(t1.ts, 10, 9))
+>A : Symbol(D1.A, Decl(t1.ts, 9, 21))
+>B : Symbol(D1.B, Decl(t1.ts, 10, 6))
+>C : Symbol(D1.C, Decl(t1.ts, 10, 9))
}
export module M {
>M : Symbol(M, Decl(t1.ts, 11, 1))
diff --git a/tests/baselines/reference/exportsAndImports3-es6.symbols b/tests/baselines/reference/exportsAndImports3-es6.symbols
index f71014281c2..edc5d5c2e4e 100644
--- a/tests/baselines/reference/exportsAndImports3-es6.symbols
+++ b/tests/baselines/reference/exportsAndImports3-es6.symbols
@@ -15,17 +15,17 @@ export enum E {
>E : Symbol(E, Decl(t1.ts, 5, 1))
A, B, C
->A : Symbol(E.A, Decl(t1.ts, 6, 15))
->B : Symbol(E.B, Decl(t1.ts, 7, 6))
->C : Symbol(E.C, Decl(t1.ts, 7, 9))
+>A : Symbol(E1.A, Decl(t1.ts, 6, 15))
+>B : Symbol(E1.B, Decl(t1.ts, 7, 6))
+>C : Symbol(E1.C, Decl(t1.ts, 7, 9))
}
export const enum D {
>D : Symbol(D, Decl(t1.ts, 8, 1))
A, B, C
->A : Symbol(D.A, Decl(t1.ts, 9, 21))
->B : Symbol(D.B, Decl(t1.ts, 10, 6))
->C : Symbol(D.C, Decl(t1.ts, 10, 9))
+>A : Symbol(D1.A, Decl(t1.ts, 9, 21))
+>B : Symbol(D1.B, Decl(t1.ts, 10, 6))
+>C : Symbol(D1.C, Decl(t1.ts, 10, 9))
}
export module M {
>M : Symbol(M, Decl(t1.ts, 11, 1))
diff --git a/tests/baselines/reference/exportsAndImports3.symbols b/tests/baselines/reference/exportsAndImports3.symbols
index f71014281c2..edc5d5c2e4e 100644
--- a/tests/baselines/reference/exportsAndImports3.symbols
+++ b/tests/baselines/reference/exportsAndImports3.symbols
@@ -15,17 +15,17 @@ export enum E {
>E : Symbol(E, Decl(t1.ts, 5, 1))
A, B, C
->A : Symbol(E.A, Decl(t1.ts, 6, 15))
->B : Symbol(E.B, Decl(t1.ts, 7, 6))
->C : Symbol(E.C, Decl(t1.ts, 7, 9))
+>A : Symbol(E1.A, Decl(t1.ts, 6, 15))
+>B : Symbol(E1.B, Decl(t1.ts, 7, 6))
+>C : Symbol(E1.C, Decl(t1.ts, 7, 9))
}
export const enum D {
>D : Symbol(D, Decl(t1.ts, 8, 1))
A, B, C
->A : Symbol(D.A, Decl(t1.ts, 9, 21))
->B : Symbol(D.B, Decl(t1.ts, 10, 6))
->C : Symbol(D.C, Decl(t1.ts, 10, 9))
+>A : Symbol(D1.A, Decl(t1.ts, 9, 21))
+>B : Symbol(D1.B, Decl(t1.ts, 10, 6))
+>C : Symbol(D1.C, Decl(t1.ts, 10, 9))
}
export module M {
>M : Symbol(M, Decl(t1.ts, 11, 1))
diff --git a/tests/baselines/reference/functionConstraintSatisfaction.js b/tests/baselines/reference/functionConstraintSatisfaction.js
index fc8a2be88a7..f24fd32aff6 100644
--- a/tests/baselines/reference/functionConstraintSatisfaction.js
+++ b/tests/baselines/reference/functionConstraintSatisfaction.js
@@ -108,4 +108,4 @@ function foo2(x, y) {
//function foo2(x: T, y: U) {
// foo(x);
// foo(y);
-//}
+//}
diff --git a/tests/baselines/reference/genericCallWithObjectTypeArgsAndNumericIndexer.js b/tests/baselines/reference/genericCallWithObjectTypeArgsAndNumericIndexer.js
index f300e3a8093..27e4093d9c7 100644
--- a/tests/baselines/reference/genericCallWithObjectTypeArgsAndNumericIndexer.js
+++ b/tests/baselines/reference/genericCallWithObjectTypeArgsAndNumericIndexer.js
@@ -63,4 +63,4 @@ function other3(arg) {
// var d = r2[1];
// // BUG 821629
// //var u: U = r2[1]; // ok
-//}
+//}
diff --git a/tests/baselines/reference/genericCallWithObjectTypeArgsAndStringIndexer.js b/tests/baselines/reference/genericCallWithObjectTypeArgsAndStringIndexer.js
index eee87caf3de..ee33746b152 100644
--- a/tests/baselines/reference/genericCallWithObjectTypeArgsAndStringIndexer.js
+++ b/tests/baselines/reference/genericCallWithObjectTypeArgsAndStringIndexer.js
@@ -64,4 +64,4 @@ function other3(arg) {
// var d: Date = r2['hm']; // ok
// // BUG 821629
// //var u: U = r2['hm']; // ok
-//}
+//}
diff --git a/tests/baselines/reference/genericCallWithTupleType.errors.txt b/tests/baselines/reference/genericCallWithTupleType.errors.txt
index 617c4f7159b..65920596c45 100644
--- a/tests/baselines/reference/genericCallWithTupleType.errors.txt
+++ b/tests/baselines/reference/genericCallWithTupleType.errors.txt
@@ -1,8 +1,6 @@
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(12,1): error TS2322: Type '[string, number, boolean, boolean]' is not assignable to type '[string, number]'.
- Types of property 'pop' are incompatible.
- Type '() => string | number | boolean' is not assignable to type '() => string | number'.
- Type 'string | number | boolean' is not assignable to type 'string | number'.
- Type 'true' is not assignable to type 'string | number'.
+ Types of property 'length' are incompatible.
+ Type '4' is not assignable to type '2'.
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(14,1): error TS2322: Type '{ a: string; }' is not assignable to type 'string | number'.
Type '{ a: string; }' is not assignable to type 'number'.
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(22,1): error TS2322: Type '[number, string]' is not assignable to type '[string, number]'.
@@ -28,10 +26,8 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTup
i1.tuple1 = ["foo", 5, false, true];
~~~~~~~~~
!!! error TS2322: Type '[string, number, boolean, boolean]' is not assignable to type '[string, number]'.
-!!! error TS2322: Types of property 'pop' are incompatible.
-!!! error TS2322: Type '() => string | number | boolean' is not assignable to type '() => string | number'.
-!!! error TS2322: Type 'string | number | boolean' is not assignable to type 'string | number'.
-!!! error TS2322: Type 'true' is not assignable to type 'string | number'.
+!!! error TS2322: Types of property 'length' are incompatible.
+!!! error TS2322: Type '4' is not assignable to type '2'.
var e3 = i1.tuple1[2]; // {}
i1.tuple1[3] = { a: "string" };
~~~~~~~~~~~~
diff --git a/tests/baselines/reference/genericTypeAliases.js b/tests/baselines/reference/genericTypeAliases.js
index 8218f5c886c..282fd9868a9 100644
--- a/tests/baselines/reference/genericTypeAliases.js
+++ b/tests/baselines/reference/genericTypeAliases.js
@@ -40,12 +40,12 @@ type Strange = string; // Type parameter not used
var s: Strange;
s = "hello";
-interface Tuple {
+interface AB {
a: A;
b: B;
}
-type Pair = Tuple;
+type Pair = AB;
interface TaggedPair extends Pair {
tag: string;
diff --git a/tests/baselines/reference/genericTypeAliases.symbols b/tests/baselines/reference/genericTypeAliases.symbols
index d5f68ec0615..521afe800b3 100644
--- a/tests/baselines/reference/genericTypeAliases.symbols
+++ b/tests/baselines/reference/genericTypeAliases.symbols
@@ -124,29 +124,29 @@ var s: Strange;
s = "hello";
>s : Symbol(s, Decl(genericTypeAliases.ts, 38, 3))
-interface Tuple {
->Tuple : Symbol(Tuple, Decl(genericTypeAliases.ts, 39, 12))
->A : Symbol(A, Decl(genericTypeAliases.ts, 41, 16))
->B : Symbol(B, Decl(genericTypeAliases.ts, 41, 18))
+interface AB {
+>AB : Symbol(AB, Decl(genericTypeAliases.ts, 39, 12))
+>A : Symbol(A, Decl(genericTypeAliases.ts, 41, 13))
+>B : Symbol(B, Decl(genericTypeAliases.ts, 41, 15))
a: A;
->a : Symbol(Tuple.a, Decl(genericTypeAliases.ts, 41, 23))
->A : Symbol(A, Decl(genericTypeAliases.ts, 41, 16))
+>a : Symbol(AB.a, Decl(genericTypeAliases.ts, 41, 20))
+>A : Symbol(A, Decl(genericTypeAliases.ts, 41, 13))
b: B;
->b : Symbol(Tuple.b, Decl(genericTypeAliases.ts, 42, 9))
->B : Symbol(B, Decl(genericTypeAliases.ts, 41, 18))
+>b : Symbol(AB.b, Decl(genericTypeAliases.ts, 42, 9))
+>B : Symbol(B, Decl(genericTypeAliases.ts, 41, 15))
}
-type Pair = Tuple;
+type Pair = AB;
>Pair : Symbol(Pair, Decl(genericTypeAliases.ts, 44, 1))
>T : Symbol(T, Decl(genericTypeAliases.ts, 46, 10))
->Tuple : Symbol(Tuple, Decl(genericTypeAliases.ts, 39, 12))
+>AB : Symbol(AB, Decl(genericTypeAliases.ts, 39, 12))
>T : Symbol(T, Decl(genericTypeAliases.ts, 46, 10))
>T : Symbol(T, Decl(genericTypeAliases.ts, 46, 10))
interface TaggedPair extends Pair {
->TaggedPair : Symbol(TaggedPair, Decl(genericTypeAliases.ts, 46, 27))
+>TaggedPair : Symbol(TaggedPair, Decl(genericTypeAliases.ts, 46, 24))
>T : Symbol(T, Decl(genericTypeAliases.ts, 48, 21))
>Pair : Symbol(Pair, Decl(genericTypeAliases.ts, 44, 1))
>T : Symbol(T, Decl(genericTypeAliases.ts, 48, 21))
@@ -157,17 +157,17 @@ interface TaggedPair extends Pair {
var p: TaggedPair;
>p : Symbol(p, Decl(genericTypeAliases.ts, 52, 3))
->TaggedPair : Symbol(TaggedPair, Decl(genericTypeAliases.ts, 46, 27))
+>TaggedPair : Symbol(TaggedPair, Decl(genericTypeAliases.ts, 46, 24))
p.a = 1;
->p.a : Symbol(Tuple.a, Decl(genericTypeAliases.ts, 41, 23))
+>p.a : Symbol(AB.a, Decl(genericTypeAliases.ts, 41, 20))
>p : Symbol(p, Decl(genericTypeAliases.ts, 52, 3))
->a : Symbol(Tuple.a, Decl(genericTypeAliases.ts, 41, 23))
+>a : Symbol(AB.a, Decl(genericTypeAliases.ts, 41, 20))
p.b = 2;
->p.b : Symbol(Tuple.b, Decl(genericTypeAliases.ts, 42, 9))
+>p.b : Symbol(AB.b, Decl(genericTypeAliases.ts, 42, 9))
>p : Symbol(p, Decl(genericTypeAliases.ts, 52, 3))
->b : Symbol(Tuple.b, Decl(genericTypeAliases.ts, 42, 9))
+>b : Symbol(AB.b, Decl(genericTypeAliases.ts, 42, 9))
p.tag = "test";
>p.tag : Symbol(TaggedPair.tag, Decl(genericTypeAliases.ts, 48, 41))
diff --git a/tests/baselines/reference/genericTypeAliases.types b/tests/baselines/reference/genericTypeAliases.types
index b4c75841245..722347b0f72 100644
--- a/tests/baselines/reference/genericTypeAliases.types
+++ b/tests/baselines/reference/genericTypeAliases.types
@@ -158,8 +158,8 @@ s = "hello";
>s : string
>"hello" : "hello"
-interface Tuple {
->Tuple : Tuple
+interface AB {
+>AB : AB
>A : A
>B : B
@@ -172,17 +172,17 @@ interface Tuple {
>B : B
}
-type Pair = Tuple;
->Pair : Tuple
+type Pair = AB;
+>Pair : AB
>T : T
->Tuple : Tuple
+>AB : AB
>T : T
>T : T
interface TaggedPair extends Pair {
>TaggedPair : TaggedPair
>T : T
->Pair : Tuple
+>Pair : AB
>T : T
tag: string;
diff --git a/tests/baselines/reference/heterogeneousArrayLiterals.js b/tests/baselines/reference/heterogeneousArrayLiterals.js
index 499aa7e7818..46dee284ae9 100644
--- a/tests/baselines/reference/heterogeneousArrayLiterals.js
+++ b/tests/baselines/reference/heterogeneousArrayLiterals.js
@@ -268,4 +268,4 @@ function foo4(t, u) {
// var i = [u, base]; // Base[]
// var j = [u, derived]; // Derived[]
// var k: Base[] = [t, u];
-//}
+//}
diff --git a/tests/baselines/reference/independentPropertyVariance.js b/tests/baselines/reference/independentPropertyVariance.js
new file mode 100644
index 00000000000..2439d8140fa
--- /dev/null
+++ b/tests/baselines/reference/independentPropertyVariance.js
@@ -0,0 +1,13 @@
+//// [independentPropertyVariance.ts]
+// Verify that properties can vary independently in comparable relationship
+
+declare const x: { a: 1, b: string };
+declare const y: { a: number, b: 'a' };
+
+x === y;
+
+
+//// [independentPropertyVariance.js]
+"use strict";
+// Verify that properties can vary independently in comparable relationship
+x === y;
diff --git a/tests/baselines/reference/independentPropertyVariance.symbols b/tests/baselines/reference/independentPropertyVariance.symbols
new file mode 100644
index 00000000000..cf503476008
--- /dev/null
+++ b/tests/baselines/reference/independentPropertyVariance.symbols
@@ -0,0 +1,17 @@
+=== tests/cases/conformance/types/typeRelationships/comparable/independentPropertyVariance.ts ===
+// Verify that properties can vary independently in comparable relationship
+
+declare const x: { a: 1, b: string };
+>x : Symbol(x, Decl(independentPropertyVariance.ts, 2, 13))
+>a : Symbol(a, Decl(independentPropertyVariance.ts, 2, 18))
+>b : Symbol(b, Decl(independentPropertyVariance.ts, 2, 24))
+
+declare const y: { a: number, b: 'a' };
+>y : Symbol(y, Decl(independentPropertyVariance.ts, 3, 13))
+>a : Symbol(a, Decl(independentPropertyVariance.ts, 3, 18))
+>b : Symbol(b, Decl(independentPropertyVariance.ts, 3, 29))
+
+x === y;
+>x : Symbol(x, Decl(independentPropertyVariance.ts, 2, 13))
+>y : Symbol(y, Decl(independentPropertyVariance.ts, 3, 13))
+
diff --git a/tests/baselines/reference/independentPropertyVariance.types b/tests/baselines/reference/independentPropertyVariance.types
new file mode 100644
index 00000000000..d2808166e01
--- /dev/null
+++ b/tests/baselines/reference/independentPropertyVariance.types
@@ -0,0 +1,18 @@
+=== tests/cases/conformance/types/typeRelationships/comparable/independentPropertyVariance.ts ===
+// Verify that properties can vary independently in comparable relationship
+
+declare const x: { a: 1, b: string };
+>x : { a: 1; b: string; }
+>a : 1
+>b : string
+
+declare const y: { a: number, b: 'a' };
+>y : { a: number; b: "a"; }
+>a : number
+>b : "a"
+
+x === y;
+>x === y : boolean
+>x : { a: 1; b: string; }
+>y : { a: number; b: "a"; }
+
diff --git a/tests/baselines/reference/innerTypeParameterShadowingOuterOne.js b/tests/baselines/reference/innerTypeParameterShadowingOuterOne.js
index 74354468e32..f566bbdd878 100644
--- a/tests/baselines/reference/innerTypeParameterShadowingOuterOne.js
+++ b/tests/baselines/reference/innerTypeParameterShadowingOuterOne.js
@@ -54,4 +54,4 @@ function f2() {
// }
// var x: U;
// x.getDate();
-//}
+//}
diff --git a/tests/baselines/reference/innerTypeParameterShadowingOuterOne2.js b/tests/baselines/reference/innerTypeParameterShadowingOuterOne2.js
index 984584389f6..824061fce1f 100644
--- a/tests/baselines/reference/innerTypeParameterShadowingOuterOne2.js
+++ b/tests/baselines/reference/innerTypeParameterShadowingOuterOne2.js
@@ -75,4 +75,4 @@ var C2 = /** @class */ (function () {
// var x: U;
// x.getDate();
// }
-//}
+//}
diff --git a/tests/baselines/reference/javascriptCommonjsModule.js b/tests/baselines/reference/javascriptCommonjsModule.js
new file mode 100644
index 00000000000..ab517f63805
--- /dev/null
+++ b/tests/baselines/reference/javascriptCommonjsModule.js
@@ -0,0 +1,23 @@
+//// [index.js]
+class Foo {}
+
+class Bar extends Foo {}
+
+module.exports = Bar;
+
+
+//// [index.js]
+var tslib_1 = require("tslib");
+var Foo = /** @class */ (function () {
+ function Foo() {
+ }
+ return Foo;
+}());
+var Bar = /** @class */ (function (_super) {
+ tslib_1.__extends(Bar, _super);
+ function Bar() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ return Bar;
+}(Foo));
+module.exports = Bar;
diff --git a/tests/baselines/reference/javascriptCommonjsModule.symbols b/tests/baselines/reference/javascriptCommonjsModule.symbols
new file mode 100644
index 00000000000..923e0b3467b
--- /dev/null
+++ b/tests/baselines/reference/javascriptCommonjsModule.symbols
@@ -0,0 +1,13 @@
+=== tests/cases/compiler/index.js ===
+class Foo {}
+>Foo : Symbol(Foo, Decl(index.js, 0, 0))
+
+class Bar extends Foo {}
+>Bar : Symbol(Bar, Decl(index.js, 0, 12))
+>Foo : Symbol(Foo, Decl(index.js, 0, 0))
+
+module.exports = Bar;
+>module : Symbol(export=, Decl(index.js, 2, 24))
+>exports : Symbol(export=, Decl(index.js, 2, 24))
+>Bar : Symbol(Bar, Decl(index.js, 0, 12))
+
diff --git a/tests/baselines/reference/javascriptCommonjsModule.types b/tests/baselines/reference/javascriptCommonjsModule.types
new file mode 100644
index 00000000000..88126ce4737
--- /dev/null
+++ b/tests/baselines/reference/javascriptCommonjsModule.types
@@ -0,0 +1,15 @@
+=== tests/cases/compiler/index.js ===
+class Foo {}
+>Foo : Foo
+
+class Bar extends Foo {}
+>Bar : Bar
+>Foo : Foo
+
+module.exports = Bar;
+>module.exports = Bar : typeof Bar
+>module.exports : any
+>module : any
+>exports : any
+>Bar : typeof Bar
+
diff --git a/tests/baselines/reference/keyofAndIndexedAccess.types b/tests/baselines/reference/keyofAndIndexedAccess.types
index 9ae7b793ce2..302cefabf90 100644
--- a/tests/baselines/reference/keyofAndIndexedAccess.types
+++ b/tests/baselines/reference/keyofAndIndexedAccess.types
@@ -352,8 +352,8 @@ function f12(t: [Shape, boolean]) {
>Shape : Shape
let len = getProperty(t, "length");
->len : number
->getProperty(t, "length") : number
+>len : 2
+>getProperty(t, "length") : 2
>getProperty : (obj: T, key: K) => T[K]
>t : [Shape, boolean]
>"length" : "length"
diff --git a/tests/baselines/reference/literalsInComputedProperties1.js b/tests/baselines/reference/literalsInComputedProperties1.js
index c5b0060f626..4611925f2d4 100644
--- a/tests/baselines/reference/literalsInComputedProperties1.js
+++ b/tests/baselines/reference/literalsInComputedProperties1.js
@@ -89,4 +89,4 @@ var X;
var a = X["foo"];
var a0 = X["bar"];
var _a;
-// TODO: make sure that enum still disallow template literals as member names
+// TODO: make sure that enum still disallow template literals as member names
diff --git a/tests/baselines/reference/moduleIdentifiers.js b/tests/baselines/reference/moduleIdentifiers.js
index 04d39019482..d3a654b8670 100644
--- a/tests/baselines/reference/moduleIdentifiers.js
+++ b/tests/baselines/reference/moduleIdentifiers.js
@@ -19,4 +19,4 @@ var M;
//var m: M = M;
var x1 = M.a;
//var x2 = m.a;
-//var q: m.P;
+//var q: m.P;
diff --git a/tests/baselines/reference/moduleResolutionWithExtensions.js b/tests/baselines/reference/moduleResolutionWithExtensions.js
index c1e0310e995..3406bb0adae 100644
--- a/tests/baselines/reference/moduleResolutionWithExtensions.js
+++ b/tests/baselines/reference/moduleResolutionWithExtensions.js
@@ -28,11 +28,11 @@ import j from "./jquery.js"
"use strict";
exports.__esModule = true;
exports["default"] = 0;
-// No extension: '.ts' added
+// No extension: '.ts' added
//// [b.js]
"use strict";
exports.__esModule = true;
-// '.js' extension: stripped and replaced with '.ts'
+// '.js' extension: stripped and replaced with '.ts'
//// [d.js]
"use strict";
exports.__esModule = true;
diff --git a/tests/baselines/reference/neverInference.js b/tests/baselines/reference/neverInference.js
index d13e537eba4..3b570599772 100644
--- a/tests/baselines/reference/neverInference.js
+++ b/tests/baselines/reference/neverInference.js
@@ -1,10 +1,10 @@
//// [neverInference.ts]
-declare function f(x: T[]): T;
+declare function f1(x: T[]): T;
let neverArray: never[] = [];
-let a1 = f([]); // {}
-let a2 = f(neverArray); // never
+let a1 = f1([]); // never
+let a2 = f1(neverArray); // never
// Repro from #19576
@@ -21,11 +21,19 @@ declare function compareNumbers(x: number, y: number): number;
declare function mkList(items: T[], comparator: Comparator): LinkedList;
const list: LinkedList = mkList([], compareNumbers);
+
+// Repro from #19858
+
+declare function f2(as1: a[], as2: a[], cmp: (a1: a, a2: a) => number): void;
+f2(Array.from([0]), [], (a1, a2) => a1 - a2);
+f2(Array.from([]), [0], (a1, a2) => a1 - a2);
//// [neverInference.js]
"use strict";
-var neverArray = [];
-var a1 = f([]); // {}
-var a2 = f(neverArray); // never
-var list = mkList([], compareNumbers);
+let neverArray = [];
+let a1 = f1([]); // never
+let a2 = f1(neverArray); // never
+const list = mkList([], compareNumbers);
+f2(Array.from([0]), [], (a1, a2) => a1 - a2);
+f2(Array.from([]), [0], (a1, a2) => a1 - a2);
diff --git a/tests/baselines/reference/neverInference.symbols b/tests/baselines/reference/neverInference.symbols
index 683e079b2f8..0441770dd3f 100644
--- a/tests/baselines/reference/neverInference.symbols
+++ b/tests/baselines/reference/neverInference.symbols
@@ -1,27 +1,27 @@
=== tests/cases/conformance/types/never/neverInference.ts ===
-declare function f(x: T[]): T;
->f : Symbol(f, Decl(neverInference.ts, 0, 0))
->T : Symbol(T, Decl(neverInference.ts, 0, 19))
->x : Symbol(x, Decl(neverInference.ts, 0, 22))
->T : Symbol(T, Decl(neverInference.ts, 0, 19))
->T : Symbol(T, Decl(neverInference.ts, 0, 19))
+declare function f1(x: T[]): T;
+>f1 : Symbol(f1, Decl(neverInference.ts, 0, 0))
+>T : Symbol(T, Decl(neverInference.ts, 0, 20))
+>x : Symbol(x, Decl(neverInference.ts, 0, 23))
+>T : Symbol(T, Decl(neverInference.ts, 0, 20))
+>T : Symbol(T, Decl(neverInference.ts, 0, 20))
let neverArray: never[] = [];
>neverArray : Symbol(neverArray, Decl(neverInference.ts, 2, 3))
-let a1 = f([]); // {}
+let a1 = f1([]); // never
>a1 : Symbol(a1, Decl(neverInference.ts, 4, 3))
->f : Symbol(f, Decl(neverInference.ts, 0, 0))
+>f1 : Symbol(f1, Decl(neverInference.ts, 0, 0))
-let a2 = f(neverArray); // never
+let a2 = f1(neverArray); // never
>a2 : Symbol(a2, Decl(neverInference.ts, 5, 3))
->f : Symbol(f, Decl(neverInference.ts, 0, 0))
+>f1 : Symbol(f1, Decl(neverInference.ts, 0, 0))
>neverArray : Symbol(neverArray, Decl(neverInference.ts, 2, 3))
// Repro from #19576
type Comparator = (x: T, y: T) => number;
->Comparator : Symbol(Comparator, Decl(neverInference.ts, 5, 23))
+>Comparator : Symbol(Comparator, Decl(neverInference.ts, 5, 24))
>T : Symbol(T, Decl(neverInference.ts, 9, 16))
>x : Symbol(x, Decl(neverInference.ts, 9, 22))
>T : Symbol(T, Decl(neverInference.ts, 9, 16))
@@ -34,7 +34,7 @@ interface LinkedList {
comparator: Comparator,
>comparator : Symbol(LinkedList.comparator, Decl(neverInference.ts, 11, 25))
->Comparator : Symbol(Comparator, Decl(neverInference.ts, 5, 23))
+>Comparator : Symbol(Comparator, Decl(neverInference.ts, 5, 24))
>T : Symbol(T, Decl(neverInference.ts, 11, 21))
nodes: Node
@@ -63,7 +63,7 @@ declare function mkList(items: T[], comparator: Comparator): LinkedList
>items : Symbol(items, Decl(neverInference.ts, 19, 27))
>T : Symbol(T, Decl(neverInference.ts, 19, 24))
>comparator : Symbol(comparator, Decl(neverInference.ts, 19, 38))
->Comparator : Symbol(Comparator, Decl(neverInference.ts, 5, 23))
+>Comparator : Symbol(Comparator, Decl(neverInference.ts, 5, 24))
>T : Symbol(T, Decl(neverInference.ts, 19, 24))
>LinkedList : Symbol(LinkedList, Decl(neverInference.ts, 9, 44))
>T : Symbol(T, Decl(neverInference.ts, 19, 24))
@@ -74,3 +74,38 @@ const list: LinkedList = mkList([], compareNumbers);
>mkList : Symbol(mkList, Decl(neverInference.ts, 18, 62))
>compareNumbers : Symbol(compareNumbers, Decl(neverInference.ts, 16, 49))
+// Repro from #19858
+
+declare function f2(as1: a[], as2: a[], cmp: (a1: a, a2: a) => number): void;
+>f2 : Symbol(f2, Decl(neverInference.ts, 21, 60))
+>a : Symbol(a, Decl(neverInference.ts, 25, 20))
+>as1 : Symbol(as1, Decl(neverInference.ts, 25, 23))
+>a : Symbol(a, Decl(neverInference.ts, 25, 20))
+>as2 : Symbol(as2, Decl(neverInference.ts, 25, 32))
+>a : Symbol(a, Decl(neverInference.ts, 25, 20))
+>cmp : Symbol(cmp, Decl(neverInference.ts, 25, 42))
+>a1 : Symbol(a1, Decl(neverInference.ts, 25, 49))
+>a : Symbol(a, Decl(neverInference.ts, 25, 20))
+>a2 : Symbol(a2, Decl(neverInference.ts, 25, 55))
+>a : Symbol(a, Decl(neverInference.ts, 25, 20))
+
+f2(Array.from([0]), [], (a1, a2) => a1 - a2);
+>f2 : Symbol(f2, Decl(neverInference.ts, 21, 60))
+>Array.from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
+>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
+>from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
+>a1 : Symbol(a1, Decl(neverInference.ts, 26, 25))
+>a2 : Symbol(a2, Decl(neverInference.ts, 26, 28))
+>a1 : Symbol(a1, Decl(neverInference.ts, 26, 25))
+>a2 : Symbol(a2, Decl(neverInference.ts, 26, 28))
+
+f2(Array.from([]), [0], (a1, a2) => a1 - a2);
+>f2 : Symbol(f2, Decl(neverInference.ts, 21, 60))
+>Array.from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
+>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
+>from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
+>a1 : Symbol(a1, Decl(neverInference.ts, 27, 25))
+>a2 : Symbol(a2, Decl(neverInference.ts, 27, 28))
+>a1 : Symbol(a1, Decl(neverInference.ts, 27, 25))
+>a2 : Symbol(a2, Decl(neverInference.ts, 27, 28))
+
diff --git a/tests/baselines/reference/neverInference.types b/tests/baselines/reference/neverInference.types
index a7dd05a3f8b..2f4b9e0cc1e 100644
--- a/tests/baselines/reference/neverInference.types
+++ b/tests/baselines/reference/neverInference.types
@@ -1,6 +1,6 @@
=== tests/cases/conformance/types/never/neverInference.ts ===
-declare function f(x: T[]): T;
->f : (x: T[]) => T
+declare function f1(x: T[]): T;
+>f1 : (x: T[]) => T
>T : T
>x : T[]
>T : T
@@ -10,16 +10,16 @@ let neverArray: never[] = [];
>neverArray : never[]
>[] : never[]
-let a1 = f([]); // {}
->a1 : {}
->f([]) : {}
->f : (x: T[]) => T
+let a1 = f1([]); // never
+>a1 : never
+>f1([]) : never
+>f1 : (x: T[]) => T
>[] : never[]
-let a2 = f(neverArray); // never
+let a2 = f1(neverArray); // never
>a2 : never
->f(neverArray) : never
->f : (x: T[]) => T
+>f1(neverArray) : never
+>f1 : (x: T[]) => T
>neverArray : never[]
// Repro from #19576
@@ -81,3 +81,52 @@ const list: LinkedList = mkList([], compareNumbers);
>[] : never[]
>compareNumbers : (x: number, y: number) => number
+// Repro from #19858
+
+declare function f2(as1: a[], as2: a[], cmp: (a1: a, a2: a) => number): void;
+>f2 : (as1: a[], as2: a[], cmp: (a1: a, a2: a) => number) => void
+>a : a
+>as1 : a[]
+>a : a
+>as2 : a[]
+>a : a
+>cmp : (a1: a, a2: a) => number
+>a1 : a
+>a : a
+>a2 : a
+>a : a
+
+f2(Array.from([0]), [], (a1, a2) => a1 - a2);
+>f2(Array.from([0]), [], (a1, a2) => a1 - a2) : void
+>f2 : (as1: a[], as2: a[], cmp: (a1: a, a2: a) => number) => void
+>Array.from([0]) : number[]
+>Array.from : { (iterable: Iterable): T[]; (iterable: Iterable, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; }
+>Array : ArrayConstructor
+>from : { (iterable: Iterable): T[]; (iterable: Iterable, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; }
+>[0] : number[]
+>0 : 0
+>[] : never[]
+>(a1, a2) => a1 - a2 : (a1: number, a2: number) => number
+>a1 : number
+>a2 : number
+>a1 - a2 : number
+>a1 : number
+>a2 : number
+
+f2(Array.from([]), [0], (a1, a2) => a1 - a2);
+>f2(Array.from([]), [0], (a1, a2) => a1 - a2) : void
+>f2 : (as1: a[], as2: a[], cmp: (a1: a, a2: a) => number) => void
+>Array.from([]) : never[]
+>Array.from : { (iterable: Iterable): T[]; (iterable: Iterable, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; }
+>Array : ArrayConstructor
+>from : { (iterable: Iterable): T[]; (iterable: Iterable, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; }
+>[] : never[]
+>[0] : number[]
+>0 : 0
+>(a1, a2) => a1 - a2 : (a1: number, a2: number) => number
+>a1 : number
+>a2 : number
+>a1 - a2 : number
+>a1 : number
+>a2 : number
+
diff --git a/tests/baselines/reference/newAbstractInstance2.errors.txt b/tests/baselines/reference/newAbstractInstance2.errors.txt
new file mode 100644
index 00000000000..2b2559cc932
--- /dev/null
+++ b/tests/baselines/reference/newAbstractInstance2.errors.txt
@@ -0,0 +1,12 @@
+/b.ts(2,1): error TS2511: Cannot create an instance of an abstract class.
+
+
+==== /a.ts (0 errors) ====
+ export default abstract class {}
+
+==== /b.ts (1 errors) ====
+ import A from "./a";
+ new A();
+ ~~~~~~~
+!!! error TS2511: Cannot create an instance of an abstract class.
+
\ No newline at end of file
diff --git a/tests/baselines/reference/newAbstractInstance2.js b/tests/baselines/reference/newAbstractInstance2.js
new file mode 100644
index 00000000000..2be1012fcd5
--- /dev/null
+++ b/tests/baselines/reference/newAbstractInstance2.js
@@ -0,0 +1,24 @@
+//// [tests/cases/compiler/newAbstractInstance2.ts] ////
+
+//// [a.ts]
+export default abstract class {}
+
+//// [b.ts]
+import A from "./a";
+new A();
+
+
+//// [a.js]
+"use strict";
+exports.__esModule = true;
+var default_1 = /** @class */ (function () {
+ function default_1() {
+ }
+ return default_1;
+}());
+exports["default"] = default_1;
+//// [b.js]
+"use strict";
+exports.__esModule = true;
+var a_1 = require("./a");
+new a_1["default"]();
diff --git a/tests/baselines/reference/newAbstractInstance2.symbols b/tests/baselines/reference/newAbstractInstance2.symbols
new file mode 100644
index 00000000000..2ce91130095
--- /dev/null
+++ b/tests/baselines/reference/newAbstractInstance2.symbols
@@ -0,0 +1,10 @@
+=== /a.ts ===
+export default abstract class {}
+No type information for this code.
+No type information for this code.=== /b.ts ===
+import A from "./a";
+>A : Symbol(A, Decl(b.ts, 0, 6))
+
+new A();
+>A : Symbol(A, Decl(b.ts, 0, 6))
+
diff --git a/tests/baselines/reference/newAbstractInstance2.types b/tests/baselines/reference/newAbstractInstance2.types
new file mode 100644
index 00000000000..8e980d90300
--- /dev/null
+++ b/tests/baselines/reference/newAbstractInstance2.types
@@ -0,0 +1,11 @@
+=== /a.ts ===
+export default abstract class {}
+No type information for this code.
+No type information for this code.=== /b.ts ===
+import A from "./a";
+>A : typeof A
+
+new A();
+>new A() : any
+>A : typeof A
+
diff --git a/tests/baselines/reference/nominalSubtypeCheckOfTypeParameter.js b/tests/baselines/reference/nominalSubtypeCheckOfTypeParameter.js
index 3259b3287fa..5712fb7c244 100644
--- a/tests/baselines/reference/nominalSubtypeCheckOfTypeParameter.js
+++ b/tests/baselines/reference/nominalSubtypeCheckOfTypeParameter.js
@@ -1,20 +1,20 @@
//// [nominalSubtypeCheckOfTypeParameter.ts]
-interface Tuple {
+interface BinaryTuple {
first: T
- second: S
+ second: S
}
interface Sequence {
hasNext(): boolean
- pop(): T
- zip
(seq: Sequence): Sequence>
+ pop(): T
+ zip(seq: Sequence): Sequence>
}
// error, despite the fact that the code explicitly says List extends Sequence, the current rules for infinitely expanding type references
// perform nominal subtyping checks that allow variance for type arguments, but not nominal subtyping for the generic type itself
interface List extends Sequence {
getLength(): number
- zip(seq: Sequence): List