Merge branch 'master' into add-braces
This commit is contained in:
commit
d470f32d8a
|
@ -24752,7 +24752,11 @@ namespace ts {
|
|||
case SyntaxKind.ParenthesizedExpression:
|
||||
return evaluate((<ParenthesizedExpression>expr).expression);
|
||||
case SyntaxKind.Identifier:
|
||||
return nodeIsMissing(expr) ? 0 : evaluateEnumMember(expr, getSymbolOfNode(member.parent), (<Identifier>expr).escapedText);
|
||||
const identifier = <Identifier>expr;
|
||||
if (isInfinityOrNaNString(identifier.escapedText)) {
|
||||
return +(identifier.escapedText);
|
||||
}
|
||||
return nodeIsMissing(expr) ? 0 : evaluateEnumMember(expr, getSymbolOfNode(member.parent), identifier.escapedText);
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
const ex = <PropertyAccessExpression | ElementAccessExpression>expr;
|
||||
|
@ -27061,7 +27065,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
// We do global augmentations seperately from module augmentations (and before creating global types) because they
|
||||
// We do global augmentations separately from module augmentations (and before creating global types) because they
|
||||
// 1. Affect global types. We won't have the correct global types until global augmentations are merged. Also,
|
||||
// 2. Module augmentation instantiation requires creating the type of a module, which, in turn, can require
|
||||
// checking for an export or property on the module (if export=) which, in turn, can fall back to the
|
||||
|
|
|
@ -2653,7 +2653,7 @@ namespace ts {
|
|||
/**
|
||||
* Matches any single directory segment unless it is the last segment and a .min.js file
|
||||
* Breakdown:
|
||||
* [^./] # matches everything up to the first . character (excluding directory seperators)
|
||||
* [^./] # matches everything up to the first . character (excluding directory separators)
|
||||
* (\\.(?!min\\.js$))? # matches . characters but not if they are part of the .min.js file extension
|
||||
*/
|
||||
singleAsteriskRegexFragment: "([^./]|(\\.(?!min\\.js$))?)*",
|
||||
|
|
|
@ -4281,16 +4281,20 @@
|
|||
"category": "Message",
|
||||
"code": 95054
|
||||
},
|
||||
"Add or remove braces in an arrow function": {
|
||||
"Convert '{0}' to mapped object type": {
|
||||
"category": "Message",
|
||||
"code": 95055
|
||||
},
|
||||
"Add braces to arrow function": {
|
||||
"Add or remove braces in an arrow function": {
|
||||
"category": "Message",
|
||||
"code": 95056
|
||||
},
|
||||
"Remove braces from arrow function": {
|
||||
"Add braces to arrow function": {
|
||||
"category": "Message",
|
||||
"code": 95057
|
||||
},
|
||||
"Remove braces from arrow function": {
|
||||
"category": "Message",
|
||||
"code": 95058
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1308,7 +1308,7 @@ namespace ts {
|
|||
let isPreviousTokenSeparator = false;
|
||||
while (true) {
|
||||
const ch = text.charCodeAt(pos);
|
||||
// Numeric seperators are allowed anywhere within a numeric literal, except not at the beginning, or following another separator
|
||||
// Numeric separators are allowed anywhere within a numeric literal, except not at the beginning, or following another separator
|
||||
if (ch === CharacterCodes._) {
|
||||
tokenFlags |= TokenFlags.ContainsSeparator;
|
||||
if (separatorAllowed) {
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
"../services/documentRegistry.ts",
|
||||
"../services/importTracker.ts",
|
||||
"../services/findAllReferences.ts",
|
||||
"../services/getEditsForFileRename.ts",
|
||||
"../services/goToDefinition.ts",
|
||||
"../services/jsDoc.ts",
|
||||
"../services/semver.ts",
|
||||
|
@ -118,6 +119,7 @@
|
|||
"../services/codefixes/requireInTs.ts",
|
||||
"../services/codefixes/useDefaultImport.ts",
|
||||
"../services/codefixes/fixAddModuleReferTypeMissingTypeof.ts",
|
||||
"../services/codefixes/convertToMappedObjectType.ts",
|
||||
"../services/refactors/extractSymbol.ts",
|
||||
"../services/refactors/generateGetAccessorAndSetAccessor.ts",
|
||||
"../services/refactors/moveToNewFile.ts",
|
||||
|
|
|
@ -1008,6 +1008,15 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Add_missing_typeof_95052" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add missing 'typeof']]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[新增遺漏的 'typeof']]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Add_qualifier_to_all_unresolved_variables_matching_a_member_name_95037" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add qualifier to all unresolved variables matching a member name]]></Val>
|
||||
|
@ -1125,6 +1134,15 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";All_variables_are_unused_6199" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[All variables are unused.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[所有變數都未使用。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typech_6011" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Allow default imports from modules with no default export. This does not affect code emit, just typechecking.]]></Val>
|
||||
|
@ -6564,6 +6582,15 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Remove_all_unused_labels_95054" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Remove all unused labels]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[移除所有未使用的標籤]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Remove_declaration_for_Colon_0_90004" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Remove declaration for: '{0}']]></Val>
|
||||
|
@ -6603,6 +6630,24 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Remove_unused_label_95053" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Remove unused label]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[移除未使用的標籤]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Remove_variable_statement_90010" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Remove variable statement]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[移除變數陳述式]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Replace_import_with_0_95015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Replace import with '{0}'.]]></Val>
|
||||
|
|
|
@ -1019,10 +1019,13 @@
|
|||
</Item>
|
||||
<Item ItemId=";Add_missing_typeof_95052" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add missing typeof]]></Val>
|
||||
<Val><![CDATA[Add missing 'typeof']]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Ajouter un typeof manquant]]></Val>
|
||||
<Val><![CDATA[Ajouter un 'typeof' manquant]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Add missing typeof]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
|
@ -1143,6 +1146,15 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";All_variables_are_unused_6199" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[All variables are unused.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Toutes les variables sont inutilisées.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typech_6011" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Allow default imports from modules with no default export. This does not affect code emit, just typechecking.]]></Val>
|
||||
|
@ -6582,6 +6594,15 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Remove_all_unused_labels_95054" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Remove all unused labels]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Supprimer toutes les étiquettes inutilisées]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Remove_declaration_for_Colon_0_90004" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Remove declaration for: '{0}']]></Val>
|
||||
|
@ -6621,6 +6642,24 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Remove_unused_label_95053" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Remove unused label]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Supprimer l'étiquette inutilisée]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Remove_variable_statement_90010" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Remove variable statement]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Supprimer l'instruction de variable]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Replace_import_with_0_95015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Replace import with '{0}'.]]></Val>
|
||||
|
|
|
@ -1007,6 +1007,15 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Add_missing_typeof_95052" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add missing 'typeof']]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Добавить отсутствующий "typeof"]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Add_qualifier_to_all_unresolved_variables_matching_a_member_name_95037" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add qualifier to all unresolved variables matching a member name]]></Val>
|
||||
|
@ -1124,6 +1133,15 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";All_variables_are_unused_6199" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[All variables are unused.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Ни одна переменная не используется.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typech_6011" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Allow default imports from modules with no default export. This does not affect code emit, just typechecking.]]></Val>
|
||||
|
@ -6563,6 +6581,15 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Remove_all_unused_labels_95054" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Remove all unused labels]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Удалить все неиспользуемые метки]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Remove_declaration_for_Colon_0_90004" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Remove declaration for: '{0}']]></Val>
|
||||
|
@ -6602,6 +6629,24 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Remove_unused_label_95053" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Remove unused label]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Удалить неиспользуемую метку]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Remove_variable_statement_90010" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Remove variable statement]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Удалить оператор с переменной]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Replace_import_with_0_95015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Replace import with '{0}'.]]></Val>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
"../services/documentRegistry.ts",
|
||||
"../services/importTracker.ts",
|
||||
"../services/findAllReferences.ts",
|
||||
"../services/getEditsForFileRename.ts",
|
||||
"../services/goToDefinition.ts",
|
||||
"../services/jsDoc.ts",
|
||||
"../services/semver.ts",
|
||||
|
@ -114,6 +115,7 @@
|
|||
"../services/codefixes/requireInTs.ts",
|
||||
"../services/codefixes/useDefaultImport.ts",
|
||||
"../services/codefixes/fixAddModuleReferTypeMissingTypeof.ts",
|
||||
"../services/codefixes/convertToMappedObjectType.ts",
|
||||
"../services/refactors/extractSymbol.ts",
|
||||
"../services/refactors/generateGetAccessorAndSetAccessor.ts",
|
||||
"../services/refactors/moveToNewFile.ts",
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
"../services/documentRegistry.ts",
|
||||
"../services/importTracker.ts",
|
||||
"../services/findAllReferences.ts",
|
||||
"../services/getEditsForFileRename.ts",
|
||||
"../services/goToDefinition.ts",
|
||||
"../services/jsDoc.ts",
|
||||
"../services/semver.ts",
|
||||
|
@ -120,6 +121,7 @@
|
|||
"../services/codefixes/requireInTs.ts",
|
||||
"../services/codefixes/useDefaultImport.ts",
|
||||
"../services/codefixes/fixAddModuleReferTypeMissingTypeof.ts",
|
||||
"../services/codefixes/convertToMappedObjectType.ts",
|
||||
"../services/refactors/extractSymbol.ts",
|
||||
"../services/refactors/generateGetAccessorAndSetAccessor.ts",
|
||||
"../services/refactors/moveToNewFile.ts",
|
||||
|
|
56
src/services/codefixes/convertToMappedObjectType.ts
Normal file
56
src/services/codefixes/convertToMappedObjectType.ts
Normal file
|
@ -0,0 +1,56 @@
|
|||
/* @internal */
|
||||
namespace ts.codefix {
|
||||
const fixIdAddMissingTypeof = "fixConvertToMappedObjectType";
|
||||
const fixId = fixIdAddMissingTypeof;
|
||||
const errorCodes = [Diagnostics.An_index_signature_parameter_type_cannot_be_a_union_type_Consider_using_a_mapped_object_type_instead.code];
|
||||
|
||||
type FixableDeclaration = InterfaceDeclaration | TypeAliasDeclaration;
|
||||
|
||||
registerCodeFix({
|
||||
errorCodes,
|
||||
getCodeActions: context => {
|
||||
const { sourceFile, span } = context;
|
||||
const info = getInfo(sourceFile, span.start);
|
||||
if (!info) return undefined;
|
||||
const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, info));
|
||||
const name = idText(info.container.name);
|
||||
return [createCodeFixAction(fixId, changes, [Diagnostics.Convert_0_to_mapped_object_type, name], fixId, [Diagnostics.Convert_0_to_mapped_object_type, name])];
|
||||
},
|
||||
fixIds: [fixId],
|
||||
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => {
|
||||
const info = getInfo(diag.file, diag.start);
|
||||
if (info) doChange(changes, diag.file, info);
|
||||
})
|
||||
});
|
||||
|
||||
interface Info { readonly indexSignature: IndexSignatureDeclaration; readonly container: FixableDeclaration; }
|
||||
function getInfo(sourceFile: SourceFile, pos: number): Info | undefined {
|
||||
const token = getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false);
|
||||
const indexSignature = cast(token.parent.parent, isIndexSignatureDeclaration);
|
||||
if (isClassDeclaration(indexSignature.parent)) return undefined;
|
||||
const container = isInterfaceDeclaration(indexSignature.parent) ? indexSignature.parent : cast(indexSignature.parent.parent, isTypeAliasDeclaration);
|
||||
return { indexSignature, container };
|
||||
}
|
||||
|
||||
function createTypeAliasFromInterface(declaration: FixableDeclaration, type: TypeNode): TypeAliasDeclaration {
|
||||
return createTypeAliasDeclaration(declaration.decorators, declaration.modifiers, declaration.name, declaration.typeParameters, type);
|
||||
}
|
||||
|
||||
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, { indexSignature, container }: Info): void {
|
||||
const members = isInterfaceDeclaration(container) ? container.members : (<TypeLiteralNode>container.type).members;
|
||||
const otherMembers = members.filter(member => !isIndexSignatureDeclaration(member));
|
||||
const parameter = first(indexSignature.parameters);
|
||||
const mappedTypeParameter = createTypeParameterDeclaration(cast(parameter.name, isIdentifier), parameter.type);
|
||||
const mappedIntersectionType = createMappedTypeNode(
|
||||
hasReadonlyModifier(indexSignature) ? createModifier(SyntaxKind.ReadonlyKeyword) : undefined,
|
||||
mappedTypeParameter,
|
||||
indexSignature.questionToken,
|
||||
indexSignature.type);
|
||||
const intersectionType = createIntersectionTypeNode([
|
||||
...getAllSuperTypeNodes(container),
|
||||
mappedIntersectionType,
|
||||
...(otherMembers.length ? [createTypeLiteralNode(otherMembers)] : emptyArray),
|
||||
]);
|
||||
changes.replaceNode(sourceFile, container, createTypeAliasFromInterface(container, intersectionType));
|
||||
}
|
||||
}
|
|
@ -211,7 +211,7 @@ namespace ts.codefix {
|
|||
|
||||
// if this file doesn't have any import statements, insert an import statement and then insert a new line
|
||||
// between the only import statement and user code. Otherwise just insert the statement because chances
|
||||
// are there are already a new line seperating code and import statements.
|
||||
// are there are already a new line separating code and import statements.
|
||||
return createCodeAction(Diagnostics.Import_0_from_module_1, [symbolName, moduleSpecifierWithoutQuotes], changes);
|
||||
}
|
||||
|
||||
|
|
|
@ -422,7 +422,7 @@ namespace ts.Completions {
|
|||
case SyntaxKind.CallExpression:
|
||||
case SyntaxKind.NewExpression:
|
||||
if (!isRequireCall(node.parent, /*checkArgumentIsStringLiteralLike*/ false) && !isImportCall(node.parent)) {
|
||||
const argumentInfo = SignatureHelp.getImmediatelyContainingArgumentInfo(node, position, sourceFile);
|
||||
const argumentInfo = SignatureHelp.getArgumentInfoForCompletions(node, position, sourceFile);
|
||||
// Get string literal completions from specialized signatures of the target
|
||||
// i.e. declare function f(a: 'A');
|
||||
// f("/*completion position*/")
|
||||
|
@ -452,7 +452,7 @@ namespace ts.Completions {
|
|||
}
|
||||
}
|
||||
|
||||
function getStringLiteralCompletionsFromSignature(argumentInfo: SignatureHelp.ArgumentListInfo, checker: TypeChecker): StringLiteralCompletionsFromTypes {
|
||||
function getStringLiteralCompletionsFromSignature(argumentInfo: SignatureHelp.ArgumentInfoForCompletions, checker: TypeChecker): StringLiteralCompletionsFromTypes {
|
||||
let isNewIdentifier = false;
|
||||
|
||||
const uniques = createMap<true>();
|
||||
|
@ -460,7 +460,7 @@ namespace ts.Completions {
|
|||
checker.getResolvedSignature(argumentInfo.invocation, candidates, argumentInfo.argumentCount);
|
||||
const types = flatMap(candidates, candidate => {
|
||||
if (!candidate.hasRestParameter && argumentInfo.argumentCount > candidate.parameters.length) return;
|
||||
const type = checker.getParameterType(candidate, argumentInfo.argumentIndex!); // TODO: GH#18217
|
||||
const type = checker.getParameterType(candidate, argumentInfo.argumentIndex);
|
||||
isNewIdentifier = isNewIdentifier || !!(type.flags & TypeFlags.String);
|
||||
return getStringLiteralTypes(type, checker, uniques);
|
||||
});
|
||||
|
@ -720,10 +720,10 @@ namespace ts.Completions {
|
|||
case SyntaxKind.OpenBraceToken:
|
||||
return isJsxExpression(parent) && parent.parent.kind !== SyntaxKind.JsxElement ? checker.getContextualTypeForJsxAttribute(parent.parent) : undefined;
|
||||
default:
|
||||
const argInfo = SignatureHelp.getImmediatelyContainingArgumentInfo(currentToken, position, sourceFile);
|
||||
const argInfo = SignatureHelp.getArgumentInfoForCompletions(currentToken, position, sourceFile);
|
||||
return argInfo
|
||||
// At `,`, treat this as the next argument after the comma.
|
||||
? checker.getContextualTypeForArgumentAtIndex(argInfo.invocation, argInfo.argumentIndex! + (currentToken.kind === SyntaxKind.CommaToken ? 1 : 0)) // TODO: GH#18217
|
||||
? checker.getContextualTypeForArgumentAtIndex(argInfo.invocation, argInfo.argumentIndex + (currentToken.kind === SyntaxKind.CommaToken ? 1 : 0))
|
||||
: isEqualityOperatorKind(currentToken.kind) && isBinaryExpression(parent) && isEqualityOperatorKind(parent.operatorToken.kind)
|
||||
// completion at `x ===/**/` should be for the right side
|
||||
? checker.getTypeAtLocation(parent.left)
|
||||
|
|
|
@ -32,23 +32,20 @@ namespace ts {
|
|||
}
|
||||
|
||||
function getImportsToUpdate(program: Program, oldFilePath: string, host: LanguageServiceHost): ReadonlyArray<ToUpdate> {
|
||||
const checker = program.getTypeChecker();
|
||||
const result: ToUpdate[] = [];
|
||||
for (const sourceFile of program.getSourceFiles()) {
|
||||
for (const ref of sourceFile.referencedFiles) {
|
||||
if (!program.getSourceFileFromReference(sourceFile, ref) && resolveTripleslashReference(ref.fileName, sourceFile.fileName) === oldFilePath) {
|
||||
if (resolveTripleslashReference(ref.fileName, sourceFile.fileName) === oldFilePath) {
|
||||
result.push({ sourceFile, toUpdate: ref });
|
||||
}
|
||||
}
|
||||
|
||||
for (const importStringLiteral of sourceFile.imports) {
|
||||
// If it resolved to something already, ignore.
|
||||
if (checker.getSymbolAtLocation(importStringLiteral)) continue;
|
||||
|
||||
const resolved = host.resolveModuleNames
|
||||
? host.getResolvedModuleWithFailedLookupLocationsFromCache && host.getResolvedModuleWithFailedLookupLocationsFromCache(importStringLiteral.text, sourceFile.fileName)
|
||||
: program.getResolvedModuleWithFailedLookupLocationsFromCache(importStringLiteral.text, sourceFile.fileName);
|
||||
if (resolved && contains(resolved.failedLookupLocations, oldFilePath)) {
|
||||
// We may or may not have picked up on the file being renamed, so maybe successfully resolved to oldFilePath, or maybe that's in failedLookupLocations
|
||||
if (resolved && contains(resolved.resolvedModule ? [resolved.resolvedModule.resolvedFileName] : resolved.failedLookupLocations, oldFilePath)) {
|
||||
result.push({ sourceFile, toUpdate: importStringLiteral });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -579,6 +579,9 @@ namespace ts.FindAllReferences {
|
|||
else if (isBinaryExpression(decl)) { // `module.exports = class {}`
|
||||
return Debug.assertDefined(decl.right.symbol);
|
||||
}
|
||||
else if (isSourceFile(decl)) { // json module
|
||||
return Debug.assertDefined(decl.symbol);
|
||||
}
|
||||
return Debug.fail();
|
||||
}
|
||||
|
||||
|
|
|
@ -297,8 +297,8 @@ namespace ts.Completions.PathCompletions {
|
|||
// after the last '/' that appears in the fragment because that's where the replacement span
|
||||
// starts
|
||||
if (fragmentDirectory !== undefined) {
|
||||
const moduleNameWithSeperator = ensureTrailingDirectorySeparator(fragmentDirectory);
|
||||
return nonRelativeModuleNames.map(nonRelativeModuleName => removePrefix(nonRelativeModuleName, moduleNameWithSeperator));
|
||||
const moduleNameWithSeparator = ensureTrailingDirectorySeparator(fragmentDirectory);
|
||||
return nonRelativeModuleNames.map(nonRelativeModuleName => removePrefix(nonRelativeModuleName, moduleNameWithSeparator));
|
||||
}
|
||||
return nonRelativeModuleNames;
|
||||
}
|
||||
|
@ -410,7 +410,7 @@ namespace ts.Completions.PathCompletions {
|
|||
return result;
|
||||
}
|
||||
|
||||
// Replace everything after the last directory seperator that appears
|
||||
// Replace everything after the last directory separator that appears
|
||||
function getDirectoryFragmentTextSpan(text: string, textStart: number): TextSpan | undefined {
|
||||
const index = Math.max(text.lastIndexOf(directorySeparator), text.lastIndexOf("\\"));
|
||||
const offset = index !== -1 ? index + 1 : 0;
|
||||
|
|
|
@ -88,7 +88,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
|
|||
return { renameFilename, renameLocation, edits };
|
||||
}
|
||||
|
||||
function isConvertableName (name: DeclarationName): name is AcceptedNameType {
|
||||
function isConvertibleName (name: DeclarationName): name is AcceptedNameType {
|
||||
return isIdentifier(name) || isStringLiteral(name);
|
||||
}
|
||||
|
||||
|
@ -125,7 +125,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
|
|||
// make sure declaration have AccessibilityModifier or Static Modifier or Readonly Modifier
|
||||
const meaning = ModifierFlags.AccessibilityModifier | ModifierFlags.Static | ModifierFlags.Readonly;
|
||||
if (!declaration || !rangeOverlapsWithStartEnd(declaration.name, startPosition, endPosition!) // TODO: GH#18217
|
||||
|| !isConvertableName(declaration.name) || (getModifierFlags(declaration) | meaning) !== meaning) return undefined;
|
||||
|| !isConvertibleName(declaration.name) || (getModifierFlags(declaration) | meaning) !== meaning) return undefined;
|
||||
|
||||
const name = declaration.name.text;
|
||||
const startWithUnderscore = startsWithUnderscore(name);
|
||||
|
|
|
@ -1,17 +1,20 @@
|
|||
/* @internal */
|
||||
namespace ts.SignatureHelp {
|
||||
export const enum ArgumentListKind {
|
||||
const enum ArgumentListKind {
|
||||
TypeArguments,
|
||||
CallArguments,
|
||||
TaggedTemplateArguments,
|
||||
JSXAttributesArguments
|
||||
}
|
||||
|
||||
export interface ArgumentListInfo {
|
||||
const enum InvocationKind { Call, TypeArgs }
|
||||
type Invocation = { kind: InvocationKind.Call, node: CallLikeExpression } | { kind: InvocationKind.TypeArgs, called: Expression };
|
||||
|
||||
interface ArgumentListInfo {
|
||||
kind: ArgumentListKind;
|
||||
invocation: CallLikeExpression;
|
||||
invocation: Invocation;
|
||||
argumentsSpan: TextSpan;
|
||||
argumentIndex?: number;
|
||||
argumentIndex: number;
|
||||
/** argumentCount is the *apparent* number of arguments. */
|
||||
argumentCount: number;
|
||||
}
|
||||
|
@ -32,32 +35,39 @@ namespace ts.SignatureHelp {
|
|||
cancellationToken.throwIfCancellationRequested();
|
||||
|
||||
// Semantic filtering of signature help
|
||||
const call = argumentInfo.invocation;
|
||||
const candidates: Signature[] = [];
|
||||
const resolvedSignature = typeChecker.getResolvedSignature(call, candidates, argumentInfo.argumentCount);
|
||||
const candidateInfo = getCandidateInfo(argumentInfo, typeChecker);
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
|
||||
if (!candidates.length) {
|
||||
if (!candidateInfo) {
|
||||
// We didn't have any sig help items produced by the TS compiler. If this is a JS
|
||||
// file, then see if we can figure out anything better.
|
||||
if (isSourceFileJavaScript(sourceFile)) {
|
||||
return createJavaScriptSignatureHelpItems(argumentInfo, program, cancellationToken);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return typeChecker.runWithCancellationToken(cancellationToken, typeChecker => createSignatureHelpItems(candidates, resolvedSignature!, argumentInfo, typeChecker));
|
||||
return typeChecker.runWithCancellationToken(cancellationToken, typeChecker => createSignatureHelpItems(candidateInfo.candidates, candidateInfo.resolvedSignature, argumentInfo, sourceFile, typeChecker));
|
||||
}
|
||||
|
||||
function getCandidateInfo(argumentInfo: ArgumentListInfo, checker: TypeChecker): { readonly candidates: ReadonlyArray<Signature>, readonly resolvedSignature: Signature } | undefined {
|
||||
const { invocation } = argumentInfo;
|
||||
if (invocation.kind === InvocationKind.Call) {
|
||||
const candidates: Signature[] = [];
|
||||
const resolvedSignature = checker.getResolvedSignature(invocation.node, candidates, argumentInfo.argumentCount)!; // TODO: GH#18217
|
||||
return candidates.length === 0 ? undefined : { candidates, resolvedSignature };
|
||||
}
|
||||
else {
|
||||
const type = checker.getTypeAtLocation(invocation.called)!; // TODO: GH#18217
|
||||
const signatures = isNewExpression(invocation.called.parent) ? type.getConstructSignatures() : type.getCallSignatures();
|
||||
const candidates = signatures.filter(candidate => !!candidate.typeParameters && candidate.typeParameters.length >= argumentInfo.argumentCount);
|
||||
return candidates.length === 0 ? undefined : { candidates, resolvedSignature: first(candidates) };
|
||||
}
|
||||
}
|
||||
|
||||
function createJavaScriptSignatureHelpItems(argumentInfo: ArgumentListInfo, program: Program, cancellationToken: CancellationToken): SignatureHelpItems | undefined {
|
||||
if (argumentInfo.invocation.kind !== SyntaxKind.CallExpression) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// See if we can find some symbol with the call expression name that has call signatures.
|
||||
const callExpression = argumentInfo.invocation;
|
||||
const expression = callExpression.expression;
|
||||
const expression = getExpressionFromInvocation(argumentInfo.invocation);
|
||||
const name = isIdentifier(expression) ? expression : isPropertyAccessExpression(expression) ? expression.name : undefined;
|
||||
if (!name || !name.escapedText) {
|
||||
return undefined;
|
||||
|
@ -76,7 +86,7 @@ namespace ts.SignatureHelp {
|
|||
if (type) {
|
||||
const callSignatures = type.getCallSignatures();
|
||||
if (callSignatures && callSignatures.length) {
|
||||
return typeChecker.runWithCancellationToken(cancellationToken, typeChecker => createSignatureHelpItems(callSignatures, callSignatures[0], argumentInfo, typeChecker));
|
||||
return typeChecker.runWithCancellationToken(cancellationToken, typeChecker => createSignatureHelpItems(callSignatures, callSignatures[0], argumentInfo, sourceFile, typeChecker));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -85,13 +95,25 @@ namespace ts.SignatureHelp {
|
|||
}
|
||||
}
|
||||
|
||||
export interface ArgumentInfoForCompletions {
|
||||
readonly invocation: CallLikeExpression;
|
||||
readonly argumentIndex: number;
|
||||
readonly argumentCount: number;
|
||||
}
|
||||
export function getArgumentInfoForCompletions(node: Node, position: number, sourceFile: SourceFile): ArgumentInfoForCompletions | undefined {
|
||||
const info = getImmediatelyContainingArgumentInfo(node, position, sourceFile);
|
||||
return !info || info.kind === ArgumentListKind.TypeArguments || info.invocation.kind === InvocationKind.TypeArgs ? undefined
|
||||
: { invocation: info.invocation.node, argumentCount: info.argumentCount, argumentIndex: info.argumentIndex };
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns relevant information for the argument list and the current argument if we are
|
||||
* in the argument of an invocation; returns undefined otherwise.
|
||||
*/
|
||||
export function getImmediatelyContainingArgumentInfo(node: Node, position: number, sourceFile: SourceFile): ArgumentListInfo | undefined {
|
||||
function getImmediatelyContainingArgumentInfo(node: Node, position: number, sourceFile: SourceFile): ArgumentListInfo | undefined {
|
||||
const { parent } = node;
|
||||
if (isCallOrNewExpression(parent)) {
|
||||
const invocation = parent;
|
||||
let list: Node | undefined;
|
||||
let argumentIndex: number;
|
||||
|
||||
|
@ -134,56 +156,63 @@ namespace ts.SignatureHelp {
|
|||
Debug.assertLessThan(argumentIndex, argumentCount);
|
||||
}
|
||||
const argumentsSpan = getApplicableSpanForArguments(list, sourceFile);
|
||||
return { kind, invocation: parent, argumentsSpan, argumentIndex, argumentCount };
|
||||
return { kind, invocation: { kind: InvocationKind.Call, node: invocation }, argumentsSpan, argumentIndex, argumentCount };
|
||||
}
|
||||
else if (node.kind === SyntaxKind.NoSubstitutionTemplateLiteral && parent.kind === SyntaxKind.TaggedTemplateExpression) {
|
||||
else if (isNoSubstitutionTemplateLiteral(node) && isTaggedTemplateExpression(parent)) {
|
||||
// Check if we're actually inside the template;
|
||||
// otherwise we'll fall out and return undefined.
|
||||
if (isInsideTemplateLiteral(<LiteralExpression>node, position)) {
|
||||
return getArgumentListInfoForTemplate(<TaggedTemplateExpression>node.parent, /*argumentIndex*/ 0, sourceFile);
|
||||
if (isInsideTemplateLiteral(node, position)) {
|
||||
return getArgumentListInfoForTemplate(parent, /*argumentIndex*/ 0, sourceFile);
|
||||
}
|
||||
}
|
||||
else if (node.kind === SyntaxKind.TemplateHead && parent.parent.kind === SyntaxKind.TaggedTemplateExpression) {
|
||||
const templateExpression = <TemplateExpression>node.parent;
|
||||
else if (isTemplateHead(node) && parent.parent.kind === SyntaxKind.TaggedTemplateExpression) {
|
||||
const templateExpression = <TemplateExpression>parent;
|
||||
const tagExpression = <TaggedTemplateExpression>templateExpression.parent;
|
||||
Debug.assert(templateExpression.kind === SyntaxKind.TemplateExpression);
|
||||
|
||||
const argumentIndex = isInsideTemplateLiteral(<LiteralExpression>node, position) ? 0 : 1;
|
||||
const argumentIndex = isInsideTemplateLiteral(node, position) ? 0 : 1;
|
||||
|
||||
return getArgumentListInfoForTemplate(tagExpression, argumentIndex, sourceFile);
|
||||
}
|
||||
else if (parent.kind === SyntaxKind.TemplateSpan && parent.parent.parent.kind === SyntaxKind.TaggedTemplateExpression) {
|
||||
const templateSpan = <TemplateSpan>node.parent;
|
||||
const templateExpression = templateSpan.parent;
|
||||
const tagExpression = <TaggedTemplateExpression>templateExpression.parent;
|
||||
Debug.assert(templateExpression.kind === SyntaxKind.TemplateExpression);
|
||||
else if (isTemplateSpan(parent) && isTaggedTemplateExpression(parent.parent.parent)) {
|
||||
const templateSpan = parent;
|
||||
const tagExpression = parent.parent.parent;
|
||||
|
||||
// If we're just after a template tail, don't show signature help.
|
||||
if (node.kind === SyntaxKind.TemplateTail && !isInsideTemplateLiteral(<LiteralExpression>node, position)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const spanIndex = templateExpression.templateSpans.indexOf(templateSpan);
|
||||
const spanIndex = templateSpan.parent.templateSpans.indexOf(templateSpan);
|
||||
const argumentIndex = getArgumentIndexForTemplatePiece(spanIndex, node, position);
|
||||
|
||||
return getArgumentListInfoForTemplate(tagExpression, argumentIndex, sourceFile);
|
||||
}
|
||||
else if (node.parent && isJsxOpeningLikeElement(node.parent)) {
|
||||
else if (isJsxOpeningLikeElement(parent)) {
|
||||
// Provide a signature help for JSX opening element or JSX self-closing element.
|
||||
// This is not guarantee that JSX tag-name is resolved into stateless function component. (that is done in "getSignatureHelpItems")
|
||||
// i.e
|
||||
// export function MainButton(props: ButtonProps, context: any): JSX.Element { ... }
|
||||
// <MainButton /*signatureHelp*/
|
||||
const attributeSpanStart = node.parent.attributes.getFullStart();
|
||||
const attributeSpanEnd = skipTrivia(sourceFile.text, node.parent.attributes.getEnd(), /*stopAfterLineBreak*/ false);
|
||||
const attributeSpanStart = parent.attributes.pos;
|
||||
const attributeSpanEnd = skipTrivia(sourceFile.text, parent.attributes.end, /*stopAfterLineBreak*/ false);
|
||||
return {
|
||||
kind: ArgumentListKind.JSXAttributesArguments,
|
||||
invocation: node.parent,
|
||||
invocation: { kind: InvocationKind.Call, node: parent },
|
||||
argumentsSpan: createTextSpan(attributeSpanStart, attributeSpanEnd - attributeSpanStart),
|
||||
argumentIndex: 0,
|
||||
argumentCount: 1
|
||||
};
|
||||
}
|
||||
else {
|
||||
const typeArgInfo = isPossiblyTypeArgumentPosition(node, sourceFile);
|
||||
if (typeArgInfo) {
|
||||
const { called, nTypeArguments } = typeArgInfo;
|
||||
const invocation: Invocation = { kind: InvocationKind.TypeArgs, called };
|
||||
const argumentsSpan = createTextSpanFromBounds(called.getStart(sourceFile), node.end);
|
||||
return { kind: ArgumentListKind.TypeArguments, invocation, argumentsSpan, argumentIndex: nTypeArguments, argumentCount: nTypeArguments + 1 };
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
@ -269,7 +298,7 @@ namespace ts.SignatureHelp {
|
|||
}
|
||||
return {
|
||||
kind: ArgumentListKind.TaggedTemplateArguments,
|
||||
invocation: tagExpression,
|
||||
invocation: { kind: InvocationKind.Call, node: tagExpression },
|
||||
argumentsSpan: getApplicableSpanForTaggedTemplate(tagExpression, sourceFile),
|
||||
argumentIndex,
|
||||
argumentCount
|
||||
|
@ -313,25 +342,15 @@ namespace ts.SignatureHelp {
|
|||
return createTextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart);
|
||||
}
|
||||
|
||||
export function getContainingArgumentInfo(node: Node, position: number, sourceFile: SourceFile): ArgumentListInfo | undefined {
|
||||
for (let n = node; n.kind !== SyntaxKind.SourceFile; n = n.parent) {
|
||||
if (isFunctionBlock(n)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getContainingArgumentInfo(node: Node, position: number, sourceFile: SourceFile): ArgumentListInfo | undefined {
|
||||
for (let n = node; !isBlock(n) && !isSourceFile(n); n = n.parent) {
|
||||
// If the node is not a subspan of its parent, this is a big problem.
|
||||
// There have been crashes that might be caused by this violation.
|
||||
if (n.pos < n.parent.pos || n.end > n.parent.end) {
|
||||
Debug.fail("Node of kind " + n.kind + " is not a subspan of its parent of kind " + n.parent.kind);
|
||||
}
|
||||
|
||||
Debug.assert(rangeContainsRange(n.parent, n), "Not a subspan", () => `Child: ${Debug.showSyntaxKind(n)}, parent: ${Debug.showSyntaxKind(n.parent)}`);
|
||||
const argumentInfo = getImmediatelyContainingArgumentInfo(n, position, sourceFile);
|
||||
if (argumentInfo) {
|
||||
return argumentInfo;
|
||||
}
|
||||
|
||||
|
||||
// TODO: Handle generic call with incomplete syntax
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
@ -343,16 +362,20 @@ namespace ts.SignatureHelp {
|
|||
return children[indexOfOpenerToken + 1];
|
||||
}
|
||||
|
||||
function getExpressionFromInvocation(invocation: Invocation): Expression {
|
||||
return invocation.kind === InvocationKind.Call ? getInvokedExpression(invocation.node) : invocation.called;
|
||||
}
|
||||
|
||||
const signatureHelpNodeBuilderFlags = NodeBuilderFlags.OmitParameterModifiers | NodeBuilderFlags.IgnoreErrors;
|
||||
function createSignatureHelpItems(candidates: Signature[], resolvedSignature: Signature, argumentListInfo: ArgumentListInfo, typeChecker: TypeChecker): SignatureHelpItems {
|
||||
function createSignatureHelpItems(candidates: ReadonlyArray<Signature>, resolvedSignature: Signature, argumentListInfo: ArgumentListInfo, sourceFile: SourceFile, typeChecker: TypeChecker): SignatureHelpItems {
|
||||
const { argumentCount, argumentsSpan: applicableSpan, invocation, argumentIndex } = argumentListInfo;
|
||||
const isTypeParameterList = argumentListInfo.kind === ArgumentListKind.TypeArguments;
|
||||
|
||||
const callTarget = getInvokedExpression(invocation);
|
||||
const callTargetSymbol = typeChecker.getSymbolAtLocation(callTarget);
|
||||
const enclosingDeclaration = invocation.kind === InvocationKind.Call ? invocation.node : invocation.called;
|
||||
const callTargetSymbol = typeChecker.getSymbolAtLocation(getExpressionFromInvocation(invocation));
|
||||
const callTargetDisplayParts = callTargetSymbol && symbolToDisplayParts(typeChecker, callTargetSymbol, /*enclosingDeclaration*/ undefined, /*meaning*/ undefined);
|
||||
const printer = createPrinter({ removeComments: true });
|
||||
const items: SignatureHelpItem[] = map(candidates, candidateSignature => {
|
||||
const items = candidates.map<SignatureHelpItem>(candidateSignature => {
|
||||
let signatureHelpParameters: SignatureHelpParameter[];
|
||||
const prefixDisplayParts: SymbolDisplayPart[] = [];
|
||||
const suffixDisplayParts: SymbolDisplayPart[] = [];
|
||||
|
@ -369,9 +392,9 @@ namespace ts.SignatureHelp {
|
|||
signatureHelpParameters = typeParameters && typeParameters.length > 0 ? map(typeParameters, createSignatureHelpParameterForTypeParameter) : emptyArray;
|
||||
suffixDisplayParts.push(punctuationPart(SyntaxKind.GreaterThanToken));
|
||||
const parameterParts = mapToDisplayParts(writer => {
|
||||
const thisParameter = candidateSignature.thisParameter ? [typeChecker.symbolToParameterDeclaration(candidateSignature.thisParameter, invocation, signatureHelpNodeBuilderFlags)!] : [];
|
||||
const params = createNodeArray([...thisParameter, ...map(candidateSignature.parameters, param => typeChecker.symbolToParameterDeclaration(param, invocation, signatureHelpNodeBuilderFlags)!)]);
|
||||
printer.writeList(ListFormat.CallExpressionArguments, params, getSourceFileOfNode(getParseTreeNode(invocation)), writer);
|
||||
const thisParameter = candidateSignature.thisParameter ? [typeChecker.symbolToParameterDeclaration(candidateSignature.thisParameter, enclosingDeclaration, signatureHelpNodeBuilderFlags)!] : [];
|
||||
const params = createNodeArray([...thisParameter, ...candidateSignature.parameters.map(param => typeChecker.symbolToParameterDeclaration(param, enclosingDeclaration, signatureHelpNodeBuilderFlags)!)]);
|
||||
printer.writeList(ListFormat.CallExpressionArguments, params, sourceFile, writer);
|
||||
});
|
||||
addRange(suffixDisplayParts, parameterParts);
|
||||
}
|
||||
|
@ -379,8 +402,8 @@ namespace ts.SignatureHelp {
|
|||
isVariadic = candidateSignature.hasRestParameter;
|
||||
const typeParameterParts = mapToDisplayParts(writer => {
|
||||
if (candidateSignature.typeParameters && candidateSignature.typeParameters.length) {
|
||||
const args = createNodeArray(map(candidateSignature.typeParameters, p => typeChecker.typeParameterToDeclaration(p, invocation)!));
|
||||
printer.writeList(ListFormat.TypeParameters, args, getSourceFileOfNode(getParseTreeNode(invocation)), writer);
|
||||
const args = createNodeArray(candidateSignature.typeParameters.map(p => typeChecker.typeParameterToDeclaration(p, enclosingDeclaration)!));
|
||||
printer.writeList(ListFormat.TypeParameters, args, sourceFile, writer);
|
||||
}
|
||||
});
|
||||
addRange(prefixDisplayParts, typeParameterParts);
|
||||
|
@ -395,10 +418,10 @@ namespace ts.SignatureHelp {
|
|||
writer.writeSpace(" ");
|
||||
const predicate = typeChecker.getTypePredicateOfSignature(candidateSignature);
|
||||
if (predicate) {
|
||||
typeChecker.writeTypePredicate(predicate, invocation, /*flags*/ undefined, writer);
|
||||
typeChecker.writeTypePredicate(predicate, enclosingDeclaration, /*flags*/ undefined, writer);
|
||||
}
|
||||
else {
|
||||
typeChecker.writeType(typeChecker.getReturnTypeOfSignature(candidateSignature), invocation, /*flags*/ undefined, writer);
|
||||
typeChecker.writeType(typeChecker.getReturnTypeOfSignature(candidateSignature), enclosingDeclaration, /*flags*/ undefined, writer);
|
||||
}
|
||||
});
|
||||
addRange(suffixDisplayParts, returnTypeParts);
|
||||
|
@ -415,18 +438,18 @@ namespace ts.SignatureHelp {
|
|||
});
|
||||
|
||||
if (argumentIndex !== 0) {
|
||||
Debug.assertLessThan(argumentIndex!, argumentCount); // TODO: GH#18217
|
||||
Debug.assertLessThan(argumentIndex, argumentCount);
|
||||
}
|
||||
|
||||
const selectedItemIndex = candidates.indexOf(resolvedSignature);
|
||||
Debug.assert(selectedItemIndex !== -1); // If candidates is non-empty it should always include bestSignature. We check for an empty candidates before calling this function.
|
||||
|
||||
return { items, applicableSpan, selectedItemIndex, argumentIndex: argumentIndex!, argumentCount }; // TODO: GH#18217
|
||||
return { items, applicableSpan, selectedItemIndex, argumentIndex, argumentCount };
|
||||
|
||||
function createSignatureHelpParameterForParameter(parameter: Symbol): SignatureHelpParameter {
|
||||
const displayParts = mapToDisplayParts(writer => {
|
||||
const param = typeChecker.symbolToParameterDeclaration(parameter, invocation, signatureHelpNodeBuilderFlags)!;
|
||||
printer.writeNode(EmitHint.Unspecified, param, getSourceFileOfNode(getParseTreeNode(invocation)), writer);
|
||||
const param = typeChecker.symbolToParameterDeclaration(parameter, enclosingDeclaration, signatureHelpNodeBuilderFlags)!;
|
||||
printer.writeNode(EmitHint.Unspecified, param, sourceFile, writer);
|
||||
});
|
||||
|
||||
return {
|
||||
|
@ -439,8 +462,8 @@ namespace ts.SignatureHelp {
|
|||
|
||||
function createSignatureHelpParameterForTypeParameter(typeParameter: TypeParameter): SignatureHelpParameter {
|
||||
const displayParts = mapToDisplayParts(writer => {
|
||||
const param = typeChecker.typeParameterToDeclaration(typeParameter, invocation)!;
|
||||
printer.writeNode(EmitHint.Unspecified, param, getSourceFileOfNode(getParseTreeNode(invocation)), writer);
|
||||
const param = typeChecker.typeParameterToDeclaration(typeParameter, enclosingDeclaration)!;
|
||||
printer.writeNode(EmitHint.Unspecified, param, sourceFile, writer);
|
||||
});
|
||||
|
||||
return {
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
"documentRegistry.ts",
|
||||
"importTracker.ts",
|
||||
"findAllReferences.ts",
|
||||
"getEditsForFileRename.ts",
|
||||
"goToDefinition.ts",
|
||||
"jsDoc.ts",
|
||||
"semver.ts",
|
||||
|
@ -111,6 +112,7 @@
|
|||
"codefixes/requireInTs.ts",
|
||||
"codefixes/useDefaultImport.ts",
|
||||
"codefixes/fixAddModuleReferTypeMissingTypeof.ts",
|
||||
"codefixes/convertToMappedObjectType.ts",
|
||||
"refactors/extractSymbol.ts",
|
||||
"refactors/generateGetAccessorAndSetAccessor.ts",
|
||||
"refactors/moveToNewFile.ts",
|
||||
|
|
|
@ -920,7 +920,11 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
export function isPossiblyTypeArgumentPosition(tokenIn: Node, sourceFile: SourceFile): boolean {
|
||||
export interface PossibleTypeArgumentInfo {
|
||||
readonly called: Identifier;
|
||||
readonly nTypeArguments: number;
|
||||
}
|
||||
export function isPossiblyTypeArgumentPosition(tokenIn: Node, sourceFile: SourceFile): PossibleTypeArgumentInfo | undefined {
|
||||
let token: Node | undefined = tokenIn;
|
||||
// This function determines if the node could be type argument position
|
||||
// Since during editing, when type argument list is not complete,
|
||||
|
@ -928,15 +932,15 @@ namespace ts {
|
|||
// scanning of the previous identifier followed by "<" before current node would give us better result
|
||||
// Note that we also balance out the already provided type arguments, arrays, object literals while doing so
|
||||
let remainingLessThanTokens = 0;
|
||||
let nTypeArguments = 0;
|
||||
while (token) {
|
||||
switch (token.kind) {
|
||||
case SyntaxKind.LessThanToken:
|
||||
// Found the beginning of the generic argument expression
|
||||
token = findPrecedingToken(token.getFullStart(), sourceFile);
|
||||
if (!token) return false;
|
||||
const tokenIsIdentifier = isIdentifier(token);
|
||||
if (!remainingLessThanTokens || !tokenIsIdentifier) {
|
||||
return tokenIsIdentifier;
|
||||
if (!token || !isIdentifier(token)) return undefined;
|
||||
if (!remainingLessThanTokens) {
|
||||
return { called: token, nTypeArguments };
|
||||
}
|
||||
remainingLessThanTokens--;
|
||||
break;
|
||||
|
@ -957,25 +961,28 @@ namespace ts {
|
|||
// This can be object type, skip until we find the matching open brace token
|
||||
// Skip until the matching open brace token
|
||||
token = findPrecedingMatchingToken(token, SyntaxKind.OpenBraceToken, sourceFile);
|
||||
if (!token) return false;
|
||||
if (!token) return undefined;
|
||||
break;
|
||||
|
||||
case SyntaxKind.CloseParenToken:
|
||||
// This can be object type, skip until we find the matching open brace token
|
||||
// Skip until the matching open brace token
|
||||
token = findPrecedingMatchingToken(token, SyntaxKind.OpenParenToken, sourceFile);
|
||||
if (!token) return false;
|
||||
if (!token) return undefined;
|
||||
break;
|
||||
|
||||
case SyntaxKind.CloseBracketToken:
|
||||
// This can be object type, skip until we find the matching open brace token
|
||||
// Skip until the matching open brace token
|
||||
token = findPrecedingMatchingToken(token, SyntaxKind.OpenBracketToken, sourceFile);
|
||||
if (!token) return false;
|
||||
if (!token) return undefined;
|
||||
break;
|
||||
|
||||
// Valid tokens in a type name. Skip.
|
||||
case SyntaxKind.CommaToken:
|
||||
nTypeArguments++;
|
||||
break;
|
||||
|
||||
case SyntaxKind.EqualsGreaterThanToken:
|
||||
|
||||
case SyntaxKind.Identifier:
|
||||
|
@ -999,13 +1006,13 @@ namespace ts {
|
|||
}
|
||||
|
||||
// Invalid token in type
|
||||
return false;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
token = findPrecedingToken(token.getFullStart(), sourceFile);
|
||||
}
|
||||
|
||||
return false;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1086,7 +1093,7 @@ namespace ts {
|
|||
return SyntaxKind.FirstPunctuation <= kind && kind <= SyntaxKind.LastPunctuation;
|
||||
}
|
||||
|
||||
export function isInsideTemplateLiteral(node: LiteralExpression, position: number) {
|
||||
export function isInsideTemplateLiteral(node: LiteralExpression | TemplateHead, position: number) {
|
||||
return isTemplateLiteralKind(node.kind)
|
||||
&& (node.getStart() < position && position < node.getEnd()) || (!!node.isUnterminated && position === node.getEnd());
|
||||
}
|
||||
|
|
64
tests/baselines/reference/enumConstantMembers.errors.txt
Normal file
64
tests/baselines/reference/enumConstantMembers.errors.txt
Normal file
|
@ -0,0 +1,64 @@
|
|||
tests/cases/conformance/enums/enumConstantMembers.ts(32,9): error TS2477: 'const' enum member initializer was evaluated to a non-finite value.
|
||||
tests/cases/conformance/enums/enumConstantMembers.ts(33,9): error TS2477: 'const' enum member initializer was evaluated to a non-finite value.
|
||||
tests/cases/conformance/enums/enumConstantMembers.ts(34,9): error TS2477: 'const' enum member initializer was evaluated to a non-finite value.
|
||||
tests/cases/conformance/enums/enumConstantMembers.ts(35,9): error TS2478: 'const' enum member initializer was evaluated to disallowed value 'NaN'.
|
||||
tests/cases/conformance/enums/enumConstantMembers.ts(36,9): error TS2478: 'const' enum member initializer was evaluated to disallowed value 'NaN'.
|
||||
tests/cases/conformance/enums/enumConstantMembers.ts(37,9): error TS2477: 'const' enum member initializer was evaluated to a non-finite value.
|
||||
tests/cases/conformance/enums/enumConstantMembers.ts(38,9): error TS2477: 'const' enum member initializer was evaluated to a non-finite value.
|
||||
|
||||
|
||||
==== tests/cases/conformance/enums/enumConstantMembers.ts (7 errors) ====
|
||||
// Constant members allow negatives, but not decimals. Also hex literals are allowed
|
||||
enum E1 {
|
||||
a = 1,
|
||||
b
|
||||
}
|
||||
enum E2 {
|
||||
a = - 1,
|
||||
b
|
||||
}
|
||||
enum E3 {
|
||||
a = 0.1,
|
||||
b // Error because 0.1 is not a constant
|
||||
}
|
||||
|
||||
declare enum E4 {
|
||||
a = 1,
|
||||
b = -1,
|
||||
c = 0.1 // Not a constant
|
||||
}
|
||||
|
||||
enum E5 {
|
||||
a = 1 / 0,
|
||||
b = 2 / 0.0,
|
||||
c = 1.0 / 0.0,
|
||||
d = 0.0 / 0.0,
|
||||
e = NaN,
|
||||
f = Infinity,
|
||||
g = -Infinity
|
||||
}
|
||||
|
||||
const enum E6 {
|
||||
a = 1 / 0,
|
||||
~~~~~
|
||||
!!! error TS2477: 'const' enum member initializer was evaluated to a non-finite value.
|
||||
b = 2 / 0.0,
|
||||
~~~~~~~
|
||||
!!! error TS2477: 'const' enum member initializer was evaluated to a non-finite value.
|
||||
c = 1.0 / 0.0,
|
||||
~~~~~~~~~
|
||||
!!! error TS2477: 'const' enum member initializer was evaluated to a non-finite value.
|
||||
d = 0.0 / 0.0,
|
||||
~~~~~~~~~
|
||||
!!! error TS2478: 'const' enum member initializer was evaluated to disallowed value 'NaN'.
|
||||
e = NaN,
|
||||
~~~
|
||||
!!! error TS2478: 'const' enum member initializer was evaluated to disallowed value 'NaN'.
|
||||
f = Infinity,
|
||||
~~~~~~~~
|
||||
!!! error TS2477: 'const' enum member initializer was evaluated to a non-finite value.
|
||||
g = -Infinity
|
||||
~~~~~~~~~
|
||||
!!! error TS2477: 'const' enum member initializer was evaluated to a non-finite value.
|
||||
}
|
||||
|
|
@ -19,6 +19,27 @@ declare enum E4 {
|
|||
c = 0.1 // Not a constant
|
||||
}
|
||||
|
||||
enum E5 {
|
||||
a = 1 / 0,
|
||||
b = 2 / 0.0,
|
||||
c = 1.0 / 0.0,
|
||||
d = 0.0 / 0.0,
|
||||
e = NaN,
|
||||
f = Infinity,
|
||||
g = -Infinity
|
||||
}
|
||||
|
||||
const enum E6 {
|
||||
a = 1 / 0,
|
||||
b = 2 / 0.0,
|
||||
c = 1.0 / 0.0,
|
||||
d = 0.0 / 0.0,
|
||||
e = NaN,
|
||||
f = Infinity,
|
||||
g = -Infinity
|
||||
}
|
||||
|
||||
|
||||
//// [enumConstantMembers.js]
|
||||
// Constant members allow negatives, but not decimals. Also hex literals are allowed
|
||||
var E1;
|
||||
|
@ -36,3 +57,13 @@ var E3;
|
|||
E3[E3["a"] = 0.1] = "a";
|
||||
E3[E3["b"] = 1.1] = "b"; // Error because 0.1 is not a constant
|
||||
})(E3 || (E3 = {}));
|
||||
var E5;
|
||||
(function (E5) {
|
||||
E5[E5["a"] = Infinity] = "a";
|
||||
E5[E5["b"] = Infinity] = "b";
|
||||
E5[E5["c"] = Infinity] = "c";
|
||||
E5[E5["d"] = NaN] = "d";
|
||||
E5[E5["e"] = NaN] = "e";
|
||||
E5[E5["f"] = Infinity] = "f";
|
||||
E5[E5["g"] = -Infinity] = "g";
|
||||
})(E5 || (E5 = {}));
|
||||
|
|
|
@ -40,3 +40,60 @@ declare enum E4 {
|
|||
c = 0.1 // Not a constant
|
||||
>c : Symbol(E4.c, Decl(enumConstantMembers.ts, 16, 11))
|
||||
}
|
||||
|
||||
enum E5 {
|
||||
>E5 : Symbol(E5, Decl(enumConstantMembers.ts, 18, 1))
|
||||
|
||||
a = 1 / 0,
|
||||
>a : Symbol(E5.a, Decl(enumConstantMembers.ts, 20, 9))
|
||||
|
||||
b = 2 / 0.0,
|
||||
>b : Symbol(E5.b, Decl(enumConstantMembers.ts, 21, 14))
|
||||
|
||||
c = 1.0 / 0.0,
|
||||
>c : Symbol(E5.c, Decl(enumConstantMembers.ts, 22, 16))
|
||||
|
||||
d = 0.0 / 0.0,
|
||||
>d : Symbol(E5.d, Decl(enumConstantMembers.ts, 23, 18))
|
||||
|
||||
e = NaN,
|
||||
>e : Symbol(E5.e, Decl(enumConstantMembers.ts, 24, 18))
|
||||
>NaN : Symbol(NaN, Decl(lib.d.ts, --, --))
|
||||
|
||||
f = Infinity,
|
||||
>f : Symbol(E5.f, Decl(enumConstantMembers.ts, 25, 12))
|
||||
>Infinity : Symbol(Infinity, Decl(lib.d.ts, --, --))
|
||||
|
||||
g = -Infinity
|
||||
>g : Symbol(E5.g, Decl(enumConstantMembers.ts, 26, 17))
|
||||
>Infinity : Symbol(Infinity, Decl(lib.d.ts, --, --))
|
||||
}
|
||||
|
||||
const enum E6 {
|
||||
>E6 : Symbol(E6, Decl(enumConstantMembers.ts, 28, 1))
|
||||
|
||||
a = 1 / 0,
|
||||
>a : Symbol(E6.a, Decl(enumConstantMembers.ts, 30, 15))
|
||||
|
||||
b = 2 / 0.0,
|
||||
>b : Symbol(E6.b, Decl(enumConstantMembers.ts, 31, 14))
|
||||
|
||||
c = 1.0 / 0.0,
|
||||
>c : Symbol(E6.c, Decl(enumConstantMembers.ts, 32, 16))
|
||||
|
||||
d = 0.0 / 0.0,
|
||||
>d : Symbol(E6.d, Decl(enumConstantMembers.ts, 33, 18))
|
||||
|
||||
e = NaN,
|
||||
>e : Symbol(E6.e, Decl(enumConstantMembers.ts, 34, 18))
|
||||
>NaN : Symbol(NaN, Decl(lib.d.ts, --, --))
|
||||
|
||||
f = Infinity,
|
||||
>f : Symbol(E6.f, Decl(enumConstantMembers.ts, 35, 12))
|
||||
>Infinity : Symbol(Infinity, Decl(lib.d.ts, --, --))
|
||||
|
||||
g = -Infinity
|
||||
>g : Symbol(E6.g, Decl(enumConstantMembers.ts, 36, 17))
|
||||
>Infinity : Symbol(Infinity, Decl(lib.d.ts, --, --))
|
||||
}
|
||||
|
||||
|
|
|
@ -48,3 +48,86 @@ declare enum E4 {
|
|||
>c : E4.c
|
||||
>0.1 : 0.1
|
||||
}
|
||||
|
||||
enum E5 {
|
||||
>E5 : E5
|
||||
|
||||
a = 1 / 0,
|
||||
>a : E5
|
||||
>1 / 0 : number
|
||||
>1 : 1
|
||||
>0 : 0
|
||||
|
||||
b = 2 / 0.0,
|
||||
>b : E5
|
||||
>2 / 0.0 : number
|
||||
>2 : 2
|
||||
>0.0 : 0
|
||||
|
||||
c = 1.0 / 0.0,
|
||||
>c : E5
|
||||
>1.0 / 0.0 : number
|
||||
>1.0 : 1
|
||||
>0.0 : 0
|
||||
|
||||
d = 0.0 / 0.0,
|
||||
>d : E5
|
||||
>0.0 / 0.0 : number
|
||||
>0.0 : 0
|
||||
>0.0 : 0
|
||||
|
||||
e = NaN,
|
||||
>e : E5
|
||||
>NaN : number
|
||||
|
||||
f = Infinity,
|
||||
>f : E5
|
||||
>Infinity : number
|
||||
|
||||
g = -Infinity
|
||||
>g : E5
|
||||
>-Infinity : number
|
||||
>Infinity : number
|
||||
}
|
||||
|
||||
const enum E6 {
|
||||
>E6 : E6
|
||||
|
||||
a = 1 / 0,
|
||||
>a : E6
|
||||
>1 / 0 : number
|
||||
>1 : 1
|
||||
>0 : 0
|
||||
|
||||
b = 2 / 0.0,
|
||||
>b : E6
|
||||
>2 / 0.0 : number
|
||||
>2 : 2
|
||||
>0.0 : 0
|
||||
|
||||
c = 1.0 / 0.0,
|
||||
>c : E6
|
||||
>1.0 / 0.0 : number
|
||||
>1.0 : 1
|
||||
>0.0 : 0
|
||||
|
||||
d = 0.0 / 0.0,
|
||||
>d : E6
|
||||
>0.0 / 0.0 : number
|
||||
>0.0 : 0
|
||||
>0.0 : 0
|
||||
|
||||
e = NaN,
|
||||
>e : E6
|
||||
>NaN : number
|
||||
|
||||
f = Infinity,
|
||||
>f : E6
|
||||
>Infinity : number
|
||||
|
||||
g = -Infinity
|
||||
>g : E6
|
||||
>-Infinity : number
|
||||
>Infinity : number
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
tests/cases/compiler/parseCommaSeperatedNewlineNew.ts(1,2): error TS2304: Cannot find name 'a'.
|
||||
tests/cases/compiler/parseCommaSeperatedNewlineNew.ts(1,2): error TS2695: Left side of comma operator is unused and has no side effects.
|
||||
tests/cases/compiler/parseCommaSeperatedNewlineNew.ts(2,4): error TS1109: Expression expected.
|
||||
tests/cases/compiler/parseCommaSeparatedNewlineNew.ts(1,2): error TS2304: Cannot find name 'a'.
|
||||
tests/cases/compiler/parseCommaSeparatedNewlineNew.ts(1,2): error TS2695: Left side of comma operator is unused and has no side effects.
|
||||
tests/cases/compiler/parseCommaSeparatedNewlineNew.ts(2,4): error TS1109: Expression expected.
|
||||
|
||||
|
||||
==== tests/cases/compiler/parseCommaSeperatedNewlineNew.ts (3 errors) ====
|
||||
==== tests/cases/compiler/parseCommaSeparatedNewlineNew.ts (3 errors) ====
|
||||
(a,
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'a'.
|
|
@ -0,0 +1,7 @@
|
|||
//// [parseCommaSeparatedNewlineNew.ts]
|
||||
(a,
|
||||
new)
|
||||
|
||||
//// [parseCommaSeparatedNewlineNew.js]
|
||||
(a,
|
||||
new );
|
|
@ -1,4 +1,4 @@
|
|||
=== tests/cases/compiler/parseCommaSeperatedNewlineNew.ts ===
|
||||
=== tests/cases/compiler/parseCommaSeparatedNewlineNew.ts ===
|
||||
(a,
|
||||
No type information for this code.new)
|
||||
No type information for this code.
|
|
@ -0,0 +1,10 @@
|
|||
=== tests/cases/compiler/parseCommaSeparatedNewlineNew.ts ===
|
||||
(a,
|
||||
>(a,new) : any
|
||||
>a,new : any
|
||||
>a : any
|
||||
|
||||
new)
|
||||
>new : any
|
||||
> : any
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
tests/cases/compiler/parseCommaSeperatedNewlineNumber.ts(1,2): error TS2304: Cannot find name 'a'.
|
||||
tests/cases/compiler/parseCommaSeperatedNewlineNumber.ts(1,2): error TS2695: Left side of comma operator is unused and has no side effects.
|
||||
tests/cases/compiler/parseCommaSeparatedNewlineNumber.ts(1,2): error TS2304: Cannot find name 'a'.
|
||||
tests/cases/compiler/parseCommaSeparatedNewlineNumber.ts(1,2): error TS2695: Left side of comma operator is unused and has no side effects.
|
||||
|
||||
|
||||
==== tests/cases/compiler/parseCommaSeperatedNewlineNumber.ts (2 errors) ====
|
||||
==== tests/cases/compiler/parseCommaSeparatedNewlineNumber.ts (2 errors) ====
|
||||
(a,
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'a'.
|
|
@ -0,0 +1,7 @@
|
|||
//// [parseCommaSeparatedNewlineNumber.ts]
|
||||
(a,
|
||||
1)
|
||||
|
||||
//// [parseCommaSeparatedNewlineNumber.js]
|
||||
(a,
|
||||
1);
|
|
@ -1,4 +1,4 @@
|
|||
=== tests/cases/compiler/parseCommaSeperatedNewlineNumber.ts ===
|
||||
=== tests/cases/compiler/parseCommaSeparatedNewlineNumber.ts ===
|
||||
(a,
|
||||
No type information for this code.1)
|
||||
No type information for this code.
|
|
@ -0,0 +1,9 @@
|
|||
=== tests/cases/compiler/parseCommaSeparatedNewlineNumber.ts ===
|
||||
(a,
|
||||
>(a,1) : 1
|
||||
>a,1 : 1
|
||||
>a : any
|
||||
|
||||
1)
|
||||
>1 : 1
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
tests/cases/compiler/parseCommaSeperatedNewlineString.ts(1,2): error TS2304: Cannot find name 'a'.
|
||||
tests/cases/compiler/parseCommaSeperatedNewlineString.ts(1,2): error TS2695: Left side of comma operator is unused and has no side effects.
|
||||
tests/cases/compiler/parseCommaSeparatedNewlineString.ts(1,2): error TS2304: Cannot find name 'a'.
|
||||
tests/cases/compiler/parseCommaSeparatedNewlineString.ts(1,2): error TS2695: Left side of comma operator is unused and has no side effects.
|
||||
|
||||
|
||||
==== tests/cases/compiler/parseCommaSeperatedNewlineString.ts (2 errors) ====
|
||||
==== tests/cases/compiler/parseCommaSeparatedNewlineString.ts (2 errors) ====
|
||||
(a,
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'a'.
|
|
@ -0,0 +1,7 @@
|
|||
//// [parseCommaSeparatedNewlineString.ts]
|
||||
(a,
|
||||
'')
|
||||
|
||||
//// [parseCommaSeparatedNewlineString.js]
|
||||
(a,
|
||||
'');
|
|
@ -1,4 +1,4 @@
|
|||
=== tests/cases/compiler/parseCommaSeperatedNewlineString.ts ===
|
||||
=== tests/cases/compiler/parseCommaSeparatedNewlineString.ts ===
|
||||
(a,
|
||||
No type information for this code.'')
|
||||
No type information for this code.
|
|
@ -0,0 +1,9 @@
|
|||
=== tests/cases/compiler/parseCommaSeparatedNewlineString.ts ===
|
||||
(a,
|
||||
>(a,'') : ""
|
||||
>a,'' : ""
|
||||
>a : any
|
||||
|
||||
'')
|
||||
>'' : ""
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
//// [parseCommaSeperatedNewlineNew.ts]
|
||||
(a,
|
||||
new)
|
||||
|
||||
//// [parseCommaSeperatedNewlineNew.js]
|
||||
(a,
|
||||
new );
|
|
@ -1,10 +0,0 @@
|
|||
=== tests/cases/compiler/parseCommaSeperatedNewlineNew.ts ===
|
||||
(a,
|
||||
>(a,new) : any
|
||||
>a,new : any
|
||||
>a : any
|
||||
|
||||
new)
|
||||
>new : any
|
||||
> : any
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
//// [parseCommaSeperatedNewlineNumber.ts]
|
||||
(a,
|
||||
1)
|
||||
|
||||
//// [parseCommaSeperatedNewlineNumber.js]
|
||||
(a,
|
||||
1);
|
|
@ -1,9 +0,0 @@
|
|||
=== tests/cases/compiler/parseCommaSeperatedNewlineNumber.ts ===
|
||||
(a,
|
||||
>(a,1) : 1
|
||||
>a,1 : 1
|
||||
>a : any
|
||||
|
||||
1)
|
||||
>1 : 1
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
//// [parseCommaSeperatedNewlineString.ts]
|
||||
(a,
|
||||
'')
|
||||
|
||||
//// [parseCommaSeperatedNewlineString.js]
|
||||
(a,
|
||||
'');
|
|
@ -1,9 +0,0 @@
|
|||
=== tests/cases/compiler/parseCommaSeperatedNewlineString.ts ===
|
||||
(a,
|
||||
>(a,'') : ""
|
||||
>a,'' : ""
|
||||
>a : any
|
||||
|
||||
'')
|
||||
>'' : ""
|
||||
|
|
@ -17,3 +17,23 @@ declare enum E4 {
|
|||
b = -1,
|
||||
c = 0.1 // Not a constant
|
||||
}
|
||||
|
||||
enum E5 {
|
||||
a = 1 / 0,
|
||||
b = 2 / 0.0,
|
||||
c = 1.0 / 0.0,
|
||||
d = 0.0 / 0.0,
|
||||
e = NaN,
|
||||
f = Infinity,
|
||||
g = -Infinity
|
||||
}
|
||||
|
||||
const enum E6 {
|
||||
a = 1 / 0,
|
||||
b = 2 / 0.0,
|
||||
c = 1.0 / 0.0,
|
||||
d = 0.0 / 0.0,
|
||||
e = NaN,
|
||||
f = Infinity,
|
||||
g = -Infinity
|
||||
}
|
||||
|
|
17
tests/cases/fourslash/codeFixConvertToMappedObjectType1.ts
Normal file
17
tests/cases/fourslash/codeFixConvertToMappedObjectType1.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// type K = "foo" | "bar";
|
||||
//// interface SomeType {
|
||||
//// a: string;
|
||||
//// [prop: K]: any;
|
||||
//// }
|
||||
|
||||
verify.codeFix({
|
||||
description: `Convert 'SomeType' to mapped object type`,
|
||||
newFileContent: `type K = "foo" | "bar";
|
||||
type SomeType = {
|
||||
[prop in K]: any;
|
||||
} & {
|
||||
a: string;
|
||||
};`
|
||||
})
|
23
tests/cases/fourslash/codeFixConvertToMappedObjectType10.ts
Normal file
23
tests/cases/fourslash/codeFixConvertToMappedObjectType10.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// type K = "foo" | "bar";
|
||||
//// interface Foo { }
|
||||
//// interface Bar<T> { bar: T; }
|
||||
//// interface SomeType<T> extends Foo, Bar<T> {
|
||||
//// a: number;
|
||||
//// b: T;
|
||||
//// [prop: K]: any;
|
||||
//// }
|
||||
|
||||
verify.codeFix({
|
||||
description: `Convert 'SomeType' to mapped object type`,
|
||||
newFileContent: `type K = "foo" | "bar";
|
||||
interface Foo { }
|
||||
interface Bar<T> { bar: T; }
|
||||
type SomeType<T> = Foo & Bar<T> & {
|
||||
[prop in K]: any;
|
||||
} & {
|
||||
a: number;
|
||||
b: T;
|
||||
};`
|
||||
})
|
23
tests/cases/fourslash/codeFixConvertToMappedObjectType11.ts
Normal file
23
tests/cases/fourslash/codeFixConvertToMappedObjectType11.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// type K = "foo" | "bar";
|
||||
//// interface Foo { }
|
||||
//// interface Bar<T> { bar: T; }
|
||||
//// interface SomeType<T> extends Foo, Bar<T> {
|
||||
//// a: number;
|
||||
//// b: T;
|
||||
//// readonly [prop: K]: any;
|
||||
//// }
|
||||
|
||||
verify.codeFix({
|
||||
description: `Convert 'SomeType' to mapped object type`,
|
||||
newFileContent: `type K = "foo" | "bar";
|
||||
interface Foo { }
|
||||
interface Bar<T> { bar: T; }
|
||||
type SomeType<T> = Foo & Bar<T> & {
|
||||
readonly [prop in K]: any;
|
||||
} & {
|
||||
a: number;
|
||||
b: T;
|
||||
};`
|
||||
})
|
12
tests/cases/fourslash/codeFixConvertToMappedObjectType12.ts
Normal file
12
tests/cases/fourslash/codeFixConvertToMappedObjectType12.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// type K = "foo" | "bar";
|
||||
//// interface Foo { }
|
||||
//// interface Bar<T> { bar: T; }
|
||||
//// interface SomeType<T> extends Foo, Bar<T> {
|
||||
//// a: number;
|
||||
//// b: T;
|
||||
//// readonly [prop: K]?: any;
|
||||
//// }
|
||||
|
||||
verify.not.codeFixAvailable()
|
17
tests/cases/fourslash/codeFixConvertToMappedObjectType2.ts
Normal file
17
tests/cases/fourslash/codeFixConvertToMappedObjectType2.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// type K = "foo" | "bar";
|
||||
//// type SomeType = {
|
||||
//// a: string;
|
||||
//// [prop: K]: any;
|
||||
//// }
|
||||
|
||||
verify.codeFix({
|
||||
description: `Convert 'SomeType' to mapped object type`,
|
||||
newFileContent: `type K = "foo" | "bar";
|
||||
type SomeType = {
|
||||
[prop in K]: any;
|
||||
} & {
|
||||
a: string;
|
||||
};`
|
||||
})
|
14
tests/cases/fourslash/codeFixConvertToMappedObjectType3.ts
Normal file
14
tests/cases/fourslash/codeFixConvertToMappedObjectType3.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// type K = "foo" | "bar";
|
||||
//// type SomeType = {
|
||||
//// [prop: K]: any;
|
||||
//// }
|
||||
|
||||
verify.codeFix({
|
||||
description: `Convert 'SomeType' to mapped object type`,
|
||||
newFileContent: `type K = "foo" | "bar";
|
||||
type SomeType = {
|
||||
[prop in K]: any;
|
||||
};`
|
||||
})
|
14
tests/cases/fourslash/codeFixConvertToMappedObjectType4.ts
Normal file
14
tests/cases/fourslash/codeFixConvertToMappedObjectType4.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// type K = "foo" | "bar";
|
||||
//// interface SomeType {
|
||||
//// [prop: K]: any;
|
||||
//// }
|
||||
|
||||
verify.codeFix({
|
||||
description: `Convert 'SomeType' to mapped object type`,
|
||||
newFileContent: `type K = "foo" | "bar";
|
||||
type SomeType = {
|
||||
[prop in K]: any;
|
||||
};`
|
||||
})
|
|
@ -0,0 +1,8 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// type K = "foo" | "bar";
|
||||
//// class SomeType {
|
||||
//// [prop: K]: any;
|
||||
//// }
|
||||
|
||||
verify.not.codeFixAvailable()
|
16
tests/cases/fourslash/codeFixConvertToMappedObjectType6.ts
Normal file
16
tests/cases/fourslash/codeFixConvertToMappedObjectType6.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// type K = "foo" | "bar";
|
||||
//// interface Foo { }
|
||||
//// interface SomeType extends Foo {
|
||||
//// [prop: K]: any;
|
||||
//// }
|
||||
|
||||
verify.codeFix({
|
||||
description: `Convert 'SomeType' to mapped object type`,
|
||||
newFileContent: `type K = "foo" | "bar";
|
||||
interface Foo { }
|
||||
type SomeType = Foo & {
|
||||
[prop in K]: any;
|
||||
};`
|
||||
})
|
18
tests/cases/fourslash/codeFixConvertToMappedObjectType7.ts
Normal file
18
tests/cases/fourslash/codeFixConvertToMappedObjectType7.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// type K = "foo" | "bar";
|
||||
//// interface Foo { }
|
||||
//// interface Bar { }
|
||||
//// interface SomeType extends Foo, Bar {
|
||||
//// [prop: K]: any;
|
||||
//// }
|
||||
|
||||
verify.codeFix({
|
||||
description: `Convert 'SomeType' to mapped object type`,
|
||||
newFileContent: `type K = "foo" | "bar";
|
||||
interface Foo { }
|
||||
interface Bar { }
|
||||
type SomeType = Foo & Bar & {
|
||||
[prop in K]: any;
|
||||
};`
|
||||
})
|
21
tests/cases/fourslash/codeFixConvertToMappedObjectType8.ts
Normal file
21
tests/cases/fourslash/codeFixConvertToMappedObjectType8.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// type K = "foo" | "bar";
|
||||
//// interface Foo { }
|
||||
//// interface Bar { }
|
||||
//// interface SomeType extends Foo, Bar {
|
||||
//// a: number;
|
||||
//// [prop: K]: any;
|
||||
//// }
|
||||
|
||||
verify.codeFix({
|
||||
description: `Convert 'SomeType' to mapped object type`,
|
||||
newFileContent: `type K = "foo" | "bar";
|
||||
interface Foo { }
|
||||
interface Bar { }
|
||||
type SomeType = Foo & Bar & {
|
||||
[prop in K]: any;
|
||||
} & {
|
||||
a: number;
|
||||
};`
|
||||
})
|
21
tests/cases/fourslash/codeFixConvertToMappedObjectType9.ts
Normal file
21
tests/cases/fourslash/codeFixConvertToMappedObjectType9.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// type K = "foo" | "bar";
|
||||
//// interface Foo { }
|
||||
//// interface Bar<T> { bar: T; }
|
||||
//// interface SomeType extends Foo, Bar<number> {
|
||||
//// a: number;
|
||||
//// [prop: K]: any;
|
||||
//// }
|
||||
|
||||
verify.codeFix({
|
||||
description: `Convert 'SomeType' to mapped object type`,
|
||||
newFileContent: `type K = "foo" | "bar";
|
||||
interface Foo { }
|
||||
interface Bar<T> { bar: T; }
|
||||
type SomeType = Foo & Bar<number> & {
|
||||
[prop in K]: any;
|
||||
} & {
|
||||
a: number;
|
||||
};`
|
||||
})
|
14
tests/cases/fourslash/findAllReferencesOfJsonModule.ts
Normal file
14
tests/cases/fourslash/findAllReferencesOfJsonModule.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @resolveJsonModule: true
|
||||
// @module: commonjs
|
||||
// @esModuleInterop: true
|
||||
|
||||
// @Filename: /foo.ts
|
||||
////import [|{| "isWriteAccess": true, "isDefinition": true |}settings|] from "./settings.json";
|
||||
////[|settings|];
|
||||
|
||||
// @Filename: /settings.json
|
||||
//// {}
|
||||
|
||||
verify.singleReferenceGroup("import settings");
|
|
@ -1,5 +1,7 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// See also `getEditsForFileRename_oldFileStillPresent.ts`
|
||||
|
||||
// @Filename: /a.ts
|
||||
/////// <reference path="./src/old.ts" />
|
||||
////import old from "./src/old";
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// Same test as `getEditsForFileRename.ts`, but with the old file not yet renamed.
|
||||
|
||||
// @Filename: /src/old.ts
|
||||
////stuff
|
||||
|
||||
// @Filename: /a.ts
|
||||
/////// <reference path="./src/old.ts" />
|
||||
////import old from "./src/old";
|
||||
|
||||
// @Filename: /src/a.ts
|
||||
/////// <reference path="./old.ts" />
|
||||
////import old from "./old";
|
||||
|
||||
// @Filename: /src/foo/a.ts
|
||||
/////// <reference path="../old.ts" />
|
||||
////import old from "../old";
|
||||
|
||||
// @Filename: /tsconfig.json
|
||||
////{ "files": ["/a.ts", "/src/a.ts", "/src/foo/a.ts", "/src/old.ts"] }
|
||||
|
||||
verify.getEditsForFileRename({
|
||||
oldPath: "/src/old.ts",
|
||||
newPath: "/src/new.ts",
|
||||
newFileContents: {
|
||||
"/a.ts": '/// <reference path="./src/new.ts" />\nimport old from "./src/new";',
|
||||
"/src/a.ts": '/// <reference path="./new.ts" />\nimport old from "./new";',
|
||||
"/src/foo/a.ts": '/// <reference path="../new.ts" />\nimport old from "../new";',
|
||||
"/tsconfig.json": '{ "files": ["/a.ts", "/src/a.ts", "/src/foo/a.ts", "/src/new.ts"] }',
|
||||
},
|
||||
});
|
62
tests/cases/fourslash/signatureHelpTypeArguments.ts
Normal file
62
tests/cases/fourslash/signatureHelpTypeArguments.ts
Normal file
|
@ -0,0 +1,62 @@
|
|||
/// <reference path="fourslash.ts"/>
|
||||
|
||||
////declare function f(a: number, b: string, c: boolean): void; // ignored, not generic
|
||||
////declare function f<T extends number>(): void;
|
||||
////declare function f<T, U>(): void;
|
||||
////declare function f<T, U, V extends string>(): void;
|
||||
////f</*f0*/;
|
||||
////f<number, /*f1*/;
|
||||
////f<number, string, /*f2*/;
|
||||
////
|
||||
////declare const C: {
|
||||
//// new<T extends number>(): void;
|
||||
//// new<T, U>(): void;
|
||||
//// new<T, U, V extends string>(): void;
|
||||
////};
|
||||
////new C</*C0*/;
|
||||
////new C<number, /*C1*/;
|
||||
////new C<number, string, /*C2*/;
|
||||
|
||||
verify.signatureHelp(
|
||||
{
|
||||
marker: "f0",
|
||||
overloadsCount: 3,
|
||||
text: "f<T extends number>(): void",
|
||||
parameterName: "T",
|
||||
parameterSpan: "T extends number",
|
||||
},
|
||||
{
|
||||
marker: "f1",
|
||||
overloadsCount: 2,
|
||||
text: "f<T, U>(): void",
|
||||
parameterName: "U",
|
||||
parameterSpan: "U",
|
||||
},
|
||||
{
|
||||
marker: "f2",
|
||||
text: "f<T, U, V extends string>(): void",
|
||||
parameterName: "V",
|
||||
parameterSpan: "V extends string",
|
||||
},
|
||||
|
||||
{
|
||||
marker: "C0",
|
||||
overloadsCount: 3,
|
||||
text: "C<T extends number>(): void",
|
||||
parameterName: "T",
|
||||
parameterSpan: "T extends number",
|
||||
},
|
||||
{
|
||||
marker: "C1",
|
||||
overloadsCount: 2,
|
||||
text: "C<T, U>(): void",
|
||||
parameterName: "U",
|
||||
parameterSpan: "U",
|
||||
},
|
||||
{
|
||||
marker: "C2",
|
||||
text: "C<T, U, V extends string>(): void",
|
||||
parameterName: "V",
|
||||
parameterSpan: "V extends string",
|
||||
},
|
||||
);
|
Loading…
Reference in a new issue