mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into watchImprovements
This commit is contained in:
+34
-24
@@ -19,47 +19,57 @@ function main(): void {
|
||||
|
||||
// Acquire the version from the package.json file and modify it appropriately.
|
||||
const packageJsonFilePath = ts.normalizePath(sys.args[0]);
|
||||
const packageJsonContents = sys.readFile(packageJsonFilePath);
|
||||
const packageJsonValue: PackageJson = JSON.parse(packageJsonContents);
|
||||
const packageJsonValue: PackageJson = JSON.parse(sys.readFile(packageJsonFilePath));
|
||||
|
||||
const nightlyVersion = getNightlyVersionString(packageJsonValue.version);
|
||||
|
||||
// Modify the package.json structure
|
||||
packageJsonValue.version = nightlyVersion;
|
||||
const { majorMinor, patch } = parsePackageJsonVersion(packageJsonValue.version);
|
||||
const nightlyPatch = getNightlyPatch(patch);
|
||||
|
||||
// Acquire and modify the source file that exposes the version string.
|
||||
const tsFilePath = ts.normalizePath(sys.args[1]);
|
||||
const tsFileContents = sys.readFile(tsFilePath);
|
||||
const versionAssignmentRegExp = /export\s+const\s+version\s+=\s+".*";/;
|
||||
const modifiedTsFileContents = tsFileContents.replace(versionAssignmentRegExp, `export const version = "${nightlyVersion}";`);
|
||||
const tsFileContents = ts.sys.readFile(tsFilePath);
|
||||
const modifiedTsFileContents = updateTsFile(tsFilePath, tsFileContents, majorMinor, patch, nightlyPatch);
|
||||
|
||||
// Ensure we are actually changing something - the user probably wants to know that the update failed.
|
||||
if (tsFileContents === modifiedTsFileContents) {
|
||||
let err = `\n '${tsFilePath}' was not updated while configuring for a nightly publish.\n `;
|
||||
|
||||
if (tsFileContents.match(versionAssignmentRegExp)) {
|
||||
err += `Ensure that you have not already run this script; otherwise, erase your changes using 'git checkout -- "${tsFilePath}"'.`;
|
||||
}
|
||||
else {
|
||||
err += `The file seems to no longer have a string matching '${versionAssignmentRegExp}'.`;
|
||||
}
|
||||
|
||||
err += `Ensure that you have not already run this script; otherwise, erase your changes using 'git checkout -- "${tsFilePath}"'.`;
|
||||
throw err + "\n";
|
||||
}
|
||||
|
||||
// Finally write the changes to disk.
|
||||
// Modify the package.json structure
|
||||
packageJsonValue.version = `${majorMinor}.${nightlyPatch}`;
|
||||
sys.writeFile(packageJsonFilePath, JSON.stringify(packageJsonValue, /*replacer:*/ undefined, /*space:*/ 4))
|
||||
sys.writeFile(tsFilePath, modifiedTsFileContents);
|
||||
}
|
||||
|
||||
function getNightlyVersionString(versionString: string): string {
|
||||
// If the version string already contains "-nightly",
|
||||
// then get the base string and update based on that.
|
||||
const dashNightlyPos = versionString.indexOf("-dev");
|
||||
if (dashNightlyPos >= 0) {
|
||||
versionString = versionString.slice(0, dashNightlyPos);
|
||||
function updateTsFile(tsFilePath: string, tsFileContents: string, majorMinor: string, patch: string, nightlyPatch: string): string {
|
||||
const majorMinorRgx = /export const versionMajorMinor = "(\d+\.\d+)"/;
|
||||
const majorMinorMatch = majorMinorRgx.exec(tsFileContents);
|
||||
ts.Debug.assert(majorMinorMatch !== null, "", () => `The file seems to no longer have a string matching '${majorMinorRgx}'.`);
|
||||
const parsedMajorMinor = majorMinorMatch[1];
|
||||
ts.Debug.assert(parsedMajorMinor === majorMinor, "versionMajorMinor does not match.", () => `${tsFilePath}: '${parsedMajorMinor}'; package.json: '${majorMinor}'`);
|
||||
|
||||
const versionRgx = /export const version = `\$\{versionMajorMinor\}\.(\d)`;/;
|
||||
const patchMatch = versionRgx.exec(tsFileContents);
|
||||
ts.Debug.assert(patchMatch !== null, "The file seems to no longer have a string matching", () => versionRgx.toString());
|
||||
const parsedPatch = patchMatch[1];
|
||||
if (parsedPatch !== patch) {
|
||||
throw new Error(`patch does not match. ${tsFilePath}: '${parsedPatch}; package.json: '${patch}'`);
|
||||
}
|
||||
|
||||
return tsFileContents.replace(versionRgx, `export const version = \`\${versionMajorMinor}.${nightlyPatch}\`;`);
|
||||
}
|
||||
|
||||
function parsePackageJsonVersion(versionString: string): { majorMinor: string, patch: string } {
|
||||
const versionRgx = /(\d+\.\d+)\.(\d+)($|\-)/;
|
||||
const match = versionString.match(versionRgx);
|
||||
ts.Debug.assert(match !== null, "package.json 'version' should match", () => versionRgx.toString());
|
||||
return { majorMinor: match[1], patch: match[2] };
|
||||
}
|
||||
|
||||
/** e.g. 0-dev.20170707 */
|
||||
function getNightlyPatch(plainPatch: string): string {
|
||||
// We're going to append a representation of the current time at the end of the current version.
|
||||
// String.prototype.toISOString() returns a 24-character string formatted as 'YYYY-MM-DDTHH:mm:ss.sssZ',
|
||||
// but we'd prefer to just remove separators and limit ourselves to YYYYMMDD.
|
||||
@@ -67,7 +77,7 @@ function getNightlyVersionString(versionString: string): string {
|
||||
const now = new Date();
|
||||
const timeStr = now.toISOString().replace(/:|T|\.|-/g, "").slice(0, 8);
|
||||
|
||||
return `${versionString}-dev.${timeStr}`;
|
||||
return `${plainPatch}-dev.${timeStr}`;
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -19,7 +19,7 @@ function walk(ctx: Lint.WalkContext<void>): void {
|
||||
ts.forEachChild(node, recur);
|
||||
}
|
||||
|
||||
function check(types: ts.TypeNode[]): void {
|
||||
function check(types: ReadonlyArray<ts.TypeNode>): void {
|
||||
let expectedStart = types[0].end + 2; // space, | or &
|
||||
for (let i = 1; i < types.length; i++) {
|
||||
const currentType = types[i];
|
||||
|
||||
+17
-13
@@ -308,7 +308,7 @@ namespace ts {
|
||||
* @param includes - The SymbolFlags that node has in addition to its declaration type (eg: export, ambient, etc.)
|
||||
* @param excludes - The flags which node cannot be declared alongside in a symbol table. Used to report forbidden declarations.
|
||||
*/
|
||||
function declareSymbol(symbolTable: SymbolTable, parent: Symbol, node: Declaration, includes: SymbolFlags, excludes: SymbolFlags): Symbol {
|
||||
function declareSymbol(symbolTable: SymbolTable, parent: Symbol, node: Declaration, includes: SymbolFlags, excludes: SymbolFlags, isReplaceableByMethod?: boolean): Symbol {
|
||||
Debug.assert(!hasDynamicName(node));
|
||||
|
||||
const isDefaultExport = hasModifier(node, ModifierFlags.Default);
|
||||
@@ -345,15 +345,20 @@ namespace ts {
|
||||
// you have multiple 'vars' with the same name in the same container). In this case
|
||||
// just add this node into the declarations list of the symbol.
|
||||
symbol = symbolTable.get(name);
|
||||
if (!symbol) {
|
||||
symbolTable.set(name, symbol = createSymbol(SymbolFlags.None, name));
|
||||
}
|
||||
|
||||
if (name && (includes & SymbolFlags.Classifiable)) {
|
||||
if (includes & SymbolFlags.Classifiable) {
|
||||
classifiableNames.set(name, true);
|
||||
}
|
||||
|
||||
if (symbol.flags & excludes) {
|
||||
if (!symbol) {
|
||||
symbolTable.set(name, symbol = createSymbol(SymbolFlags.None, name));
|
||||
if (isReplaceableByMethod) symbol.isReplaceableByMethod = true;
|
||||
}
|
||||
else if (isReplaceableByMethod && !symbol.isReplaceableByMethod) {
|
||||
// A symbol already exists, so don't add this as a declaration.
|
||||
return symbol;
|
||||
}
|
||||
else if (symbol.flags & excludes) {
|
||||
if (symbol.isReplaceableByMethod) {
|
||||
// Javascript constructor-declared symbols can be discarded in favor of
|
||||
// prototype symbols like methods.
|
||||
@@ -1327,7 +1332,7 @@ namespace ts {
|
||||
function bindInitializedVariableFlow(node: VariableDeclaration | ArrayBindingElement) {
|
||||
const name = !isOmittedExpression(node) ? node.name : undefined;
|
||||
if (isBindingPattern(name)) {
|
||||
for (const child of <ArrayBindingElement[]>name.elements) {
|
||||
for (const child of name.elements) {
|
||||
bindInitializedVariableFlow(child);
|
||||
}
|
||||
}
|
||||
@@ -2061,8 +2066,10 @@ namespace ts {
|
||||
case SyntaxKind.Parameter:
|
||||
return bindParameter(<ParameterDeclaration>node);
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
return bindVariableDeclarationOrBindingElement(<VariableDeclaration>node);
|
||||
case SyntaxKind.BindingElement:
|
||||
return bindVariableDeclarationOrBindingElement(<VariableDeclaration | BindingElement>node);
|
||||
node.flowNode = currentFlow;
|
||||
return bindVariableDeclarationOrBindingElement(<BindingElement>node);
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.PropertySignature:
|
||||
return bindPropertyWorker(node as PropertyDeclaration | PropertySignature);
|
||||
@@ -2342,11 +2349,8 @@ namespace ts {
|
||||
// this.foo assignment in a JavaScript class
|
||||
// Bind this property to the containing class
|
||||
const containingClass = container.parent;
|
||||
const symbol = declareSymbol(hasModifier(container, ModifierFlags.Static) ? containingClass.symbol.exports : containingClass.symbol.members, containingClass.symbol, node, SymbolFlags.Property, SymbolFlags.None);
|
||||
if (symbol) {
|
||||
// symbols declared through 'this' property assignements can be overwritten by subsequent method declarations
|
||||
(symbol as Symbol).isReplaceableByMethod = true;
|
||||
}
|
||||
const symbolTable = hasModifier(container, ModifierFlags.Static) ? containingClass.symbol.exports : containingClass.symbol.members;
|
||||
declareSymbol(symbolTable, containingClass.symbol, node, SymbolFlags.Property, SymbolFlags.None, /*isReplaceableByMethod*/ true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+135
-47
@@ -117,6 +117,7 @@ namespace ts {
|
||||
},
|
||||
getParameterType: getTypeAtPosition,
|
||||
getReturnTypeOfSignature,
|
||||
getNullableType,
|
||||
getNonNullableType,
|
||||
typeToTypeNode: nodeBuilder.typeToTypeNode,
|
||||
indexInfoToIndexSignatureDeclaration: nodeBuilder.indexInfoToIndexSignatureDeclaration,
|
||||
@@ -2669,7 +2670,7 @@ namespace ts {
|
||||
entityName = nameIdentifier;
|
||||
}
|
||||
|
||||
let typeArgumentNodes: TypeNode[] | undefined;
|
||||
let typeArgumentNodes: ReadonlyArray<TypeNode> | undefined;
|
||||
if (typeArguments.length > 0) {
|
||||
const typeParameterCount = (type.target.typeParameters || emptyArray).length;
|
||||
typeArgumentNodes = mapToTypeNodes(typeArguments.slice(i, typeParameterCount), context);
|
||||
@@ -2906,7 +2907,7 @@ namespace ts {
|
||||
function createEntityNameFromSymbolChain(chain: Symbol[], index: number): EntityName {
|
||||
Debug.assert(chain && 0 <= index && index < chain.length);
|
||||
const symbol = chain[index];
|
||||
let typeParameterNodes: TypeNode[] | undefined;
|
||||
let typeParameterNodes: ReadonlyArray<TypeNode> | undefined;
|
||||
if (context.flags & NodeBuilderFlags.WriteTypeParametersInQualifiedName && index > 0) {
|
||||
const parentSymbol = chain[index - 1];
|
||||
let typeParameters: TypeParameter[];
|
||||
@@ -3301,7 +3302,7 @@ namespace ts {
|
||||
function writeTypeReference(type: TypeReference, flags: TypeFormatFlags) {
|
||||
const typeArguments = type.typeArguments || emptyArray;
|
||||
if (type.target === globalArrayType && !(flags & TypeFormatFlags.WriteArrayAsGenericType)) {
|
||||
writeType(typeArguments[0], TypeFormatFlags.InElementType);
|
||||
writeType(typeArguments[0], TypeFormatFlags.InElementType | TypeFormatFlags.InArrayType);
|
||||
writePunctuation(writer, SyntaxKind.OpenBracketToken);
|
||||
writePunctuation(writer, SyntaxKind.CloseBracketToken);
|
||||
}
|
||||
@@ -3426,9 +3427,15 @@ namespace ts {
|
||||
}
|
||||
|
||||
function writeTypeOfSymbol(type: ObjectType, typeFormatFlags?: TypeFormatFlags) {
|
||||
if (typeFormatFlags & TypeFormatFlags.InArrayType) {
|
||||
writePunctuation(writer, SyntaxKind.OpenParenToken);
|
||||
}
|
||||
writeKeyword(writer, SyntaxKind.TypeOfKeyword);
|
||||
writeSpace(writer);
|
||||
buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Value, SymbolFormatFlags.None, typeFormatFlags);
|
||||
if (typeFormatFlags & TypeFormatFlags.InArrayType) {
|
||||
writePunctuation(writer, SyntaxKind.CloseParenToken);
|
||||
}
|
||||
}
|
||||
|
||||
function writePropertyWithModifiers(prop: Symbol) {
|
||||
@@ -3666,7 +3673,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function buildDisplayForTypeParametersAndDelimiters(typeParameters: TypeParameter[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) {
|
||||
function buildDisplayForTypeParametersAndDelimiters(typeParameters: ReadonlyArray<TypeParameter>, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) {
|
||||
if (typeParameters && typeParameters.length) {
|
||||
writePunctuation(writer, SyntaxKind.LessThanToken);
|
||||
buildDisplayForCommaSeparatedList(typeParameters, writer, p => buildTypeParameterDisplay(p, writer, enclosingDeclaration, flags, symbolStack));
|
||||
@@ -3674,7 +3681,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function buildDisplayForCommaSeparatedList<T>(list: T[], writer: SymbolWriter, action: (item: T) => void) {
|
||||
function buildDisplayForCommaSeparatedList<T>(list: ReadonlyArray<T>, writer: SymbolWriter, action: (item: T) => void) {
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
if (i > 0) {
|
||||
writePunctuation(writer, SyntaxKind.CommaToken);
|
||||
@@ -3684,7 +3691,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function buildDisplayForTypeArgumentsAndDelimiters(typeParameters: TypeParameter[], mapper: TypeMapper, writer: SymbolWriter, enclosingDeclaration?: Node) {
|
||||
function buildDisplayForTypeArgumentsAndDelimiters(typeParameters: ReadonlyArray<TypeParameter>, mapper: TypeMapper, writer: SymbolWriter, enclosingDeclaration?: Node) {
|
||||
if (typeParameters && typeParameters.length) {
|
||||
writePunctuation(writer, SyntaxKind.LessThanToken);
|
||||
let flags = TypeFormatFlags.InFirstTypeArgument;
|
||||
@@ -4088,8 +4095,8 @@ namespace ts {
|
||||
|
||||
/** Return the inferred type for a binding element */
|
||||
function getTypeForBindingElement(declaration: BindingElement): Type {
|
||||
const pattern = <BindingPattern>declaration.parent;
|
||||
const parentType = getTypeForBindingElementParent(<VariableLikeDeclaration>pattern.parent);
|
||||
const pattern = declaration.parent;
|
||||
const parentType = getTypeForBindingElementParent(pattern.parent);
|
||||
// If parent has the unknown (error) type, then so does this binding element
|
||||
if (parentType === unknownType) {
|
||||
return unknownType;
|
||||
@@ -4134,7 +4141,8 @@ namespace ts {
|
||||
// or otherwise the type of the string index signature.
|
||||
const text = getTextOfPropertyName(name);
|
||||
|
||||
type = getTypeOfPropertyOfType(parentType, text) ||
|
||||
const declaredType = getTypeOfPropertyOfType(parentType, text);
|
||||
type = declaredType && getFlowTypeOfReference(declaration, declaredType) ||
|
||||
isNumericLiteralName(text) && getIndexTypeOfType(parentType, IndexKind.Number) ||
|
||||
getIndexTypeOfType(parentType, IndexKind.String);
|
||||
if (!type) {
|
||||
@@ -4736,7 +4744,7 @@ namespace ts {
|
||||
// Appends the type parameters given by a list of declarations to a set of type parameters and returns the resulting set.
|
||||
// The function allocates a new array if the input type parameter set is undefined, but otherwise it modifies the set
|
||||
// in-place and returns the same array.
|
||||
function appendTypeParameters(typeParameters: TypeParameter[], declarations: TypeParameterDeclaration[]): TypeParameter[] {
|
||||
function appendTypeParameters(typeParameters: TypeParameter[], declarations: ReadonlyArray<TypeParameterDeclaration>): TypeParameter[] {
|
||||
for (const declaration of declarations) {
|
||||
const tp = getDeclaredTypeOfTypeParameter(getSymbolOfNode(declaration));
|
||||
if (!typeParameters) {
|
||||
@@ -4823,14 +4831,14 @@ namespace ts {
|
||||
return getClassExtendsHeritageClauseElement(<ClassLikeDeclaration>type.symbol.valueDeclaration);
|
||||
}
|
||||
|
||||
function getConstructorsForTypeArguments(type: Type, typeArgumentNodes: TypeNode[], location: Node): Signature[] {
|
||||
function getConstructorsForTypeArguments(type: Type, typeArgumentNodes: ReadonlyArray<TypeNode>, location: Node): Signature[] {
|
||||
const typeArgCount = length(typeArgumentNodes);
|
||||
const isJavaScript = isInJavaScriptFile(location);
|
||||
return filter(getSignaturesOfType(type, SignatureKind.Construct),
|
||||
sig => (isJavaScript || typeArgCount >= getMinTypeArgumentCount(sig.typeParameters)) && typeArgCount <= length(sig.typeParameters));
|
||||
}
|
||||
|
||||
function getInstantiatedConstructorsForTypeArguments(type: Type, typeArgumentNodes: TypeNode[], location: Node): Signature[] {
|
||||
function getInstantiatedConstructorsForTypeArguments(type: Type, typeArgumentNodes: ReadonlyArray<TypeNode>, location: Node): Signature[] {
|
||||
const signatures = getConstructorsForTypeArguments(type, typeArgumentNodes, location);
|
||||
const typeArguments = map(typeArgumentNodes, getTypeFromTypeNode);
|
||||
return sameMap(signatures, sig => some(sig.typeParameters) ? getSignatureInstantiation(sig, typeArguments) : sig);
|
||||
@@ -6870,8 +6878,19 @@ namespace ts {
|
||||
return node.flags & NodeFlags.JSDoc && node.kind === SyntaxKind.TypeReference;
|
||||
}
|
||||
|
||||
function getPrimitiveTypeFromJSDocTypeReference(node: TypeReferenceNode): Type {
|
||||
function getIntendedTypeFromJSDocTypeReference(node: TypeReferenceNode): Type {
|
||||
if (isIdentifier(node.typeName)) {
|
||||
if (node.typeName.text === "Object") {
|
||||
if (node.typeArguments && node.typeArguments.length === 2) {
|
||||
const indexed = getTypeFromTypeNode(node.typeArguments[0]);
|
||||
const target = getTypeFromTypeNode(node.typeArguments[1]);
|
||||
const index = createIndexInfo(target, /*isReadonly*/ false);
|
||||
if (indexed === stringType || indexed === numberType) {
|
||||
return createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, indexed === stringType && index, indexed === numberType && index);
|
||||
}
|
||||
}
|
||||
return anyType;
|
||||
}
|
||||
switch (node.typeName.text) {
|
||||
case "String":
|
||||
return stringType;
|
||||
@@ -6885,8 +6904,6 @@ namespace ts {
|
||||
return undefinedType;
|
||||
case "Null":
|
||||
return nullType;
|
||||
case "Object":
|
||||
return anyType;
|
||||
case "Function":
|
||||
case "function":
|
||||
return globalFunctionType;
|
||||
@@ -6912,7 +6929,7 @@ namespace ts {
|
||||
let type: Type;
|
||||
let meaning = SymbolFlags.Type;
|
||||
if (isJSDocTypeReference(node)) {
|
||||
type = getPrimitiveTypeFromJSDocTypeReference(node);
|
||||
type = getIntendedTypeFromJSDocTypeReference(node);
|
||||
meaning |= SymbolFlags.Value;
|
||||
}
|
||||
if (!type) {
|
||||
@@ -9954,6 +9971,11 @@ namespace ts {
|
||||
neverType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add undefined or null or both to a type if they are missing.
|
||||
* @param type - type to add undefined and/or null to if not present
|
||||
* @param flags - Either TypeFlags.Undefined or TypeFlags.Null, or both
|
||||
*/
|
||||
function getNullableType(type: Type, flags: TypeFlags): Type {
|
||||
const missing = (flags & ~type.flags) & (TypeFlags.Undefined | TypeFlags.Null);
|
||||
return missing === 0 ? type :
|
||||
@@ -10656,7 +10678,7 @@ namespace ts {
|
||||
// The result is undefined if the reference isn't a dotted name. We prefix nodes
|
||||
// occurring in an apparent type position with '@' because the control flow type
|
||||
// of such nodes may be based on the apparent type instead of the declared type.
|
||||
function getFlowCacheKey(node: Node): string {
|
||||
function getFlowCacheKey(node: Node): string | undefined {
|
||||
if (node.kind === SyntaxKind.Identifier) {
|
||||
const symbol = getResolvedSymbol(<Identifier>node);
|
||||
return symbol !== unknownSymbol ? (isApparentTypePosition(node) ? "@" : "") + getSymbolId(symbol) : undefined;
|
||||
@@ -10666,7 +10688,14 @@ namespace ts {
|
||||
}
|
||||
if (node.kind === SyntaxKind.PropertyAccessExpression) {
|
||||
const key = getFlowCacheKey((<PropertyAccessExpression>node).expression);
|
||||
return key && key + "." + (<PropertyAccessExpression>node).name.text;
|
||||
return key && key + "." + unescapeLeadingUnderscores((<PropertyAccessExpression>node).name.text);
|
||||
}
|
||||
if (node.kind === SyntaxKind.BindingElement) {
|
||||
const container = (node as BindingElement).parent.parent;
|
||||
const key = container.kind === SyntaxKind.BindingElement ? getFlowCacheKey(container) : (container.initializer && getFlowCacheKey(container.initializer));
|
||||
const text = getBindingElementNameText(node as BindingElement);
|
||||
const result = key && text && (key + "." + text);
|
||||
return result;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
@@ -10682,6 +10711,28 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getBindingElementNameText(element: BindingElement): string | undefined {
|
||||
if (element.parent.kind === SyntaxKind.ObjectBindingPattern) {
|
||||
const name = element.propertyName || element.name;
|
||||
switch (name.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
return unescapeLeadingUnderscores(name.text);
|
||||
case SyntaxKind.ComputedPropertyName:
|
||||
if (isComputedNonLiteralName(name as PropertyName)) return undefined;
|
||||
return (name.expression as LiteralExpression).text;
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
return name.text;
|
||||
default:
|
||||
// Per types, array and object binding patterns remain, however they should never be present if propertyName is not defined
|
||||
Debug.fail("Unexpected name kind for binding element name");
|
||||
}
|
||||
}
|
||||
else {
|
||||
return "" + element.parent.elements.indexOf(element);
|
||||
}
|
||||
}
|
||||
|
||||
function isMatchingReference(source: Node, target: Node): boolean {
|
||||
switch (source.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
@@ -10696,6 +10747,17 @@ namespace ts {
|
||||
return target.kind === SyntaxKind.PropertyAccessExpression &&
|
||||
(<PropertyAccessExpression>source).name.text === (<PropertyAccessExpression>target).name.text &&
|
||||
isMatchingReference((<PropertyAccessExpression>source).expression, (<PropertyAccessExpression>target).expression);
|
||||
case SyntaxKind.BindingElement:
|
||||
if (target.kind !== SyntaxKind.PropertyAccessExpression) return false;
|
||||
const t = target as PropertyAccessExpression;
|
||||
if (t.name.text !== getBindingElementNameText(source as BindingElement)) return false;
|
||||
if (source.parent.parent.kind === SyntaxKind.BindingElement && isMatchingReference(source.parent.parent, t.expression)) {
|
||||
return true;
|
||||
}
|
||||
if (source.parent.parent.kind === SyntaxKind.VariableDeclaration) {
|
||||
const maybeId = (source.parent.parent as VariableDeclaration).initializer;
|
||||
return maybeId && isMatchingReference(maybeId, t.expression);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -11486,6 +11548,10 @@ namespace ts {
|
||||
const cache = flowLoopCaches[id] || (flowLoopCaches[id] = createMap<Type>());
|
||||
if (!key) {
|
||||
key = getFlowCacheKey(reference);
|
||||
// No cache key is generated when binding patterns are in unnarrowable situations
|
||||
if (!key) {
|
||||
return declaredType;
|
||||
}
|
||||
}
|
||||
const cached = cache.get(key);
|
||||
if (cached) {
|
||||
@@ -12602,7 +12668,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (noImplicitThis) {
|
||||
if (noImplicitThis || isInJavaScriptFile(func)) {
|
||||
const containingLiteral = getContainingObjectLiteral(func);
|
||||
if (containingLiteral) {
|
||||
// We have an object literal method. Check if the containing object literal has a contextual type
|
||||
@@ -14846,7 +14912,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getSpreadArgumentIndex(args: Expression[]): number {
|
||||
function getSpreadArgumentIndex(args: ReadonlyArray<Expression>): number {
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const arg = args[i];
|
||||
if (arg && arg.kind === SyntaxKind.SpreadElement) {
|
||||
@@ -14856,7 +14922,7 @@ namespace ts {
|
||||
return -1;
|
||||
}
|
||||
|
||||
function hasCorrectArity(node: CallLikeExpression, args: Expression[], signature: Signature, signatureHelpTrailingComma = false) {
|
||||
function hasCorrectArity(node: CallLikeExpression, args: ReadonlyArray<Expression>, signature: Signature, signatureHelpTrailingComma = false) {
|
||||
let argCount: number; // Apparent number of arguments we will have in this call
|
||||
let typeArguments: NodeArray<TypeNode>; // Type arguments (undefined if none)
|
||||
let callIsIncomplete: boolean; // In incomplete call we want to be lenient when we have too few arguments
|
||||
@@ -14967,7 +15033,7 @@ namespace ts {
|
||||
return getSignatureInstantiation(signature, getInferredTypes(context));
|
||||
}
|
||||
|
||||
function inferTypeArguments(node: CallLikeExpression, signature: Signature, args: Expression[], excludeArgument: boolean[], context: InferenceContext): Type[] {
|
||||
function inferTypeArguments(node: CallLikeExpression, signature: Signature, args: ReadonlyArray<Expression>, excludeArgument: boolean[], context: InferenceContext): Type[] {
|
||||
// Clear out all the inference results from the last time inferTypeArguments was called on this context
|
||||
for (const inference of context.inferences) {
|
||||
// As an optimization, we don't have to clear (and later recompute) inferred types
|
||||
@@ -15055,7 +15121,7 @@ namespace ts {
|
||||
return getInferredTypes(context);
|
||||
}
|
||||
|
||||
function checkTypeArguments(signature: Signature, typeArgumentNodes: TypeNode[], typeArgumentTypes: Type[], reportErrors: boolean, headMessage?: DiagnosticMessage): boolean {
|
||||
function checkTypeArguments(signature: Signature, typeArgumentNodes: ReadonlyArray<TypeNode>, typeArgumentTypes: Type[], reportErrors: boolean, headMessage?: DiagnosticMessage): boolean {
|
||||
const typeParameters = signature.typeParameters;
|
||||
let typeArgumentsAreAssignable = true;
|
||||
let mapper: TypeMapper;
|
||||
@@ -15119,7 +15185,13 @@ namespace ts {
|
||||
return checkTypeRelatedTo(attributesType, paramType, relation, /*errorNode*/ undefined, headMessage);
|
||||
}
|
||||
|
||||
function checkApplicableSignature(node: CallLikeExpression, args: Expression[], signature: Signature, relation: Map<RelationComparisonResult>, excludeArgument: boolean[], reportErrors: boolean) {
|
||||
function checkApplicableSignature(
|
||||
node: CallLikeExpression,
|
||||
args: ReadonlyArray<Expression>,
|
||||
signature: Signature,
|
||||
relation: Map<RelationComparisonResult>,
|
||||
excludeArgument: boolean[],
|
||||
reportErrors: boolean) {
|
||||
if (isJsxOpeningLikeElement(node)) {
|
||||
return checkApplicableSignatureForJsxOpeningLikeElement(<JsxOpeningLikeElement>node, signature, relation);
|
||||
}
|
||||
@@ -15187,16 +15259,16 @@ namespace ts {
|
||||
* If 'node' is a Decorator, the argument list will be `undefined`, and its arguments and types
|
||||
* will be supplied from calls to `getEffectiveArgumentCount` and `getEffectiveArgumentType`.
|
||||
*/
|
||||
function getEffectiveCallArguments(node: CallLikeExpression): Expression[] {
|
||||
let args: Expression[];
|
||||
function getEffectiveCallArguments(node: CallLikeExpression): ReadonlyArray<Expression> {
|
||||
if (node.kind === SyntaxKind.TaggedTemplateExpression) {
|
||||
const template = (<TaggedTemplateExpression>node).template;
|
||||
args = [undefined];
|
||||
const args: Expression[] = [undefined];
|
||||
if (template.kind === SyntaxKind.TemplateExpression) {
|
||||
forEach((<TemplateExpression>template).templateSpans, span => {
|
||||
args.push(span.expression);
|
||||
});
|
||||
}
|
||||
return args;
|
||||
}
|
||||
else if (node.kind === SyntaxKind.Decorator) {
|
||||
// For a decorator, we return undefined as we will determine
|
||||
@@ -15205,13 +15277,11 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
else if (isJsxOpeningLikeElement(node)) {
|
||||
args = node.attributes.properties.length > 0 ? [node.attributes] : emptyArray;
|
||||
return node.attributes.properties.length > 0 ? [node.attributes] : emptyArray;
|
||||
}
|
||||
else {
|
||||
args = node.arguments || emptyArray;
|
||||
return node.arguments || emptyArray;
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
|
||||
@@ -15228,7 +15298,7 @@ namespace ts {
|
||||
* us to match a property decorator.
|
||||
* Otherwise, the argument count is the length of the 'args' array.
|
||||
*/
|
||||
function getEffectiveArgumentCount(node: CallLikeExpression, args: Expression[], signature: Signature) {
|
||||
function getEffectiveArgumentCount(node: CallLikeExpression, args: ReadonlyArray<Expression>, signature: Signature) {
|
||||
if (node.kind === SyntaxKind.Decorator) {
|
||||
switch (node.parent.kind) {
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
@@ -15460,7 +15530,7 @@ namespace ts {
|
||||
/**
|
||||
* Gets the effective argument expression for an argument in a call expression.
|
||||
*/
|
||||
function getEffectiveArgument(node: CallLikeExpression, args: Expression[], argIndex: number) {
|
||||
function getEffectiveArgument(node: CallLikeExpression, args: ReadonlyArray<Expression>, argIndex: number) {
|
||||
// For a decorator or the first argument of a tagged template expression we return undefined.
|
||||
if (node.kind === SyntaxKind.Decorator ||
|
||||
(argIndex === 0 && node.kind === SyntaxKind.TaggedTemplateExpression)) {
|
||||
@@ -15492,7 +15562,7 @@ namespace ts {
|
||||
const isDecorator = node.kind === SyntaxKind.Decorator;
|
||||
const isJsxOpeningOrSelfClosingElement = isJsxOpeningLikeElement(node);
|
||||
|
||||
let typeArguments: TypeNode[];
|
||||
let typeArguments: ReadonlyArray<TypeNode>;
|
||||
|
||||
if (!isTaggedTemplate && !isDecorator && !isJsxOpeningOrSelfClosingElement) {
|
||||
typeArguments = (<CallExpression>node).typeArguments;
|
||||
@@ -16256,15 +16326,19 @@ namespace ts {
|
||||
}
|
||||
|
||||
function checkAssertion(node: AssertionExpression) {
|
||||
const exprType = getRegularTypeOfObjectLiteral(getBaseTypeOfLiteralType(checkExpression(node.expression)));
|
||||
return checkAssertionWorker(node, node.type, node.expression);
|
||||
}
|
||||
|
||||
checkSourceElement(node.type);
|
||||
const targetType = getTypeFromTypeNode(node.type);
|
||||
function checkAssertionWorker(errNode: Node, type: TypeNode, expression: UnaryExpression | Expression, checkMode?: CheckMode) {
|
||||
const exprType = getRegularTypeOfObjectLiteral(getBaseTypeOfLiteralType(checkExpression(expression, checkMode)));
|
||||
|
||||
checkSourceElement(type);
|
||||
const targetType = getTypeFromTypeNode(type);
|
||||
|
||||
if (produceDiagnostics && targetType !== unknownType) {
|
||||
const widenedType = getWidenedType(exprType);
|
||||
if (!isTypeComparableTo(targetType, widenedType)) {
|
||||
checkTypeComparableTo(exprType, targetType, node, Diagnostics.Type_0_cannot_be_converted_to_type_1);
|
||||
checkTypeComparableTo(exprType, targetType, errNode, Diagnostics.Type_0_cannot_be_converted_to_type_1);
|
||||
}
|
||||
}
|
||||
return targetType;
|
||||
@@ -17001,7 +17075,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
/** Note: If property cannot be a SpreadAssignment, then allProperties does not need to be provided */
|
||||
function checkObjectLiteralDestructuringPropertyAssignment(objectLiteralType: Type, property: ObjectLiteralElementLike, allProperties?: ObjectLiteralElementLike[]) {
|
||||
function checkObjectLiteralDestructuringPropertyAssignment(objectLiteralType: Type, property: ObjectLiteralElementLike, allProperties?: ReadonlyArray<ObjectLiteralElementLike>) {
|
||||
if (property.kind === SyntaxKind.PropertyAssignment || property.kind === SyntaxKind.ShorthandPropertyAssignment) {
|
||||
const name = <PropertyName>(<PropertyAssignment>property).name;
|
||||
if (name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
@@ -17735,6 +17809,18 @@ namespace ts {
|
||||
return type;
|
||||
}
|
||||
|
||||
function checkParenthesizedExpression(node: ParenthesizedExpression, checkMode?: CheckMode): Type {
|
||||
if (isInJavaScriptFile(node) && node.jsDoc) {
|
||||
const typecasts = flatMap(node.jsDoc, doc => filter(doc.tags, tag => tag.kind === SyntaxKind.JSDocTypeTag));
|
||||
if (typecasts && typecasts.length) {
|
||||
// We should have already issued an error if there were multiple type jsdocs
|
||||
const cast = typecasts[0] as JSDocTypeTag;
|
||||
return checkAssertionWorker(cast, cast.typeExpression.type, node.expression, checkMode);
|
||||
}
|
||||
}
|
||||
return checkExpression(node.expression, checkMode);
|
||||
}
|
||||
|
||||
function checkExpressionWorker(node: Expression, checkMode: CheckMode): Type {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
@@ -17774,7 +17860,7 @@ namespace ts {
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
return checkTaggedTemplateExpression(<TaggedTemplateExpression>node);
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
return checkExpression((<ParenthesizedExpression>node).expression, checkMode);
|
||||
return checkParenthesizedExpression(<ParenthesizedExpression>node, checkMode);
|
||||
case SyntaxKind.ClassExpression:
|
||||
return checkClassExpression(<ClassExpression>node);
|
||||
case SyntaxKind.FunctionExpression:
|
||||
@@ -17910,6 +17996,8 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
|
||||
checkSourceElement(node.type);
|
||||
|
||||
const { parameterName } = node;
|
||||
if (isThisTypePredicate(typePredicate)) {
|
||||
getTypeFromThisTypeNode(parameterName as ThisTypeNode);
|
||||
@@ -18433,7 +18521,7 @@ namespace ts {
|
||||
checkDecorators(node);
|
||||
}
|
||||
|
||||
function checkTypeArgumentConstraints(typeParameters: TypeParameter[], typeArgumentNodes: TypeNode[]): boolean {
|
||||
function checkTypeArgumentConstraints(typeParameters: TypeParameter[], typeArgumentNodes: ReadonlyArray<TypeNode>): boolean {
|
||||
const minTypeArgumentCount = getMinTypeArgumentCount(typeParameters);
|
||||
let typeArguments: Type[];
|
||||
let mapper: TypeMapper;
|
||||
@@ -20879,7 +20967,7 @@ namespace ts {
|
||||
/**
|
||||
* Check each type parameter and check that type parameters have no duplicate type parameter declarations
|
||||
*/
|
||||
function checkTypeParameters(typeParameterDeclarations: TypeParameterDeclaration[]) {
|
||||
function checkTypeParameters(typeParameterDeclarations: ReadonlyArray<TypeParameterDeclaration>) {
|
||||
if (typeParameterDeclarations) {
|
||||
let seenDefault = false;
|
||||
for (let i = 0; i < typeParameterDeclarations.length; i++) {
|
||||
@@ -22186,8 +22274,8 @@ namespace ts {
|
||||
// Grammar checking
|
||||
checkGrammarSourceFile(node);
|
||||
|
||||
potentialThisCollisions.length = 0;
|
||||
potentialNewTargetCollisions.length = 0;
|
||||
clear(potentialThisCollisions);
|
||||
clear(potentialNewTargetCollisions);
|
||||
|
||||
deferredNodes = [];
|
||||
deferredUnusedIdentifierNodes = produceDiagnostics && noUnusedIdentifiers ? [] : undefined;
|
||||
@@ -22213,12 +22301,12 @@ namespace ts {
|
||||
|
||||
if (potentialThisCollisions.length) {
|
||||
forEach(potentialThisCollisions, checkIfThisIsCapturedInEnclosingScope);
|
||||
potentialThisCollisions.length = 0;
|
||||
clear(potentialThisCollisions);
|
||||
}
|
||||
|
||||
if (potentialNewTargetCollisions.length) {
|
||||
forEach(potentialNewTargetCollisions, checkIfNewTargetIsCapturedInEnclosingScope);
|
||||
potentialNewTargetCollisions.length = 0;
|
||||
clear(potentialNewTargetCollisions);
|
||||
}
|
||||
|
||||
links.flags |= NodeCheckFlags.TypeChecked;
|
||||
@@ -23466,7 +23554,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Initialize global symbol table
|
||||
let augmentations: LiteralExpression[][];
|
||||
let augmentations: ReadonlyArray<StringLiteral>[];
|
||||
for (const file of host.getSourceFiles()) {
|
||||
if (!isExternalOrCommonJsModule(file)) {
|
||||
mergeSymbolTable(globals, file.locals);
|
||||
|
||||
+17
-11
@@ -2,6 +2,8 @@
|
||||
/// <reference path="performance.ts" />
|
||||
|
||||
namespace ts {
|
||||
// WARNING: The script `configureNightly.ts` uses a regexp to parse out these values.
|
||||
// If changing the text in this section, be sure to test `configureNightly` too.
|
||||
export const versionMajorMinor = "2.5";
|
||||
/** The version of the TypeScript compiler release */
|
||||
export const version = `${versionMajorMinor}.0`;
|
||||
@@ -384,6 +386,10 @@ namespace ts {
|
||||
array.length = outIndex;
|
||||
}
|
||||
|
||||
export function clear(array: {}[]): void {
|
||||
array.length = 0;
|
||||
}
|
||||
|
||||
export function map<T, U>(array: ReadonlyArray<T>, f: (x: T, i: number) => U): U[] {
|
||||
let result: U[];
|
||||
if (array) {
|
||||
@@ -592,7 +598,7 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
export function mapEntries<T, U>(map: Map<T>, f: (key: string, value: T) => [string, U]): Map<U> {
|
||||
export function mapEntries<T, U>(map: ReadonlyMap<T>, f: (key: string, value: T) => [string, U]): Map<U> {
|
||||
if (!map) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -1005,9 +1011,9 @@ namespace ts {
|
||||
* Calls `callback` for each entry in the map, returning the first truthy result.
|
||||
* Use `map.forEach` instead for normal iteration.
|
||||
*/
|
||||
export function forEachEntry<T, U>(map: UnderscoreEscapedMap<T>, callback: (value: T, key: __String) => U | undefined): U | undefined;
|
||||
export function forEachEntry<T, U>(map: Map<T>, callback: (value: T, key: string) => U | undefined): U | undefined;
|
||||
export function forEachEntry<T, U>(map: UnderscoreEscapedMap<T> | Map<T>, callback: (value: T, key: (string & __String)) => U | undefined): U | undefined {
|
||||
export function forEachEntry<T, U>(map: ReadonlyUnderscoreEscapedMap<T>, callback: (value: T, key: __String) => U | undefined): U | undefined;
|
||||
export function forEachEntry<T, U>(map: ReadonlyMap<T>, callback: (value: T, key: string) => U | undefined): U | undefined;
|
||||
export function forEachEntry<T, U>(map: ReadonlyUnderscoreEscapedMap<T> | ReadonlyMap<T>, callback: (value: T, key: (string & __String)) => U | undefined): U | undefined {
|
||||
const iterator = map.entries();
|
||||
for (let { value: pair, done } = iterator.next(); !done; { value: pair, done } = iterator.next()) {
|
||||
const [key, value] = pair;
|
||||
@@ -1020,9 +1026,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
/** `forEachEntry` for just keys. */
|
||||
export function forEachKey<T>(map: UnderscoreEscapedMap<{}>, callback: (key: __String) => T | undefined): T | undefined;
|
||||
export function forEachKey<T>(map: Map<{}>, callback: (key: string) => T | undefined): T | undefined;
|
||||
export function forEachKey<T>(map: UnderscoreEscapedMap<{}> | Map<{}>, callback: (key: string & __String) => T | undefined): T | undefined {
|
||||
export function forEachKey<T>(map: ReadonlyUnderscoreEscapedMap<{}>, callback: (key: __String) => T | undefined): T | undefined;
|
||||
export function forEachKey<T>(map: ReadonlyMap<{}>, callback: (key: string) => T | undefined): T | undefined;
|
||||
export function forEachKey<T>(map: ReadonlyUnderscoreEscapedMap<{}> | ReadonlyMap<{}>, callback: (key: string & __String) => T | undefined): T | undefined {
|
||||
const iterator = map.keys();
|
||||
for (let { value: key, done } = iterator.next(); !done; { value: key, done } = iterator.next()) {
|
||||
const result = callback(key as string & __String);
|
||||
@@ -1034,8 +1040,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
/** Copy entries from `source` to `target`. */
|
||||
export function copyEntries<T>(source: UnderscoreEscapedMap<T>, target: UnderscoreEscapedMap<T>): void;
|
||||
export function copyEntries<T>(source: Map<T>, target: Map<T>): void;
|
||||
export function copyEntries<T>(source: ReadonlyUnderscoreEscapedMap<T>, target: UnderscoreEscapedMap<T>): void;
|
||||
export function copyEntries<T>(source: ReadonlyMap<T>, target: Map<T>): void;
|
||||
export function copyEntries<T, U extends UnderscoreEscapedMap<T> | Map<T>>(source: U, target: U): void {
|
||||
(source as Map<T>).forEach((value, key) => {
|
||||
(target as Map<T>).set(key, value);
|
||||
@@ -1113,8 +1119,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function cloneMap(map: SymbolTable): SymbolTable;
|
||||
export function cloneMap<T>(map: Map<T>): Map<T>;
|
||||
export function cloneMap<T>(map: Map<T> | SymbolTable): Map<T> | SymbolTable {
|
||||
export function cloneMap<T>(map: ReadonlyMap<T>): Map<T>;
|
||||
export function cloneMap<T>(map: ReadonlyMap<T> | SymbolTable): Map<T> | SymbolTable {
|
||||
const clone = createMap<T>();
|
||||
copyEntries(map as Map<T>, clone);
|
||||
return clone;
|
||||
|
||||
@@ -211,7 +211,7 @@ namespace ts {
|
||||
decreaseIndent = newWriter.decreaseIndent;
|
||||
}
|
||||
|
||||
function writeAsynchronousModuleElements(nodes: Node[]) {
|
||||
function writeAsynchronousModuleElements(nodes: ReadonlyArray<Node>) {
|
||||
const oldWriter = writer;
|
||||
forEach(nodes, declaration => {
|
||||
let nodeToCheck: Node;
|
||||
@@ -374,13 +374,13 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function emitLines(nodes: Node[]) {
|
||||
function emitLines(nodes: ReadonlyArray<Node>) {
|
||||
for (const node of nodes) {
|
||||
emit(node);
|
||||
}
|
||||
}
|
||||
|
||||
function emitSeparatedList(nodes: Node[], separator: string, eachNodeEmitFn: (node: Node) => void, canEmitFn?: (node: Node) => boolean) {
|
||||
function emitSeparatedList(nodes: ReadonlyArray<Node>, separator: string, eachNodeEmitFn: (node: Node) => void, canEmitFn?: (node: Node) => boolean) {
|
||||
let currentWriterPos = writer.getTextPos();
|
||||
for (const node of nodes) {
|
||||
if (!canEmitFn || canEmitFn(node)) {
|
||||
@@ -393,7 +393,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function emitCommaList(nodes: Node[], eachNodeEmitFn: (node: Node) => void, canEmitFn?: (node: Node) => boolean) {
|
||||
function emitCommaList(nodes: ReadonlyArray<Node>, eachNodeEmitFn: (node: Node) => void, canEmitFn?: (node: Node) => boolean) {
|
||||
emitSeparatedList(nodes, ", ", eachNodeEmitFn, canEmitFn);
|
||||
}
|
||||
|
||||
@@ -1007,7 +1007,7 @@ namespace ts {
|
||||
return node.parent.kind === SyntaxKind.MethodDeclaration && hasModifier(node.parent, ModifierFlags.Private);
|
||||
}
|
||||
|
||||
function emitTypeParameters(typeParameters: TypeParameterDeclaration[]) {
|
||||
function emitTypeParameters(typeParameters: ReadonlyArray<TypeParameterDeclaration>) {
|
||||
function emitTypeParameter(node: TypeParameterDeclaration) {
|
||||
increaseIndent();
|
||||
emitJsDocComments(node);
|
||||
@@ -1109,7 +1109,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function emitHeritageClause(typeReferences: ExpressionWithTypeArguments[], isImplementsList: boolean) {
|
||||
function emitHeritageClause(typeReferences: ReadonlyArray<ExpressionWithTypeArguments>, isImplementsList: boolean) {
|
||||
if (typeReferences) {
|
||||
write(isImplementsList ? " implements " : " extends ");
|
||||
emitCommaList(typeReferences, emitTypeOfTypeReference);
|
||||
|
||||
@@ -2228,7 +2228,7 @@ namespace ts {
|
||||
* Emits any prologue directives at the start of a Statement list, returning the
|
||||
* number of prologue directives written to the output.
|
||||
*/
|
||||
function emitPrologueDirectives(statements: Node[], startWithNewLine?: boolean, seenPrologueDirectives?: Map<true>): number {
|
||||
function emitPrologueDirectives(statements: ReadonlyArray<Node>, startWithNewLine?: boolean, seenPrologueDirectives?: Map<true>): number {
|
||||
for (let i = 0; i < statements.length; i++) {
|
||||
const statement = statements[i];
|
||||
if (isPrologueDirective(statement)) {
|
||||
|
||||
+338
-111
File diff suppressed because it is too large
Load Diff
@@ -1121,8 +1121,8 @@ namespace ts {
|
||||
new TokenConstructor(kind, pos, pos);
|
||||
}
|
||||
|
||||
function createNodeArray<T extends Node>(elements?: T[], pos?: number): NodeArray<T> {
|
||||
const array = <NodeArray<T>>(elements || []);
|
||||
function createNodeArray<T extends Node>(elements?: T[], pos?: number): MutableNodeArray<T> {
|
||||
const array = <MutableNodeArray<T>>(elements || []);
|
||||
if (!(pos >= 0)) {
|
||||
pos = getNodePos();
|
||||
}
|
||||
@@ -4342,7 +4342,7 @@ namespace ts {
|
||||
parseExpected(SyntaxKind.OpenParenToken);
|
||||
node.expression = allowInAnd(parseExpression);
|
||||
parseExpected(SyntaxKind.CloseParenToken);
|
||||
return finishNode(node);
|
||||
return addJSDocComment(finishNode(node));
|
||||
}
|
||||
|
||||
function parseSpreadElement(): Expression {
|
||||
@@ -5395,7 +5395,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function parseDecorators(): NodeArray<Decorator> {
|
||||
let decorators: NodeArray<Decorator>;
|
||||
let decorators: NodeArray<Decorator> & Decorator[];
|
||||
while (true) {
|
||||
const decoratorStart = getNodePos();
|
||||
if (!parseOptional(SyntaxKind.AtToken)) {
|
||||
@@ -5426,7 +5426,7 @@ namespace ts {
|
||||
* In such situations, 'permitInvalidConstAsModifier' should be set to true.
|
||||
*/
|
||||
function parseModifiers(permitInvalidConstAsModifier?: boolean): NodeArray<Modifier> | undefined {
|
||||
let modifiers: NodeArray<Modifier> | undefined;
|
||||
let modifiers: MutableNodeArray<Modifier> | undefined;
|
||||
while (true) {
|
||||
const modifierStart = scanner.getStartPos();
|
||||
const modifierKind = token();
|
||||
@@ -6165,7 +6165,7 @@ namespace ts {
|
||||
Debug.assert(start <= end);
|
||||
Debug.assert(end <= content.length);
|
||||
|
||||
let tags: NodeArray<JSDocTag>;
|
||||
let tags: MutableNodeArray<JSDocTag>;
|
||||
const comments: string[] = [];
|
||||
let result: JSDoc;
|
||||
|
||||
@@ -6673,9 +6673,9 @@ namespace ts {
|
||||
const propertyTag = parseParameterOrPropertyTag(atToken, tagName, /*shouldParseParamTag*/ false) as JSDocPropertyTag;
|
||||
if (propertyTag) {
|
||||
if (!parentTag.jsDocPropertyTags) {
|
||||
parentTag.jsDocPropertyTags = <NodeArray<JSDocPropertyTag>>[];
|
||||
parentTag.jsDocPropertyTags = <MutableNodeArray<JSDocPropertyTag>>[];
|
||||
}
|
||||
parentTag.jsDocPropertyTags.push(propertyTag);
|
||||
(parentTag.jsDocPropertyTags as MutableNodeArray<JSDocPropertyTag>).push(propertyTag);
|
||||
return true;
|
||||
}
|
||||
// Error parsing property tag
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
/// <reference path="core.ts" />
|
||||
|
||||
namespace ts {
|
||||
const emptyArray: any[] = [];
|
||||
const ignoreDiagnosticCommentRegEx = /(^\s*$)|(^\s*\/\/\/?\s*(@ts-ignore)?)/;
|
||||
|
||||
export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName = "tsconfig.json"): string {
|
||||
@@ -1390,8 +1389,8 @@ namespace ts {
|
||||
const isExternalModuleFile = isExternalModule(file);
|
||||
|
||||
// file.imports may not be undefined if there exists dynamic import
|
||||
let imports: LiteralExpression[];
|
||||
let moduleAugmentations: LiteralExpression[];
|
||||
let imports: StringLiteral[];
|
||||
let moduleAugmentations: StringLiteral[];
|
||||
let ambientModules: string[];
|
||||
|
||||
// If we are importing helpers, we need to add a synthetic reference to resolve the
|
||||
@@ -1426,23 +1425,23 @@ namespace ts {
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
const moduleNameExpr = getExternalModuleName(node);
|
||||
if (!moduleNameExpr || moduleNameExpr.kind !== SyntaxKind.StringLiteral) {
|
||||
if (!moduleNameExpr || !isStringLiteral(moduleNameExpr)) {
|
||||
break;
|
||||
}
|
||||
if (!(<LiteralExpression>moduleNameExpr).text) {
|
||||
if (!moduleNameExpr.text) {
|
||||
break;
|
||||
}
|
||||
|
||||
// TypeScript 1.0 spec (April 2014): 12.1.6
|
||||
// An ExternalImportDeclaration in an AmbientExternalModuleDeclaration may reference other external modules
|
||||
// only through top - level external module names. Relative external module names are not permitted.
|
||||
if (!inAmbientModule || !isExternalModuleNameRelative((<LiteralExpression>moduleNameExpr).text)) {
|
||||
(imports || (imports = [])).push(<LiteralExpression>moduleNameExpr);
|
||||
if (!inAmbientModule || !isExternalModuleNameRelative(moduleNameExpr.text)) {
|
||||
(imports || (imports = [])).push(moduleNameExpr);
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
if (isAmbientModule(<ModuleDeclaration>node) && (inAmbientModule || hasModifier(node, ModifierFlags.Ambient) || file.isDeclarationFile)) {
|
||||
const moduleName = <LiteralExpression>(<ModuleDeclaration>node).name;
|
||||
const moduleName = <StringLiteral>(<ModuleDeclaration>node).name;
|
||||
// Ambient module declarations can be interpreted as augmentations for some existing external modules.
|
||||
// This will happen in two cases:
|
||||
// - if current file is external module then module augmentation is a ambient module declaration defined in the top level scope
|
||||
|
||||
@@ -492,7 +492,7 @@ namespace ts {
|
||||
/** Given value: o, propName: p, pattern: { a, b, ...p } from the original statement
|
||||
* `{ a, b, ...p } = o`, create `p = __rest(o, ["a", "b"]);`
|
||||
*/
|
||||
function createRestCall(context: TransformationContext, value: Expression, elements: BindingOrAssignmentElement[], computedTempVariables: Expression[], location: TextRange): Expression {
|
||||
function createRestCall(context: TransformationContext, value: Expression, elements: ReadonlyArray<BindingOrAssignmentElement>, computedTempVariables: ReadonlyArray<Expression>, location: TextRange): Expression {
|
||||
context.requestEmitHelper(restHelper);
|
||||
const propertyNames: Expression[] = [];
|
||||
let computedTempVariableOffset = 0;
|
||||
|
||||
@@ -1963,7 +1963,7 @@ namespace ts {
|
||||
updated,
|
||||
setTextRange(
|
||||
createNodeArray(
|
||||
prependCaptureNewTargetIfNeeded(updated.statements, node, /*copyOnWrite*/ true)
|
||||
prependCaptureNewTargetIfNeeded(updated.statements as MutableNodeArray<Statement>, node, /*copyOnWrite*/ true)
|
||||
),
|
||||
/*location*/ updated.statements
|
||||
)
|
||||
@@ -3199,7 +3199,7 @@ namespace ts {
|
||||
|
||||
function addStatementToStartOfBlock(block: Block, statement: Statement): Block {
|
||||
const transformedStatements = visitNodes(block.statements, visitor, isStatement);
|
||||
return updateBlock(block, [statement].concat(transformedStatements));
|
||||
return updateBlock(block, [statement, ...transformedStatements]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -156,7 +156,7 @@ namespace ts {
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
function chunkObjectLiteralElements(elements: ObjectLiteralElement[]): Expression[] {
|
||||
function chunkObjectLiteralElements(elements: ReadonlyArray<ObjectLiteralElement>): Expression[] {
|
||||
let chunkObject: (ShorthandPropertyAssignment | PropertyAssignment)[];
|
||||
const objects: Expression[] = [];
|
||||
for (const e of elements) {
|
||||
|
||||
@@ -1176,7 +1176,7 @@ namespace ts {
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
function transformAndEmitStatements(statements: Statement[], start = 0) {
|
||||
function transformAndEmitStatements(statements: ReadonlyArray<Statement>, start = 0) {
|
||||
const numStatements = statements.length;
|
||||
for (let i = start; i < numStatements; i++) {
|
||||
transformAndEmitStatement(statements[i]);
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace ts {
|
||||
return visitJsxOpeningLikeElement(node, /*children*/ undefined, isChild, /*location*/ node);
|
||||
}
|
||||
|
||||
function visitJsxOpeningLikeElement(node: JsxOpeningLikeElement, children: JsxChild[], isChild: boolean, location: TextRange) {
|
||||
function visitJsxOpeningLikeElement(node: JsxOpeningLikeElement, children: ReadonlyArray<JsxChild>, isChild: boolean, location: TextRange) {
|
||||
const tagName = getTagName(node);
|
||||
let objectProperties: Expression;
|
||||
const attrs = node.attributes.properties;
|
||||
|
||||
@@ -522,7 +522,7 @@ namespace ts {
|
||||
return parameter.decorators !== undefined && parameter.decorators.length > 0;
|
||||
}
|
||||
|
||||
function getClassFacts(node: ClassDeclaration, staticProperties: PropertyDeclaration[]) {
|
||||
function getClassFacts(node: ClassDeclaration, staticProperties: ReadonlyArray<PropertyDeclaration>) {
|
||||
let facts = ClassFacts.None;
|
||||
if (some(staticProperties)) facts |= ClassFacts.HasStaticInitializedProperties;
|
||||
if (getClassExtendsHeritageClauseElement(node)) facts |= ClassFacts.HasExtendsClause;
|
||||
@@ -1051,7 +1051,7 @@ namespace ts {
|
||||
*
|
||||
* @param node The constructor node.
|
||||
*/
|
||||
function getParametersWithPropertyAssignments(node: ConstructorDeclaration): ParameterDeclaration[] {
|
||||
function getParametersWithPropertyAssignments(node: ConstructorDeclaration): ReadonlyArray<ParameterDeclaration> {
|
||||
return filter(node.parameters, isParameterWithPropertyAssignment);
|
||||
}
|
||||
|
||||
@@ -1104,7 +1104,7 @@ namespace ts {
|
||||
* @param node The class node.
|
||||
* @param isStatic A value indicating whether to get properties from the static or instance side of the class.
|
||||
*/
|
||||
function getInitializedProperties(node: ClassExpression | ClassDeclaration, isStatic: boolean): PropertyDeclaration[] {
|
||||
function getInitializedProperties(node: ClassExpression | ClassDeclaration, isStatic: boolean): ReadonlyArray<PropertyDeclaration> {
|
||||
return filter(node.members, isStatic ? isStaticInitializedProperty : isInstanceInitializedProperty);
|
||||
}
|
||||
|
||||
@@ -1144,7 +1144,7 @@ namespace ts {
|
||||
* @param properties An array of property declarations to transform.
|
||||
* @param receiver The receiver on which each property should be assigned.
|
||||
*/
|
||||
function addInitializedPropertyStatements(statements: Statement[], properties: PropertyDeclaration[], receiver: LeftHandSideExpression) {
|
||||
function addInitializedPropertyStatements(statements: Statement[], properties: ReadonlyArray<PropertyDeclaration>, receiver: LeftHandSideExpression) {
|
||||
for (const property of properties) {
|
||||
const statement = createStatement(transformInitializedProperty(property, receiver));
|
||||
setSourceMapRange(statement, moveRangePastModifiers(property));
|
||||
@@ -1159,7 +1159,7 @@ namespace ts {
|
||||
* @param properties An array of property declarations to transform.
|
||||
* @param receiver The receiver on which each property should be assigned.
|
||||
*/
|
||||
function generateInitializedPropertyExpressions(properties: PropertyDeclaration[], receiver: LeftHandSideExpression) {
|
||||
function generateInitializedPropertyExpressions(properties: ReadonlyArray<PropertyDeclaration>, receiver: LeftHandSideExpression) {
|
||||
const expressions: Expression[] = [];
|
||||
for (const property of properties) {
|
||||
const expression = transformInitializedProperty(property, receiver);
|
||||
@@ -1194,7 +1194,7 @@ namespace ts {
|
||||
* @param isStatic A value indicating whether to retrieve static or instance members of
|
||||
* the class.
|
||||
*/
|
||||
function getDecoratedClassElements(node: ClassExpression | ClassDeclaration, isStatic: boolean): ClassElement[] {
|
||||
function getDecoratedClassElements(node: ClassExpression | ClassDeclaration, isStatic: boolean): ReadonlyArray<ClassElement> {
|
||||
return filter(node.members, isStatic ? isStaticDecoratedClassElement : isInstanceDecoratedClassElement);
|
||||
}
|
||||
|
||||
@@ -1233,8 +1233,8 @@ namespace ts {
|
||||
* A structure describing the decorators for a class element.
|
||||
*/
|
||||
interface AllDecorators {
|
||||
decorators: Decorator[];
|
||||
parameters?: Decorator[][];
|
||||
decorators: ReadonlyArray<Decorator>;
|
||||
parameters?: ReadonlyArray<ReadonlyArray<Decorator>>;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1244,7 +1244,7 @@ namespace ts {
|
||||
* @param node The function-like node.
|
||||
*/
|
||||
function getDecoratorsOfParameters(node: FunctionLikeDeclaration) {
|
||||
let decorators: Decorator[][];
|
||||
let decorators: ReadonlyArray<Decorator>[];
|
||||
if (node) {
|
||||
const parameters = node.parameters;
|
||||
for (let i = 0; i < parameters.length; i++) {
|
||||
@@ -1377,7 +1377,7 @@ namespace ts {
|
||||
|
||||
const decoratorExpressions: Expression[] = [];
|
||||
addRange(decoratorExpressions, map(allDecorators.decorators, transformDecorator));
|
||||
addRange(decoratorExpressions, flatMap<Decorator[], Expression>(allDecorators.parameters, transformDecoratorsOfParameter));
|
||||
addRange(decoratorExpressions, flatMap(allDecorators.parameters, transformDecoratorsOfParameter));
|
||||
addTypeMetadata(node, container, decoratorExpressions);
|
||||
return decoratorExpressions;
|
||||
}
|
||||
|
||||
+29
-16
@@ -8,13 +8,10 @@ namespace ts {
|
||||
[index: string]: T;
|
||||
}
|
||||
|
||||
/** ES6 Map interface. */
|
||||
export interface Map<T> {
|
||||
/** ES6 Map interface, only read methods included. */
|
||||
export interface ReadonlyMap<T> {
|
||||
get(key: string): T | undefined;
|
||||
has(key: string): boolean;
|
||||
set(key: string, value: T): this;
|
||||
delete(key: string): boolean;
|
||||
clear(): void;
|
||||
forEach(action: (value: T, key: string) => void): void;
|
||||
readonly size: number;
|
||||
keys(): Iterator<string>;
|
||||
@@ -22,6 +19,13 @@ namespace ts {
|
||||
entries(): Iterator<[string, T]>;
|
||||
}
|
||||
|
||||
/** ES6 Map interface. */
|
||||
export interface Map<T> extends ReadonlyMap<T> {
|
||||
set(key: string, value: T): this;
|
||||
delete(key: string): boolean;
|
||||
clear(): void;
|
||||
}
|
||||
|
||||
/** ES6 Iterator type. */
|
||||
export interface Iterator<T> {
|
||||
next(): { value: T, done: false } | { value: never, done: true };
|
||||
@@ -519,7 +523,10 @@ namespace ts {
|
||||
/* @internal */ contextualMapper?: TypeMapper; // Mapper for contextual type
|
||||
}
|
||||
|
||||
export interface NodeArray<T extends Node> extends Array<T>, TextRange {
|
||||
/* @internal */
|
||||
export type MutableNodeArray<T extends Node> = NodeArray<T> & T[];
|
||||
|
||||
export interface NodeArray<T extends Node> extends ReadonlyArray<T>, TextRange {
|
||||
hasTrailingComma?: boolean;
|
||||
/* @internal */ transformFlags?: TransformFlags;
|
||||
}
|
||||
@@ -673,7 +680,7 @@ namespace ts {
|
||||
kind: SyntaxKind.Parameter;
|
||||
parent?: SignatureDeclaration;
|
||||
dotDotDotToken?: DotDotDotToken; // Present on rest parameter
|
||||
name: BindingName; // Declared parameter name
|
||||
name?: BindingName; // Declared parameter name. Missing if this is a parameter in a JSDocFunctionType.
|
||||
questionToken?: QuestionToken; // Present on optional parameter
|
||||
type?: TypeNode; // Optional type annotation
|
||||
initializer?: Expression; // Optional initializer
|
||||
@@ -751,7 +758,7 @@ namespace ts {
|
||||
export interface VariableLikeDeclaration extends NamedDeclaration {
|
||||
propertyName?: PropertyName;
|
||||
dotDotDotToken?: DotDotDotToken;
|
||||
name: DeclarationName;
|
||||
name?: DeclarationName; // May be missing for ParameterDeclaration, see comment there
|
||||
questionToken?: QuestionToken;
|
||||
type?: TypeNode;
|
||||
initializer?: Expression;
|
||||
@@ -2314,10 +2321,10 @@ namespace ts {
|
||||
// Content of this field should never be used directly - use getResolvedModuleFileName/setResolvedModuleFileName functions instead
|
||||
/* @internal */ resolvedModules: Map<ResolvedModuleFull>;
|
||||
/* @internal */ resolvedTypeReferenceDirectiveNames: Map<ResolvedTypeReferenceDirective>;
|
||||
/* @internal */ imports: StringLiteral[];
|
||||
/* @internal */ moduleAugmentations: StringLiteral[];
|
||||
/* @internal */ imports: ReadonlyArray<StringLiteral>;
|
||||
/* @internal */ moduleAugmentations: ReadonlyArray<StringLiteral>;
|
||||
/* @internal */ patternAmbientModules?: PatternAmbientModule[];
|
||||
/* @internal */ ambientModuleNames: string[];
|
||||
/* @internal */ ambientModuleNames: ReadonlyArray<string>;
|
||||
/* @internal */ checkJsDirective: CheckJsDirective | undefined;
|
||||
}
|
||||
|
||||
@@ -2520,6 +2527,7 @@ namespace ts {
|
||||
* Returns `any` if the index is not valid.
|
||||
*/
|
||||
/* @internal */ getParameterType(signature: Signature, parameterIndex: number): Type;
|
||||
getNullableType(type: Type, flags: TypeFlags): Type;
|
||||
getNonNullableType(type: Type): Type;
|
||||
|
||||
/** Note that the resulting nodes cannot be checked. */
|
||||
@@ -2677,6 +2685,7 @@ namespace ts {
|
||||
SuppressAnyReturnType = 1 << 12, // If the return type is any-like, don't offer a return type.
|
||||
AddUndefined = 1 << 13, // Add undefined to types of initialized, non-optional parameters
|
||||
WriteClassExpressionAsTypeLiteral = 1 << 14, // Write a type literal instead of (Anonymous class)
|
||||
InArrayType = 1 << 15, // Writing an array element type
|
||||
}
|
||||
|
||||
export const enum SymbolFormatFlags {
|
||||
@@ -2982,13 +2991,10 @@ namespace ts {
|
||||
*/
|
||||
export type __String = (string & { __escapedIdentifier: void }) | (void & { __escapedIdentifier: void }) | InternalSymbolName;
|
||||
|
||||
/** EscapedStringMap based on ES6 Map interface. */
|
||||
export interface UnderscoreEscapedMap<T> {
|
||||
/** ReadonlyMap where keys are `__String`s. */
|
||||
export interface ReadonlyUnderscoreEscapedMap<T> {
|
||||
get(key: __String): T | undefined;
|
||||
has(key: __String): boolean;
|
||||
set(key: __String, value: T): this;
|
||||
delete(key: __String): boolean;
|
||||
clear(): void;
|
||||
forEach(action: (value: T, key: __String) => void): void;
|
||||
readonly size: number;
|
||||
keys(): Iterator<__String>;
|
||||
@@ -2996,6 +3002,13 @@ namespace ts {
|
||||
entries(): Iterator<[__String, T]>;
|
||||
}
|
||||
|
||||
/** Map where keys are `__String`s. */
|
||||
export interface UnderscoreEscapedMap<T> extends ReadonlyUnderscoreEscapedMap<T> {
|
||||
set(key: __String, value: T): this;
|
||||
delete(key: __String): boolean;
|
||||
clear(): void;
|
||||
}
|
||||
|
||||
/** SymbolTable based on ES6 Map interface. */
|
||||
export type SymbolTable = UnderscoreEscapedMap<Symbol>;
|
||||
|
||||
|
||||
@@ -640,7 +640,8 @@ namespace ts {
|
||||
const commentRanges = (node.kind === SyntaxKind.Parameter ||
|
||||
node.kind === SyntaxKind.TypeParameter ||
|
||||
node.kind === SyntaxKind.FunctionExpression ||
|
||||
node.kind === SyntaxKind.ArrowFunction) ?
|
||||
node.kind === SyntaxKind.ArrowFunction ||
|
||||
node.kind === SyntaxKind.ParenthesizedExpression) ?
|
||||
concatenate(getTrailingCommentRanges(text, node.pos), getLeadingCommentRanges(text, node.pos)) :
|
||||
getLeadingCommentRangesOfNodeFromText(node, text);
|
||||
// True if the comment starts with '/**' but not if it is '/**/'
|
||||
@@ -1539,27 +1540,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function getJSDocParameterTags(param: ParameterDeclaration): JSDocParameterTag[] | undefined {
|
||||
const func = param.parent;
|
||||
const tags = getJSDocTags(func);
|
||||
if (!tags) return undefined;
|
||||
|
||||
if (!param.name) {
|
||||
// this is an anonymous jsdoc param from a `function(type1, type2): type3` specification
|
||||
const paramIndex = func.parameters.indexOf(param);
|
||||
Debug.assert(paramIndex !== -1);
|
||||
let curParamIndex = 0;
|
||||
for (const tag of tags) {
|
||||
if (isJSDocParameterTag(tag)) {
|
||||
if (curParamIndex === paramIndex) {
|
||||
return [tag];
|
||||
}
|
||||
curParamIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (param.name.kind === SyntaxKind.Identifier) {
|
||||
const name = (param.name as Identifier).text;
|
||||
return tags.filter((tag): tag is JSDocParameterTag => isJSDocParameterTag(tag) && tag.name.text === name) as JSDocParameterTag[];
|
||||
if (param.name && isIdentifier(param.name)) {
|
||||
const name = param.name.text;
|
||||
return getJSDocTags(param.parent).filter((tag): tag is JSDocParameterTag => isJSDocParameterTag(tag) && tag.name.text === name) as JSDocParameterTag[];
|
||||
}
|
||||
else {
|
||||
// TODO: it's a destructured parameter, so it should look up an "object type" series of multiple lines
|
||||
@@ -2748,7 +2731,7 @@ namespace ts {
|
||||
* Gets the effective type parameters. If the node was parsed in a
|
||||
* JavaScript file, gets the type parameters from the `@template` tag from JSDoc.
|
||||
*/
|
||||
export function getEffectiveTypeParameterDeclarations(node: DeclarationWithTypeParameters): TypeParameterDeclaration[] {
|
||||
export function getEffectiveTypeParameterDeclarations(node: DeclarationWithTypeParameters): ReadonlyArray<TypeParameterDeclaration> {
|
||||
if (node.typeParameters) {
|
||||
return node.typeParameters;
|
||||
}
|
||||
@@ -4756,7 +4739,7 @@ namespace ts {
|
||||
// Node Arrays
|
||||
|
||||
/* @internal */
|
||||
export function isNodeArray<T extends Node>(array: T[]): array is NodeArray<T> {
|
||||
export function isNodeArray<T extends Node>(array: ReadonlyArray<T>): array is NodeArray<T> {
|
||||
return array.hasOwnProperty("pos")
|
||||
&& array.hasOwnProperty("end");
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ namespace ts {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
let updated: NodeArray<T>;
|
||||
let updated: MutableNodeArray<T>;
|
||||
|
||||
// Ensure start and count have valid values
|
||||
const length = nodes.length;
|
||||
@@ -901,7 +901,7 @@ namespace ts {
|
||||
*
|
||||
* @param nodes The NodeArray.
|
||||
*/
|
||||
function extractSingleNode(nodes: Node[]): Node {
|
||||
function extractSingleNode(nodes: ReadonlyArray<Node>): Node {
|
||||
Debug.assert(nodes.length <= 1, "Too many nodes written to output.");
|
||||
return singleOrUndefined(nodes);
|
||||
}
|
||||
@@ -1421,13 +1421,13 @@ namespace ts {
|
||||
/**
|
||||
* Merges generated lexical declarations into a new statement list.
|
||||
*/
|
||||
export function mergeLexicalEnvironment(statements: NodeArray<Statement>, declarations: Statement[]): NodeArray<Statement>;
|
||||
export function mergeLexicalEnvironment(statements: NodeArray<Statement>, declarations: ReadonlyArray<Statement>): NodeArray<Statement>;
|
||||
|
||||
/**
|
||||
* Appends generated lexical declarations to an array of statements.
|
||||
*/
|
||||
export function mergeLexicalEnvironment(statements: Statement[], declarations: Statement[]): Statement[];
|
||||
export function mergeLexicalEnvironment(statements: Statement[], declarations: Statement[]) {
|
||||
export function mergeLexicalEnvironment(statements: Statement[], declarations: ReadonlyArray<Statement>): Statement[];
|
||||
export function mergeLexicalEnvironment(statements: Statement[] | NodeArray<Statement>, declarations: ReadonlyArray<Statement>) {
|
||||
if (!some(declarations)) {
|
||||
return statements;
|
||||
}
|
||||
@@ -1442,7 +1442,7 @@ namespace ts {
|
||||
*
|
||||
* @param nodes The NodeArray.
|
||||
*/
|
||||
export function liftToBlock(nodes: Node[]): Statement {
|
||||
export function liftToBlock(nodes: ReadonlyArray<Node>): Statement {
|
||||
Debug.assert(every(nodes, isStatement), "Cannot lift nodes to a Block.");
|
||||
return <Statement>singleOrUndefined(nodes) || createBlock(<NodeArray<Statement>>nodes);
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ namespace FourSlash {
|
||||
// 0 - cancelled
|
||||
// >0 - not cancelled
|
||||
// <0 - not cancelled and value denotes number of isCancellationRequested after which token become cancelled
|
||||
private static NotCanceled: number = -1;
|
||||
private static readonly NotCanceled: number = -1;
|
||||
private numberOfCallsBeforeCancellation: number = TestCancellationToken.NotCanceled;
|
||||
|
||||
public isCancellationRequested(): boolean {
|
||||
|
||||
@@ -108,7 +108,7 @@ namespace Harness.LanguageService {
|
||||
}
|
||||
|
||||
class DefaultHostCancellationToken implements ts.HostCancellationToken {
|
||||
public static Instance = new DefaultHostCancellationToken();
|
||||
public static readonly Instance = new DefaultHostCancellationToken();
|
||||
|
||||
public isCancellationRequested() {
|
||||
return false;
|
||||
|
||||
@@ -238,10 +238,8 @@ namespace RWC {
|
||||
}
|
||||
|
||||
class RWCRunner extends RunnerBase {
|
||||
private static sourcePath = "internal/cases/rwc/";
|
||||
|
||||
public enumerateTestFiles() {
|
||||
return Harness.IO.listFiles(RWCRunner.sourcePath, /.+\.json$/);
|
||||
return Harness.IO.listFiles("internal/cases/rwc/", /.+\.json$/);
|
||||
}
|
||||
|
||||
public kind(): TestRunnerKind {
|
||||
|
||||
@@ -4,19 +4,19 @@
|
||||
/* tslint:disable:no-null-keyword */
|
||||
|
||||
class Test262BaselineRunner extends RunnerBase {
|
||||
private static basePath = "internal/cases/test262";
|
||||
private static helpersFilePath = "tests/cases/test262-harness/helpers.d.ts";
|
||||
private static helperFile: Harness.Compiler.TestFile = {
|
||||
private static readonly basePath = "internal/cases/test262";
|
||||
private static readonly helpersFilePath = "tests/cases/test262-harness/helpers.d.ts";
|
||||
private static readonly helperFile: Harness.Compiler.TestFile = {
|
||||
unitName: Test262BaselineRunner.helpersFilePath,
|
||||
content: Harness.IO.readFile(Test262BaselineRunner.helpersFilePath),
|
||||
};
|
||||
private static testFileExtensionRegex = /\.js$/;
|
||||
private static options: ts.CompilerOptions = {
|
||||
private static readonly testFileExtensionRegex = /\.js$/;
|
||||
private static readonly options: ts.CompilerOptions = {
|
||||
allowNonTsExtensions: true,
|
||||
target: ts.ScriptTarget.Latest,
|
||||
module: ts.ModuleKind.CommonJS
|
||||
};
|
||||
private static baselineOptions: Harness.Baseline.BaselineOptions = {
|
||||
private static readonly baselineOptions: Harness.Baseline.BaselineOptions = {
|
||||
Subfolder: "test262",
|
||||
Baselinefolder: "internal/baselines"
|
||||
};
|
||||
|
||||
@@ -67,12 +67,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
function flattenNodes(n: Node) {
|
||||
const data: (Node | NodeArray<any>)[] = [];
|
||||
const data: (Node | NodeArray<Node>)[] = [];
|
||||
walk(n);
|
||||
return data;
|
||||
|
||||
function walk(n: Node | Node[]): void {
|
||||
data.push(<any>n);
|
||||
function walk(n: Node | NodeArray<Node>): void {
|
||||
data.push(n);
|
||||
return isArray(n) ? forEach(n, walk) : forEachChild(n, walk, walk);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -704,7 +704,7 @@ namespace ts.projectSystem {
|
||||
}
|
||||
|
||||
clearOutput() {
|
||||
this.output.length = 0;
|
||||
clear(this.output);
|
||||
}
|
||||
|
||||
readonly readFile = (s: string) => (<File>this.fs.get(this.toFullPath(s))).content;
|
||||
|
||||
@@ -223,7 +223,7 @@ namespace ts.server {
|
||||
for (const reference of this.references) {
|
||||
reference.removeReferencedBy(this);
|
||||
}
|
||||
this.references = createSortedArray<ModuleBuilderFileInfo>();
|
||||
clear(this.references);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -225,10 +225,7 @@ namespace ts.server {
|
||||
const fileNamePropertyReader: FilePropertyReader<string> = {
|
||||
getFileName: x => x,
|
||||
getScriptKind: _ => undefined,
|
||||
hasMixedContent: (fileName, extraFileExtensions) => {
|
||||
const mixedContentExtensions = map(filter(extraFileExtensions, item => item.isMixedContent), item => item.extension);
|
||||
return forEach(mixedContentExtensions, extension => fileExtensionIs(fileName, extension));
|
||||
}
|
||||
hasMixedContent: (fileName, extraFileExtensions) => some(extraFileExtensions, ext => ext.isMixedContent && fileExtensionIs(fileName, ext.extension)),
|
||||
};
|
||||
|
||||
const externalFilePropertyReader: FilePropertyReader<protocol.ExternalFile> = {
|
||||
@@ -725,7 +722,7 @@ namespace ts.server {
|
||||
|
||||
switch (project.projectKind) {
|
||||
case ProjectKind.External:
|
||||
removeItemFromSet(this.externalProjects, <ExternalProject>project);
|
||||
unorderedRemoveItem(this.externalProjects, <ExternalProject>project);
|
||||
this.projectToSizeMap.delete((project as ExternalProject).externalProjectName);
|
||||
break;
|
||||
case ProjectKind.Configured:
|
||||
@@ -734,7 +731,7 @@ namespace ts.server {
|
||||
this.setConfigFilePresenceByClosedConfigFile(<ConfiguredProject>project);
|
||||
break;
|
||||
case ProjectKind.Inferred:
|
||||
removeItemFromSet(this.inferredProjects, <InferredProject>project);
|
||||
unorderedRemoveItem(this.inferredProjects, <InferredProject>project);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -793,7 +790,7 @@ namespace ts.server {
|
||||
info.close();
|
||||
this.stopWatchingConfigFilesForClosedScriptInfo(info);
|
||||
|
||||
removeItemFromSet(this.openFiles, info);
|
||||
unorderedRemoveItem(this.openFiles, info);
|
||||
|
||||
// collect all projects that should be removed
|
||||
let projectsToRemove: Project[];
|
||||
@@ -1896,7 +1893,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
/** Makes a filename safe to insert in a RegExp */
|
||||
private static filenameEscapeRegexp = /[-\/\\^$*+?.()|[\]{}]/g;
|
||||
private static readonly filenameEscapeRegexp = /[-\/\\^$*+?.()|[\]{}]/g;
|
||||
private static escapeFilenameForRegex(filename: string) {
|
||||
return filename.replace(this.filenameEscapeRegexp, "\\$&");
|
||||
}
|
||||
|
||||
@@ -876,7 +876,7 @@ namespace ts.server {
|
||||
*/
|
||||
export class InferredProject extends Project {
|
||||
|
||||
private static newName = (() => {
|
||||
private static readonly newName = (() => {
|
||||
let nextId = 1;
|
||||
return () => {
|
||||
const id = nextId;
|
||||
|
||||
@@ -232,7 +232,7 @@ namespace ts.server {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
removeItemFromSet(this.containingProjects, project);
|
||||
unorderedRemoveItem(this.containingProjects, project);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -251,7 +251,7 @@ namespace ts.server {
|
||||
p.addMissingFileRoot(this.fileName);
|
||||
}
|
||||
}
|
||||
this.containingProjects.length = 0;
|
||||
clear(this.containingProjects);
|
||||
}
|
||||
|
||||
getDefaultProject() {
|
||||
|
||||
+5
-11
@@ -162,19 +162,13 @@ namespace ts.server {
|
||||
* Represents operation that can schedule its next step to be executed later.
|
||||
* Scheduling is done via instance of NextStep. If on current step subsequent step was not scheduled - operation is assumed to be completed.
|
||||
*/
|
||||
class MultistepOperation {
|
||||
class MultistepOperation implements NextStep {
|
||||
private requestId: number;
|
||||
private timerHandle: any;
|
||||
private immediateId: any;
|
||||
private completed = true;
|
||||
private readonly next: NextStep;
|
||||
|
||||
constructor(private readonly operationHost: MultistepOperationHost) {
|
||||
this.next = {
|
||||
immediate: action => this.immediate(action),
|
||||
delay: (ms, action) => this.delay(ms, action)
|
||||
};
|
||||
}
|
||||
constructor(private readonly operationHost: MultistepOperationHost) {}
|
||||
|
||||
public startNew(action: (next: NextStep) => void) {
|
||||
this.complete();
|
||||
@@ -194,7 +188,7 @@ namespace ts.server {
|
||||
this.setImmediateId(undefined);
|
||||
}
|
||||
|
||||
private immediate(action: () => void) {
|
||||
public immediate(action: () => void) {
|
||||
const requestId = this.requestId;
|
||||
Debug.assert(requestId === this.operationHost.getCurrentRequestId(), "immediate: incorrect request id");
|
||||
this.setImmediateId(this.operationHost.getServerHost().setImmediate(() => {
|
||||
@@ -203,7 +197,7 @@ namespace ts.server {
|
||||
}));
|
||||
}
|
||||
|
||||
private delay(ms: number, action: () => void) {
|
||||
public delay(ms: number, action: () => void) {
|
||||
const requestId = this.requestId;
|
||||
Debug.assert(requestId === this.operationHost.getCurrentRequestId(), "delay: incorrect request id");
|
||||
this.setTimerHandle(this.operationHost.getServerHost().setTimeout(() => {
|
||||
@@ -219,7 +213,7 @@ namespace ts.server {
|
||||
stop = true;
|
||||
}
|
||||
else {
|
||||
action(this.next);
|
||||
action(this);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
|
||||
@@ -103,24 +103,6 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
export function removeItemFromSet<T>(items: T[], itemToRemove: T) {
|
||||
if (items.length === 0) {
|
||||
return;
|
||||
}
|
||||
const index = items.indexOf(itemToRemove);
|
||||
if (index < 0) {
|
||||
return;
|
||||
}
|
||||
if (index === items.length - 1) {
|
||||
// last item - pop it
|
||||
items.pop();
|
||||
}
|
||||
else {
|
||||
// non-last item - replace it with the last one
|
||||
items[index] = items.pop();
|
||||
}
|
||||
}
|
||||
|
||||
export type NormalizedPath = string & { __normalizedPathTag: any };
|
||||
|
||||
export function toNormalizedPath(fileName: string): NormalizedPath {
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace ts.codefix {
|
||||
}
|
||||
}
|
||||
|
||||
// If all fails, add an extra new line immediatlly before the error span.
|
||||
// If all fails, add an extra new line immediately before the error span.
|
||||
return {
|
||||
span: { start: position, length: 0 },
|
||||
newText: `${position === startPosition ? "" : newLineCharacter}// @ts-ignore${newLineCharacter}`
|
||||
@@ -67,4 +67,4 @@ namespace ts.codefix {
|
||||
}]
|
||||
}];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/* @internal */
|
||||
namespace ts.codefix {
|
||||
registerCodeFix({
|
||||
errorCodes: [Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments.code],
|
||||
getCodeActions: getActionsForJSDocTypes
|
||||
});
|
||||
|
||||
function getActionsForJSDocTypes(context: CodeFixContext): CodeAction[] | undefined {
|
||||
const sourceFile = context.sourceFile;
|
||||
const node = getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false);
|
||||
const decl = ts.findAncestor(node, n => n.kind === SyntaxKind.VariableDeclaration);
|
||||
if (!decl) return;
|
||||
const checker = context.program.getTypeChecker();
|
||||
|
||||
const jsdocType = (decl as VariableDeclaration).type;
|
||||
const original = getTextOfNode(jsdocType);
|
||||
const type = checker.getTypeFromTypeNode(jsdocType);
|
||||
const actions = [createAction(jsdocType, sourceFile.fileName, original, checker.typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.NoTruncation))];
|
||||
if (jsdocType.kind === SyntaxKind.JSDocNullableType) {
|
||||
// for nullable types, suggest the flow-compatible `T | null | undefined`
|
||||
// in addition to the jsdoc/closure-compatible `T | null`
|
||||
const replacementWithUndefined = checker.typeToString(checker.getNullableType(type, TypeFlags.Undefined), /*enclosingDeclaration*/ undefined, TypeFormatFlags.NoTruncation);
|
||||
actions.push(createAction(jsdocType, sourceFile.fileName, original, replacementWithUndefined));
|
||||
}
|
||||
return actions;
|
||||
}
|
||||
|
||||
function createAction(declaration: TypeNode, fileName: string, original: string, replacement: string): CodeAction {
|
||||
return {
|
||||
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Change_0_to_1), [original, replacement]),
|
||||
changes: [{
|
||||
fileName,
|
||||
textChanges: [{
|
||||
span: { start: declaration.getStart(), length: declaration.getWidth() },
|
||||
newText: replacement
|
||||
}]
|
||||
}],
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
/// <reference path="fixExtendsInterfaceBecomesImplements.ts" />
|
||||
/// <reference path="fixForgottenThisPropertyAccess.ts" />
|
||||
/// <reference path='fixUnusedIdentifier.ts' />
|
||||
/// <reference path='fixJSDocTypes.ts' />
|
||||
/// <reference path='importFixes.ts' />
|
||||
/// <reference path='disableJsDiagnostics.ts' />
|
||||
/// <reference path='helpers.ts' />
|
||||
|
||||
@@ -186,7 +186,7 @@ namespace ts.codefix {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
function createMethodImplementingSignatures(signatures: Signature[], name: PropertyName, optional: boolean, modifiers: Modifier[] | undefined): MethodDeclaration {
|
||||
function createMethodImplementingSignatures(signatures: ReadonlyArray<Signature>, name: PropertyName, optional: boolean, modifiers: ReadonlyArray<Modifier> | undefined): MethodDeclaration {
|
||||
/** This is *a* signature with the maximal number of arguments,
|
||||
* such that if there is a "maximal" signature without rest arguments,
|
||||
* this is one of them.
|
||||
@@ -231,7 +231,13 @@ namespace ts.codefix {
|
||||
/*returnType*/ undefined);
|
||||
}
|
||||
|
||||
export function createStubbedMethod(modifiers: Modifier[], name: PropertyName, optional: boolean, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], returnType: TypeNode | undefined) {
|
||||
export function createStubbedMethod(
|
||||
modifiers: ReadonlyArray<Modifier>,
|
||||
name: PropertyName,
|
||||
optional: boolean,
|
||||
typeParameters: ReadonlyArray<TypeParameterDeclaration> | undefined,
|
||||
parameters: ReadonlyArray<ParameterDeclaration>,
|
||||
returnType: TypeNode | undefined) {
|
||||
return createMethod(
|
||||
/*decorators*/ undefined,
|
||||
modifiers,
|
||||
|
||||
+23
-11
@@ -963,7 +963,7 @@ namespace ts.Completions {
|
||||
isMemberCompletion = true;
|
||||
|
||||
let typeMembers: Symbol[];
|
||||
let existingMembers: Declaration[];
|
||||
let existingMembers: ReadonlyArray<Declaration>;
|
||||
|
||||
if (objectLikeContainer.kind === SyntaxKind.ObjectLiteralExpression) {
|
||||
// We are completing on contextual types, but may also include properties
|
||||
@@ -1093,14 +1093,14 @@ namespace ts.Completions {
|
||||
}
|
||||
}
|
||||
const implementedInterfaceTypePropertySymbols = (classElementModifierFlags & ModifierFlags.Static) ?
|
||||
undefined :
|
||||
flatMap(implementsTypeNodes, typeNode => typeChecker.getPropertiesOfType(typeChecker.getTypeAtLocation(typeNode)));
|
||||
emptyArray :
|
||||
flatMap(implementsTypeNodes || emptyArray, typeNode => typeChecker.getPropertiesOfType(typeChecker.getTypeAtLocation(typeNode)));
|
||||
|
||||
// List of property symbols of base type that are not private and already implemented
|
||||
symbols = filterClassMembersList(
|
||||
baseClassTypeToGetPropertiesFrom ?
|
||||
typeChecker.getPropertiesOfType(baseClassTypeToGetPropertiesFrom) :
|
||||
undefined,
|
||||
emptyArray,
|
||||
implementedInterfaceTypePropertySymbols,
|
||||
classLikeDeclaration.members,
|
||||
classElementModifierFlags);
|
||||
@@ -1443,7 +1443,7 @@ namespace ts.Completions {
|
||||
* @returns Symbols to be suggested at an import/export clause, barring those whose named imports/exports
|
||||
* do not occur at the current position and have not otherwise been typed.
|
||||
*/
|
||||
function filterNamedImportOrExportCompletionItems(exportsOfModule: Symbol[], namedImportsOrExports: ImportOrExportSpecifier[]): Symbol[] {
|
||||
function filterNamedImportOrExportCompletionItems(exportsOfModule: Symbol[], namedImportsOrExports: ReadonlyArray<ImportOrExportSpecifier>): Symbol[] {
|
||||
const existingImportsOrExports = createUnderscoreEscapedMap<boolean>();
|
||||
|
||||
for (const element of namedImportsOrExports) {
|
||||
@@ -1469,7 +1469,7 @@ namespace ts.Completions {
|
||||
* @returns Symbols to be suggested in an object binding pattern or object literal expression, barring those whose declarations
|
||||
* do not occur at the current position and have not otherwise been typed.
|
||||
*/
|
||||
function filterObjectMembersList(contextualMemberSymbols: Symbol[], existingMembers: Declaration[]): Symbol[] {
|
||||
function filterObjectMembersList(contextualMemberSymbols: Symbol[], existingMembers: ReadonlyArray<Declaration>): Symbol[] {
|
||||
if (!existingMembers || existingMembers.length === 0) {
|
||||
return contextualMemberSymbols;
|
||||
}
|
||||
@@ -1518,7 +1518,11 @@ namespace ts.Completions {
|
||||
*
|
||||
* @returns Symbols to be suggested in an class element depending on existing memebers and symbol flags
|
||||
*/
|
||||
function filterClassMembersList(baseSymbols: Symbol[], implementingTypeSymbols: Symbol[], existingMembers: ClassElement[], currentClassElementModifierFlags: ModifierFlags): Symbol[] {
|
||||
function filterClassMembersList(
|
||||
baseSymbols: ReadonlyArray<Symbol>,
|
||||
implementingTypeSymbols: ReadonlyArray<Symbol>,
|
||||
existingMembers: ReadonlyArray<ClassElement>,
|
||||
currentClassElementModifierFlags: ModifierFlags): Symbol[] {
|
||||
const existingMemberNames = createUnderscoreEscapedMap<boolean>();
|
||||
for (const m of existingMembers) {
|
||||
// Ignore omitted expressions for missing members
|
||||
@@ -1553,10 +1557,18 @@ namespace ts.Completions {
|
||||
}
|
||||
}
|
||||
|
||||
return concatenate(
|
||||
filter(baseSymbols, baseProperty => isValidProperty(baseProperty, ModifierFlags.Private)),
|
||||
filter(implementingTypeSymbols, implementingProperty => isValidProperty(implementingProperty, ModifierFlags.NonPublicAccessibilityModifier))
|
||||
);
|
||||
const result: Symbol[] = [];
|
||||
addPropertySymbols(baseSymbols, ModifierFlags.Private);
|
||||
addPropertySymbols(implementingTypeSymbols, ModifierFlags.NonPublicAccessibilityModifier);
|
||||
return result;
|
||||
|
||||
function addPropertySymbols(properties: ReadonlyArray<Symbol>, inValidModifierFlags: ModifierFlags) {
|
||||
for (const property of properties) {
|
||||
if (isValidProperty(property, inValidModifierFlags)) {
|
||||
result.push(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isValidProperty(propertySymbol: Symbol, inValidModifierFlags: ModifierFlags) {
|
||||
return !existingMemberNames.get(propertySymbol.name) &&
|
||||
|
||||
@@ -298,21 +298,20 @@ namespace ts.DocumentHighlights {
|
||||
const keywords: Node[] = [];
|
||||
const modifierFlag: ModifierFlags = getFlagFromModifier(modifier);
|
||||
|
||||
let nodes: Node[];
|
||||
let nodes: ReadonlyArray<Node>;
|
||||
switch (container.kind) {
|
||||
case SyntaxKind.ModuleBlock:
|
||||
case SyntaxKind.SourceFile:
|
||||
// Container is either a class declaration or the declaration is a classDeclaration
|
||||
if (modifierFlag & ModifierFlags.Abstract) {
|
||||
nodes = (<Node[]>(<ClassDeclaration>declaration).members).concat(declaration);
|
||||
nodes = [...(<ClassDeclaration>declaration).members, declaration];
|
||||
}
|
||||
else {
|
||||
nodes = (<Block>container).statements;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.Constructor:
|
||||
nodes = (<Node[]>(<ConstructorDeclaration>container).parameters).concat(
|
||||
(<ClassDeclaration>container.parent).members);
|
||||
nodes = [...(<ConstructorDeclaration>container).parameters, ...(<ClassDeclaration>container.parent).members];
|
||||
break;
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.ClassExpression:
|
||||
@@ -326,11 +325,11 @@ namespace ts.DocumentHighlights {
|
||||
});
|
||||
|
||||
if (constructor) {
|
||||
nodes = nodes.concat(constructor.parameters);
|
||||
nodes = [...nodes, ...constructor.parameters];
|
||||
}
|
||||
}
|
||||
else if (modifierFlag & ModifierFlags.Abstract) {
|
||||
nodes = nodes.concat(container);
|
||||
nodes = [...nodes, container];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -1152,7 +1152,7 @@ namespace ts.formatting {
|
||||
}
|
||||
}
|
||||
|
||||
function getOpenTokenForList(node: Node, list: Node[]) {
|
||||
function getOpenTokenForList(node: Node, list: ReadonlyArray<Node>) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.Constructor:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
namespace ts.formatting {
|
||||
|
||||
export class RuleOperationContext {
|
||||
private customContextChecks: { (context: FormattingContext): boolean; }[];
|
||||
private readonly customContextChecks: { (context: FormattingContext): boolean; }[];
|
||||
|
||||
constructor(...funcs: { (context: FormattingContext): boolean; }[]) {
|
||||
this.customContextChecks = funcs;
|
||||
}
|
||||
|
||||
static Any: RuleOperationContext = new RuleOperationContext();
|
||||
static readonly Any: RuleOperationContext = new RuleOperationContext();
|
||||
|
||||
public IsAny(): boolean {
|
||||
return this === RuleOperationContext.Any;
|
||||
|
||||
@@ -328,7 +328,7 @@ namespace ts.formatting {
|
||||
const containingList = getContainingList(node, sourceFile);
|
||||
return containingList ? getActualIndentationFromList(containingList) : Value.Unknown;
|
||||
|
||||
function getActualIndentationFromList(list: Node[]): number {
|
||||
function getActualIndentationFromList(list: ReadonlyArray<Node>): number {
|
||||
const index = indexOf(list, node);
|
||||
return index !== -1 ? deriveActualIndentationFromList(list, index, sourceFile, options) : Value.Unknown;
|
||||
}
|
||||
@@ -378,7 +378,7 @@ namespace ts.formatting {
|
||||
}
|
||||
}
|
||||
|
||||
function deriveActualIndentationFromList(list: Node[], index: number, sourceFile: SourceFile, options: EditorSettings): number {
|
||||
function deriveActualIndentationFromList(list: ReadonlyArray<Node>, index: number, sourceFile: SourceFile, options: EditorSettings): number {
|
||||
Debug.assert(index >= 0 && index < list.length);
|
||||
const node = list[index];
|
||||
|
||||
|
||||
@@ -191,7 +191,7 @@ namespace ts.GoToDefinition {
|
||||
return false;
|
||||
}
|
||||
|
||||
function tryAddSignature(signatureDeclarations: Declaration[] | undefined, selectConstructors: boolean, symbolKind: ScriptElementKind, symbolName: string, containerName: string, result: DefinitionInfo[]) {
|
||||
function tryAddSignature(signatureDeclarations: ReadonlyArray<Declaration> | undefined, selectConstructors: boolean, symbolKind: ScriptElementKind, symbolName: string, containerName: string, result: DefinitionInfo[]) {
|
||||
if (!signatureDeclarations) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -241,7 +241,7 @@ namespace ts.JsDoc {
|
||||
return { newText: result, caretOffset: preamble.length };
|
||||
}
|
||||
|
||||
function getParametersForJsDocOwningNode(commentOwner: Node): ParameterDeclaration[] {
|
||||
function getParametersForJsDocOwningNode(commentOwner: Node): ReadonlyArray<ParameterDeclaration> {
|
||||
if (isFunctionLike(commentOwner)) {
|
||||
return commentOwner.parameters;
|
||||
}
|
||||
@@ -266,7 +266,7 @@ namespace ts.JsDoc {
|
||||
* @param rightHandSide the expression which may contain an appropriate set of parameters
|
||||
* @returns the parameters of a signature found on the RHS if one exists; otherwise 'emptyArray'.
|
||||
*/
|
||||
function getParametersFromRightHandSideOfAssignment(rightHandSide: Expression): ParameterDeclaration[] {
|
||||
function getParametersFromRightHandSideOfAssignment(rightHandSide: Expression): ReadonlyArray<ParameterDeclaration> {
|
||||
while (rightHandSide.kind === SyntaxKind.ParenthesizedExpression) {
|
||||
rightHandSide = (<ParenthesizedExpression>rightHandSide).expression;
|
||||
}
|
||||
|
||||
@@ -1176,7 +1176,7 @@ namespace ts {
|
||||
|
||||
public close(): void {
|
||||
// Forget all the registered shims
|
||||
this._shims = [];
|
||||
clear(this._shims);
|
||||
this.documentRegistry = undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
///<reference path='services.ts' />
|
||||
/* @internal */
|
||||
namespace ts.SignatureHelp {
|
||||
const emptyArray: any[] = [];
|
||||
|
||||
export const enum ArgumentListKind {
|
||||
TypeArguments,
|
||||
CallArguments,
|
||||
|
||||
@@ -18,13 +18,13 @@ interface IHasVisualizationModel {
|
||||
var xs: IHasVisualizationModel[] = [moduleA];
|
||||
>xs : IHasVisualizationModel[]
|
||||
>IHasVisualizationModel : IHasVisualizationModel
|
||||
>[moduleA] : typeof moduleA[]
|
||||
>[moduleA] : (typeof moduleA)[]
|
||||
>moduleA : typeof moduleA
|
||||
|
||||
var xs2: typeof moduleA[] = [moduleA];
|
||||
>xs2 : typeof moduleA[]
|
||||
>xs2 : (typeof moduleA)[]
|
||||
>moduleA : typeof moduleA
|
||||
>[moduleA] : typeof moduleA[]
|
||||
>[moduleA] : (typeof moduleA)[]
|
||||
>moduleA : typeof moduleA
|
||||
|
||||
=== tests/cases/compiler/aliasUsageInArray_backbone.ts ===
|
||||
|
||||
@@ -22,8 +22,8 @@ class C {
|
||||
>foo : string
|
||||
}
|
||||
var y = [C, C];
|
||||
>y : typeof C[]
|
||||
>[C, C] : typeof C[]
|
||||
>y : (typeof C)[]
|
||||
>[C, C] : (typeof C)[]
|
||||
>C : typeof C
|
||||
>C : typeof C
|
||||
|
||||
@@ -31,7 +31,7 @@ var r3 = new y[0]();
|
||||
>r3 : C
|
||||
>new y[0]() : C
|
||||
>y[0] : typeof C
|
||||
>y : typeof C[]
|
||||
>y : (typeof C)[]
|
||||
>0 : 0
|
||||
|
||||
var a: { (x: number): number; (x: string): string; };
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
=== tests/cases/conformance/types/thisType/context.js ===
|
||||
const obj = {
|
||||
>obj : Symbol(obj, Decl(context.js, 0, 5))
|
||||
|
||||
prop: 2,
|
||||
>prop : Symbol(prop, Decl(context.js, 0, 13))
|
||||
|
||||
method() {
|
||||
>method : Symbol(method, Decl(context.js, 1, 12))
|
||||
|
||||
this;
|
||||
>this : Symbol(obj, Decl(context.js, 0, 11))
|
||||
|
||||
this.prop;
|
||||
>this.prop : Symbol(prop, Decl(context.js, 0, 13))
|
||||
>this : Symbol(obj, Decl(context.js, 0, 11))
|
||||
>prop : Symbol(prop, Decl(context.js, 0, 13))
|
||||
|
||||
this.method;
|
||||
>this.method : Symbol(method, Decl(context.js, 1, 12))
|
||||
>this : Symbol(obj, Decl(context.js, 0, 11))
|
||||
>method : Symbol(method, Decl(context.js, 1, 12))
|
||||
|
||||
this.unknown; // ok, obj has a string indexer
|
||||
>this : Symbol(obj, Decl(context.js, 0, 11))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
=== tests/cases/conformance/types/thisType/context.js ===
|
||||
const obj = {
|
||||
>obj : { [x: string]: any; prop: number; method(): void; }
|
||||
>{ prop: 2, method() { this; this.prop; this.method; this.unknown; // ok, obj has a string indexer }} : { [x: string]: any; prop: number; method(): void; }
|
||||
|
||||
prop: 2,
|
||||
>prop : number
|
||||
>2 : 2
|
||||
|
||||
method() {
|
||||
>method : () => void
|
||||
|
||||
this;
|
||||
>this : { [x: string]: any; prop: number; method(): void; }
|
||||
|
||||
this.prop;
|
||||
>this.prop : number
|
||||
>this : { [x: string]: any; prop: number; method(): void; }
|
||||
>prop : number
|
||||
|
||||
this.method;
|
||||
>this.method : () => void
|
||||
>this : { [x: string]: any; prop: number; method(): void; }
|
||||
>method : () => void
|
||||
|
||||
this.unknown; // ok, obj has a string indexer
|
||||
>this.unknown : any
|
||||
>this : { [x: string]: any; prop: number; method(): void; }
|
||||
>unknown : any
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
=== tests/cases/compiler/declarationEmitIndexTypeArray.ts ===
|
||||
function doSomethingWithKeys<T>(...keys: (keyof T)[]) { }
|
||||
>doSomethingWithKeys : <T>(...keys: keyof T[]) => void
|
||||
>doSomethingWithKeys : <T>(...keys: (keyof T)[]) => void
|
||||
>T : T
|
||||
>keys : keyof T[]
|
||||
>keys : (keyof T)[]
|
||||
>T : T
|
||||
|
||||
const utilityFunctions = {
|
||||
>utilityFunctions : { doSomethingWithKeys: <T>(...keys: keyof T[]) => void; }
|
||||
>{ doSomethingWithKeys} : { doSomethingWithKeys: <T>(...keys: keyof T[]) => void; }
|
||||
>utilityFunctions : { doSomethingWithKeys: <T>(...keys: (keyof T)[]) => void; }
|
||||
>{ doSomethingWithKeys} : { doSomethingWithKeys: <T>(...keys: (keyof T)[]) => void; }
|
||||
|
||||
doSomethingWithKeys
|
||||
>doSomethingWithKeys : <T>(...keys: keyof T[]) => void
|
||||
>doSomethingWithKeys : <T>(...keys: (keyof T)[]) => void
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
//// [destructuringTypeGuardFlow.ts]
|
||||
type foo = {
|
||||
bar: number | null;
|
||||
baz: string;
|
||||
nested: {
|
||||
a: number;
|
||||
b: string | null;
|
||||
}
|
||||
};
|
||||
|
||||
const aFoo: foo = { bar: 3, baz: "b", nested: { a: 1, b: "y" } };
|
||||
|
||||
if (aFoo.bar && aFoo.nested.b) {
|
||||
const { bar, baz, nested: {a, b: text} } = aFoo;
|
||||
const right: number = aFoo.bar;
|
||||
const wrong: number = bar;
|
||||
const another: string = baz;
|
||||
const aAgain: number = a;
|
||||
const bAgain: string = text;
|
||||
}
|
||||
|
||||
type bar = {
|
||||
elem1: number | null;
|
||||
elem2: foo | null;
|
||||
};
|
||||
|
||||
const bBar = { elem1: 7, elem2: aFoo };
|
||||
|
||||
if (bBar.elem2 && bBar.elem2.bar && bBar.elem2.nested.b) {
|
||||
const { bar, baz, nested: {a, b: text} } = bBar.elem2;
|
||||
const right: number = bBar.elem2.bar;
|
||||
const wrong: number = bar;
|
||||
const another: string = baz;
|
||||
const aAgain: number = a;
|
||||
const bAgain: string = text;
|
||||
}
|
||||
|
||||
|
||||
//// [destructuringTypeGuardFlow.js]
|
||||
var aFoo = { bar: 3, baz: "b", nested: { a: 1, b: "y" } };
|
||||
if (aFoo.bar && aFoo.nested.b) {
|
||||
var bar = aFoo.bar, baz = aFoo.baz, _a = aFoo.nested, a = _a.a, text = _a.b;
|
||||
var right = aFoo.bar;
|
||||
var wrong = bar;
|
||||
var another = baz;
|
||||
var aAgain = a;
|
||||
var bAgain = text;
|
||||
}
|
||||
var bBar = { elem1: 7, elem2: aFoo };
|
||||
if (bBar.elem2 && bBar.elem2.bar && bBar.elem2.nested.b) {
|
||||
var _b = bBar.elem2, bar = _b.bar, baz = _b.baz, _c = _b.nested, a = _c.a, text = _c.b;
|
||||
var right = bBar.elem2.bar;
|
||||
var wrong = bar;
|
||||
var another = baz;
|
||||
var aAgain = a;
|
||||
var bAgain = text;
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
=== tests/cases/compiler/destructuringTypeGuardFlow.ts ===
|
||||
type foo = {
|
||||
>foo : Symbol(foo, Decl(destructuringTypeGuardFlow.ts, 0, 0))
|
||||
|
||||
bar: number | null;
|
||||
>bar : Symbol(bar, Decl(destructuringTypeGuardFlow.ts, 0, 12))
|
||||
|
||||
baz: string;
|
||||
>baz : Symbol(baz, Decl(destructuringTypeGuardFlow.ts, 1, 21))
|
||||
|
||||
nested: {
|
||||
>nested : Symbol(nested, Decl(destructuringTypeGuardFlow.ts, 2, 14))
|
||||
|
||||
a: number;
|
||||
>a : Symbol(a, Decl(destructuringTypeGuardFlow.ts, 3, 11))
|
||||
|
||||
b: string | null;
|
||||
>b : Symbol(b, Decl(destructuringTypeGuardFlow.ts, 4, 14))
|
||||
}
|
||||
};
|
||||
|
||||
const aFoo: foo = { bar: 3, baz: "b", nested: { a: 1, b: "y" } };
|
||||
>aFoo : Symbol(aFoo, Decl(destructuringTypeGuardFlow.ts, 9, 5))
|
||||
>foo : Symbol(foo, Decl(destructuringTypeGuardFlow.ts, 0, 0))
|
||||
>bar : Symbol(bar, Decl(destructuringTypeGuardFlow.ts, 9, 19))
|
||||
>baz : Symbol(baz, Decl(destructuringTypeGuardFlow.ts, 9, 27))
|
||||
>nested : Symbol(nested, Decl(destructuringTypeGuardFlow.ts, 9, 37))
|
||||
>a : Symbol(a, Decl(destructuringTypeGuardFlow.ts, 9, 47))
|
||||
>b : Symbol(b, Decl(destructuringTypeGuardFlow.ts, 9, 53))
|
||||
|
||||
if (aFoo.bar && aFoo.nested.b) {
|
||||
>aFoo.bar : Symbol(bar, Decl(destructuringTypeGuardFlow.ts, 0, 12))
|
||||
>aFoo : Symbol(aFoo, Decl(destructuringTypeGuardFlow.ts, 9, 5))
|
||||
>bar : Symbol(bar, Decl(destructuringTypeGuardFlow.ts, 0, 12))
|
||||
>aFoo.nested.b : Symbol(b, Decl(destructuringTypeGuardFlow.ts, 4, 14))
|
||||
>aFoo.nested : Symbol(nested, Decl(destructuringTypeGuardFlow.ts, 2, 14))
|
||||
>aFoo : Symbol(aFoo, Decl(destructuringTypeGuardFlow.ts, 9, 5))
|
||||
>nested : Symbol(nested, Decl(destructuringTypeGuardFlow.ts, 2, 14))
|
||||
>b : Symbol(b, Decl(destructuringTypeGuardFlow.ts, 4, 14))
|
||||
|
||||
const { bar, baz, nested: {a, b: text} } = aFoo;
|
||||
>bar : Symbol(bar, Decl(destructuringTypeGuardFlow.ts, 12, 9))
|
||||
>baz : Symbol(baz, Decl(destructuringTypeGuardFlow.ts, 12, 14))
|
||||
>nested : Symbol(nested, Decl(destructuringTypeGuardFlow.ts, 2, 14))
|
||||
>a : Symbol(a, Decl(destructuringTypeGuardFlow.ts, 12, 29))
|
||||
>b : Symbol(b, Decl(destructuringTypeGuardFlow.ts, 4, 14))
|
||||
>text : Symbol(text, Decl(destructuringTypeGuardFlow.ts, 12, 31))
|
||||
>aFoo : Symbol(aFoo, Decl(destructuringTypeGuardFlow.ts, 9, 5))
|
||||
|
||||
const right: number = aFoo.bar;
|
||||
>right : Symbol(right, Decl(destructuringTypeGuardFlow.ts, 13, 7))
|
||||
>aFoo.bar : Symbol(bar, Decl(destructuringTypeGuardFlow.ts, 0, 12))
|
||||
>aFoo : Symbol(aFoo, Decl(destructuringTypeGuardFlow.ts, 9, 5))
|
||||
>bar : Symbol(bar, Decl(destructuringTypeGuardFlow.ts, 0, 12))
|
||||
|
||||
const wrong: number = bar;
|
||||
>wrong : Symbol(wrong, Decl(destructuringTypeGuardFlow.ts, 14, 7))
|
||||
>bar : Symbol(bar, Decl(destructuringTypeGuardFlow.ts, 12, 9))
|
||||
|
||||
const another: string = baz;
|
||||
>another : Symbol(another, Decl(destructuringTypeGuardFlow.ts, 15, 7))
|
||||
>baz : Symbol(baz, Decl(destructuringTypeGuardFlow.ts, 12, 14))
|
||||
|
||||
const aAgain: number = a;
|
||||
>aAgain : Symbol(aAgain, Decl(destructuringTypeGuardFlow.ts, 16, 7))
|
||||
>a : Symbol(a, Decl(destructuringTypeGuardFlow.ts, 12, 29))
|
||||
|
||||
const bAgain: string = text;
|
||||
>bAgain : Symbol(bAgain, Decl(destructuringTypeGuardFlow.ts, 17, 7))
|
||||
>text : Symbol(text, Decl(destructuringTypeGuardFlow.ts, 12, 31))
|
||||
}
|
||||
|
||||
type bar = {
|
||||
>bar : Symbol(bar, Decl(destructuringTypeGuardFlow.ts, 18, 1))
|
||||
|
||||
elem1: number | null;
|
||||
>elem1 : Symbol(elem1, Decl(destructuringTypeGuardFlow.ts, 20, 12))
|
||||
|
||||
elem2: foo | null;
|
||||
>elem2 : Symbol(elem2, Decl(destructuringTypeGuardFlow.ts, 21, 23))
|
||||
>foo : Symbol(foo, Decl(destructuringTypeGuardFlow.ts, 0, 0))
|
||||
|
||||
};
|
||||
|
||||
const bBar = { elem1: 7, elem2: aFoo };
|
||||
>bBar : Symbol(bBar, Decl(destructuringTypeGuardFlow.ts, 25, 5))
|
||||
>elem1 : Symbol(elem1, Decl(destructuringTypeGuardFlow.ts, 25, 14))
|
||||
>elem2 : Symbol(elem2, Decl(destructuringTypeGuardFlow.ts, 25, 24))
|
||||
>aFoo : Symbol(aFoo, Decl(destructuringTypeGuardFlow.ts, 9, 5))
|
||||
|
||||
if (bBar.elem2 && bBar.elem2.bar && bBar.elem2.nested.b) {
|
||||
>bBar.elem2 : Symbol(elem2, Decl(destructuringTypeGuardFlow.ts, 25, 24))
|
||||
>bBar : Symbol(bBar, Decl(destructuringTypeGuardFlow.ts, 25, 5))
|
||||
>elem2 : Symbol(elem2, Decl(destructuringTypeGuardFlow.ts, 25, 24))
|
||||
>bBar.elem2.bar : Symbol(bar, Decl(destructuringTypeGuardFlow.ts, 0, 12))
|
||||
>bBar.elem2 : Symbol(elem2, Decl(destructuringTypeGuardFlow.ts, 25, 24))
|
||||
>bBar : Symbol(bBar, Decl(destructuringTypeGuardFlow.ts, 25, 5))
|
||||
>elem2 : Symbol(elem2, Decl(destructuringTypeGuardFlow.ts, 25, 24))
|
||||
>bar : Symbol(bar, Decl(destructuringTypeGuardFlow.ts, 0, 12))
|
||||
>bBar.elem2.nested.b : Symbol(b, Decl(destructuringTypeGuardFlow.ts, 4, 14))
|
||||
>bBar.elem2.nested : Symbol(nested, Decl(destructuringTypeGuardFlow.ts, 2, 14))
|
||||
>bBar.elem2 : Symbol(elem2, Decl(destructuringTypeGuardFlow.ts, 25, 24))
|
||||
>bBar : Symbol(bBar, Decl(destructuringTypeGuardFlow.ts, 25, 5))
|
||||
>elem2 : Symbol(elem2, Decl(destructuringTypeGuardFlow.ts, 25, 24))
|
||||
>nested : Symbol(nested, Decl(destructuringTypeGuardFlow.ts, 2, 14))
|
||||
>b : Symbol(b, Decl(destructuringTypeGuardFlow.ts, 4, 14))
|
||||
|
||||
const { bar, baz, nested: {a, b: text} } = bBar.elem2;
|
||||
>bar : Symbol(bar, Decl(destructuringTypeGuardFlow.ts, 28, 9))
|
||||
>baz : Symbol(baz, Decl(destructuringTypeGuardFlow.ts, 28, 14))
|
||||
>nested : Symbol(nested, Decl(destructuringTypeGuardFlow.ts, 2, 14))
|
||||
>a : Symbol(a, Decl(destructuringTypeGuardFlow.ts, 28, 29))
|
||||
>b : Symbol(b, Decl(destructuringTypeGuardFlow.ts, 4, 14))
|
||||
>text : Symbol(text, Decl(destructuringTypeGuardFlow.ts, 28, 31))
|
||||
>bBar.elem2 : Symbol(elem2, Decl(destructuringTypeGuardFlow.ts, 25, 24))
|
||||
>bBar : Symbol(bBar, Decl(destructuringTypeGuardFlow.ts, 25, 5))
|
||||
>elem2 : Symbol(elem2, Decl(destructuringTypeGuardFlow.ts, 25, 24))
|
||||
|
||||
const right: number = bBar.elem2.bar;
|
||||
>right : Symbol(right, Decl(destructuringTypeGuardFlow.ts, 29, 7))
|
||||
>bBar.elem2.bar : Symbol(bar, Decl(destructuringTypeGuardFlow.ts, 0, 12))
|
||||
>bBar.elem2 : Symbol(elem2, Decl(destructuringTypeGuardFlow.ts, 25, 24))
|
||||
>bBar : Symbol(bBar, Decl(destructuringTypeGuardFlow.ts, 25, 5))
|
||||
>elem2 : Symbol(elem2, Decl(destructuringTypeGuardFlow.ts, 25, 24))
|
||||
>bar : Symbol(bar, Decl(destructuringTypeGuardFlow.ts, 0, 12))
|
||||
|
||||
const wrong: number = bar;
|
||||
>wrong : Symbol(wrong, Decl(destructuringTypeGuardFlow.ts, 30, 7))
|
||||
>bar : Symbol(bar, Decl(destructuringTypeGuardFlow.ts, 28, 9))
|
||||
|
||||
const another: string = baz;
|
||||
>another : Symbol(another, Decl(destructuringTypeGuardFlow.ts, 31, 7))
|
||||
>baz : Symbol(baz, Decl(destructuringTypeGuardFlow.ts, 28, 14))
|
||||
|
||||
const aAgain: number = a;
|
||||
>aAgain : Symbol(aAgain, Decl(destructuringTypeGuardFlow.ts, 32, 7))
|
||||
>a : Symbol(a, Decl(destructuringTypeGuardFlow.ts, 28, 29))
|
||||
|
||||
const bAgain: string = text;
|
||||
>bAgain : Symbol(bAgain, Decl(destructuringTypeGuardFlow.ts, 33, 7))
|
||||
>text : Symbol(text, Decl(destructuringTypeGuardFlow.ts, 28, 31))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
=== tests/cases/compiler/destructuringTypeGuardFlow.ts ===
|
||||
type foo = {
|
||||
>foo : foo
|
||||
|
||||
bar: number | null;
|
||||
>bar : number | null
|
||||
>null : null
|
||||
|
||||
baz: string;
|
||||
>baz : string
|
||||
|
||||
nested: {
|
||||
>nested : { a: number; b: string | null; }
|
||||
|
||||
a: number;
|
||||
>a : number
|
||||
|
||||
b: string | null;
|
||||
>b : string | null
|
||||
>null : null
|
||||
}
|
||||
};
|
||||
|
||||
const aFoo: foo = { bar: 3, baz: "b", nested: { a: 1, b: "y" } };
|
||||
>aFoo : foo
|
||||
>foo : foo
|
||||
>{ bar: 3, baz: "b", nested: { a: 1, b: "y" } } : { bar: number; baz: string; nested: { a: number; b: string; }; }
|
||||
>bar : number
|
||||
>3 : 3
|
||||
>baz : string
|
||||
>"b" : "b"
|
||||
>nested : { a: number; b: string; }
|
||||
>{ a: 1, b: "y" } : { a: number; b: string; }
|
||||
>a : number
|
||||
>1 : 1
|
||||
>b : string
|
||||
>"y" : "y"
|
||||
|
||||
if (aFoo.bar && aFoo.nested.b) {
|
||||
>aFoo.bar && aFoo.nested.b : string | 0 | null
|
||||
>aFoo.bar : number | null
|
||||
>aFoo : foo
|
||||
>bar : number | null
|
||||
>aFoo.nested.b : string | null
|
||||
>aFoo.nested : { a: number; b: string | null; }
|
||||
>aFoo : foo
|
||||
>nested : { a: number; b: string | null; }
|
||||
>b : string | null
|
||||
|
||||
const { bar, baz, nested: {a, b: text} } = aFoo;
|
||||
>bar : number
|
||||
>baz : string
|
||||
>nested : any
|
||||
>a : number
|
||||
>b : any
|
||||
>text : string
|
||||
>aFoo : foo
|
||||
|
||||
const right: number = aFoo.bar;
|
||||
>right : number
|
||||
>aFoo.bar : number
|
||||
>aFoo : foo
|
||||
>bar : number
|
||||
|
||||
const wrong: number = bar;
|
||||
>wrong : number
|
||||
>bar : number
|
||||
|
||||
const another: string = baz;
|
||||
>another : string
|
||||
>baz : string
|
||||
|
||||
const aAgain: number = a;
|
||||
>aAgain : number
|
||||
>a : number
|
||||
|
||||
const bAgain: string = text;
|
||||
>bAgain : string
|
||||
>text : string
|
||||
}
|
||||
|
||||
type bar = {
|
||||
>bar : bar
|
||||
|
||||
elem1: number | null;
|
||||
>elem1 : number | null
|
||||
>null : null
|
||||
|
||||
elem2: foo | null;
|
||||
>elem2 : foo | null
|
||||
>foo : foo
|
||||
>null : null
|
||||
|
||||
};
|
||||
|
||||
const bBar = { elem1: 7, elem2: aFoo };
|
||||
>bBar : { elem1: number; elem2: foo; }
|
||||
>{ elem1: 7, elem2: aFoo } : { elem1: number; elem2: foo; }
|
||||
>elem1 : number
|
||||
>7 : 7
|
||||
>elem2 : foo
|
||||
>aFoo : foo
|
||||
|
||||
if (bBar.elem2 && bBar.elem2.bar && bBar.elem2.nested.b) {
|
||||
>bBar.elem2 && bBar.elem2.bar && bBar.elem2.nested.b : string | 0 | null
|
||||
>bBar.elem2 && bBar.elem2.bar : number | null
|
||||
>bBar.elem2 : foo
|
||||
>bBar : { elem1: number; elem2: foo; }
|
||||
>elem2 : foo
|
||||
>bBar.elem2.bar : number | null
|
||||
>bBar.elem2 : foo
|
||||
>bBar : { elem1: number; elem2: foo; }
|
||||
>elem2 : foo
|
||||
>bar : number | null
|
||||
>bBar.elem2.nested.b : string | null
|
||||
>bBar.elem2.nested : { a: number; b: string | null; }
|
||||
>bBar.elem2 : foo
|
||||
>bBar : { elem1: number; elem2: foo; }
|
||||
>elem2 : foo
|
||||
>nested : { a: number; b: string | null; }
|
||||
>b : string | null
|
||||
|
||||
const { bar, baz, nested: {a, b: text} } = bBar.elem2;
|
||||
>bar : number
|
||||
>baz : string
|
||||
>nested : any
|
||||
>a : number
|
||||
>b : any
|
||||
>text : string
|
||||
>bBar.elem2 : foo
|
||||
>bBar : { elem1: number; elem2: foo; }
|
||||
>elem2 : foo
|
||||
|
||||
const right: number = bBar.elem2.bar;
|
||||
>right : number
|
||||
>bBar.elem2.bar : number
|
||||
>bBar.elem2 : foo
|
||||
>bBar : { elem1: number; elem2: foo; }
|
||||
>elem2 : foo
|
||||
>bar : number
|
||||
|
||||
const wrong: number = bar;
|
||||
>wrong : number
|
||||
>bar : number
|
||||
|
||||
const another: string = baz;
|
||||
>another : string
|
||||
>baz : string
|
||||
|
||||
const aAgain: number = a;
|
||||
>aAgain : number
|
||||
>a : number
|
||||
|
||||
const bAgain: string = text;
|
||||
>bAgain : string
|
||||
>text : string
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
/a.js(4,9): error TS2322: Type '0' is not assignable to type '() => void'.
|
||||
|
||||
|
||||
==== /a.js (1 errors) ====
|
||||
const o = {
|
||||
a() {
|
||||
// Should not be treated as a declaration. Should be an error.
|
||||
this.a = 0;
|
||||
~~~~~~
|
||||
!!! error TS2322: Type '0' is not assignable to type '() => void'.
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
/a.js(4,9): error TS2322: Type '0' is not assignable to type '() => void'.
|
||||
|
||||
|
||||
==== /a.js (1 errors) ====
|
||||
const o = {
|
||||
a() {
|
||||
// Should not be treated as a declaration. Should be an error.
|
||||
this.a = 0;
|
||||
~~~~~~
|
||||
!!! error TS2322: Type '0' is not assignable to type '() => void'.
|
||||
},
|
||||
b() {
|
||||
this.b = () => {}; // OK
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
=== /a.js ===
|
||||
const o = {
|
||||
>o : Symbol(o, Decl(a.js, 0, 5))
|
||||
|
||||
a() {
|
||||
>a : Symbol(a, Decl(a.js, 0, 11))
|
||||
|
||||
// Should not be treated as a declaration.
|
||||
this.a = () => {};
|
||||
>this.a : Symbol(a, Decl(a.js, 0, 11))
|
||||
>this : Symbol(o, Decl(a.js, 0, 9))
|
||||
>a : Symbol(a, Decl(a.js, 0, 11))
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
=== /a.js ===
|
||||
const o = {
|
||||
>o : { [x: string]: any; a(): void; }
|
||||
>{ a() { // Should not be treated as a declaration. this.a = () => {}; }} : { [x: string]: any; a(): void; }
|
||||
|
||||
a() {
|
||||
>a : () => void
|
||||
|
||||
// Should not be treated as a declaration.
|
||||
this.a = () => {};
|
||||
>this.a = () => {} : () => void
|
||||
>this.a : () => void
|
||||
>this : { [x: string]: any; a(): void; }
|
||||
>a : () => void
|
||||
>() => {} : () => void
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
=== tests/cases/conformance/jsdoc/indices.js ===
|
||||
/** @type {Object.<string, number>} */
|
||||
var o1;
|
||||
>o1 : Symbol(o1, Decl(indices.js, 1, 3))
|
||||
|
||||
/** @type {Object.<number, boolean>} */
|
||||
var o2;
|
||||
>o2 : Symbol(o2, Decl(indices.js, 3, 3))
|
||||
|
||||
/** @type {Object.<boolean, string>} */
|
||||
var o3;
|
||||
>o3 : Symbol(o3, Decl(indices.js, 5, 3))
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
=== tests/cases/conformance/jsdoc/indices.js ===
|
||||
/** @type {Object.<string, number>} */
|
||||
var o1;
|
||||
>o1 : { [x: string]: number; }
|
||||
|
||||
/** @type {Object.<number, boolean>} */
|
||||
var o2;
|
||||
>o2 : { [x: number]: boolean; }
|
||||
|
||||
/** @type {Object.<boolean, string>} */
|
||||
var o3;
|
||||
>o3 : any
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
tests/cases/conformance/jsdoc/b.js(4,13): error TS2352: Type 'number' cannot be converted to type 'string'.
|
||||
tests/cases/conformance/jsdoc/b.js(45,16): error TS2352: Type 'SomeOther' cannot be converted to type 'SomeBase'.
|
||||
Property 'p' is missing in type 'SomeOther'.
|
||||
tests/cases/conformance/jsdoc/b.js(49,19): error TS2352: Type 'SomeOther' cannot be converted to type 'SomeDerived'.
|
||||
Property 'x' is missing in type 'SomeOther'.
|
||||
tests/cases/conformance/jsdoc/b.js(51,17): error TS2352: Type 'SomeDerived' cannot be converted to type 'SomeOther'.
|
||||
Property 'q' is missing in type 'SomeDerived'.
|
||||
tests/cases/conformance/jsdoc/b.js(52,17): error TS2352: Type 'SomeBase' cannot be converted to type 'SomeOther'.
|
||||
Property 'q' is missing in type 'SomeBase'.
|
||||
tests/cases/conformance/jsdoc/b.js(58,1): error TS2322: Type '{ p: string | number | undefined; }' is not assignable to type 'SomeBase'.
|
||||
Types of property 'p' are incompatible.
|
||||
Type 'string | number | undefined' is not assignable to type 'number'.
|
||||
Type 'undefined' is not assignable to type 'number'.
|
||||
tests/cases/conformance/jsdoc/b.js(66,8): error TS2352: Type 'boolean' cannot be converted to type 'string | number'.
|
||||
tests/cases/conformance/jsdoc/b.js(66,15): error TS2304: Cannot find name 'numOrStr'.
|
||||
tests/cases/conformance/jsdoc/b.js(66,24): error TS1005: '}' expected.
|
||||
tests/cases/conformance/jsdoc/b.js(66,38): error TS2454: Variable 'numOrStr' is used before being assigned.
|
||||
tests/cases/conformance/jsdoc/b.js(67,2): error TS2322: Type 'string | number' is not assignable to type 'string'.
|
||||
Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/conformance/jsdoc/b.js(67,8): error TS2454: Variable 'numOrStr' is used before being assigned.
|
||||
|
||||
|
||||
==== tests/cases/conformance/jsdoc/a.ts (0 errors) ====
|
||||
var W: string;
|
||||
|
||||
==== tests/cases/conformance/jsdoc/b.js (12 errors) ====
|
||||
// @ts-check
|
||||
var W = /** @type {string} */(/** @type {*} */ (4));
|
||||
|
||||
var W = /** @type {string} */(4); // Error
|
||||
~~~~~~~~~~~~~~
|
||||
!!! error TS2352: Type 'number' cannot be converted to type 'string'.
|
||||
|
||||
/** @type {*} */
|
||||
var a;
|
||||
|
||||
/** @type {string} */
|
||||
var s;
|
||||
|
||||
var a = /** @type {*} */("" + 4);
|
||||
var s = "" + /** @type {*} */(4);
|
||||
|
||||
class SomeBase {
|
||||
constructor() {
|
||||
this.p = 42;
|
||||
}
|
||||
}
|
||||
class SomeDerived extends SomeBase {
|
||||
constructor() {
|
||||
super();
|
||||
this.x = 42;
|
||||
}
|
||||
}
|
||||
class SomeOther {
|
||||
constructor() {
|
||||
this.q = 42;
|
||||
}
|
||||
}
|
||||
|
||||
function SomeFakeClass() {
|
||||
/** @type {string|number} */
|
||||
this.p = "bar";
|
||||
}
|
||||
|
||||
// Type assertion should check for assignability in either direction
|
||||
var someBase = new SomeBase();
|
||||
var someDerived = new SomeDerived();
|
||||
var someOther = new SomeOther();
|
||||
var someFakeClass = new SomeFakeClass();
|
||||
|
||||
someBase = /** @type {SomeBase} */(someDerived);
|
||||
someBase = /** @type {SomeBase} */(someBase);
|
||||
someBase = /** @type {SomeBase} */(someOther); // Error
|
||||
~~~~~~~~~~~~~~~~
|
||||
!!! error TS2352: Type 'SomeOther' cannot be converted to type 'SomeBase'.
|
||||
!!! error TS2352: Property 'p' is missing in type 'SomeOther'.
|
||||
|
||||
someDerived = /** @type {SomeDerived} */(someDerived);
|
||||
someDerived = /** @type {SomeDerived} */(someBase);
|
||||
someDerived = /** @type {SomeDerived} */(someOther); // Error
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2352: Type 'SomeOther' cannot be converted to type 'SomeDerived'.
|
||||
!!! error TS2352: Property 'x' is missing in type 'SomeOther'.
|
||||
|
||||
someOther = /** @type {SomeOther} */(someDerived); // Error
|
||||
~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2352: Type 'SomeDerived' cannot be converted to type 'SomeOther'.
|
||||
!!! error TS2352: Property 'q' is missing in type 'SomeDerived'.
|
||||
someOther = /** @type {SomeOther} */(someBase); // Error
|
||||
~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2352: Type 'SomeBase' cannot be converted to type 'SomeOther'.
|
||||
!!! error TS2352: Property 'q' is missing in type 'SomeBase'.
|
||||
someOther = /** @type {SomeOther} */(someOther);
|
||||
|
||||
someFakeClass = someBase;
|
||||
someFakeClass = someDerived;
|
||||
|
||||
someBase = someFakeClass; // Error
|
||||
~~~~~~~~
|
||||
!!! error TS2322: Type '{ p: string | number | undefined; }' is not assignable to type 'SomeBase'.
|
||||
!!! error TS2322: Types of property 'p' are incompatible.
|
||||
!!! error TS2322: Type 'string | number | undefined' is not assignable to type 'number'.
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'number'.
|
||||
someBase = /** @type {SomeBase} */(someFakeClass);
|
||||
|
||||
// Type assertion cannot be a type-predicate type
|
||||
/** @type {number | string} */
|
||||
var numOrStr;
|
||||
/** @type {string} */
|
||||
var str;
|
||||
if(/** @type {numOrStr is string} */(numOrStr === undefined)) { // Error
|
||||
~~~~~~~~~~~~~~~
|
||||
!!! error TS2352: Type 'boolean' cannot be converted to type 'string | number'.
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'numOrStr'.
|
||||
~~
|
||||
!!! error TS1005: '}' expected.
|
||||
~~~~~~~~
|
||||
!!! error TS2454: Variable 'numOrStr' is used before being assigned.
|
||||
str = numOrStr; // Error, no narrowing occurred
|
||||
~~~
|
||||
!!! error TS2322: Type 'string | number' is not assignable to type 'string'.
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
~~~~~~~~
|
||||
!!! error TS2454: Variable 'numOrStr' is used before being assigned.
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
//// [tests/cases/conformance/jsdoc/jsdocTypeTagCast.ts] ////
|
||||
|
||||
//// [a.ts]
|
||||
var W: string;
|
||||
|
||||
//// [b.js]
|
||||
// @ts-check
|
||||
var W = /** @type {string} */(/** @type {*} */ (4));
|
||||
|
||||
var W = /** @type {string} */(4); // Error
|
||||
|
||||
/** @type {*} */
|
||||
var a;
|
||||
|
||||
/** @type {string} */
|
||||
var s;
|
||||
|
||||
var a = /** @type {*} */("" + 4);
|
||||
var s = "" + /** @type {*} */(4);
|
||||
|
||||
class SomeBase {
|
||||
constructor() {
|
||||
this.p = 42;
|
||||
}
|
||||
}
|
||||
class SomeDerived extends SomeBase {
|
||||
constructor() {
|
||||
super();
|
||||
this.x = 42;
|
||||
}
|
||||
}
|
||||
class SomeOther {
|
||||
constructor() {
|
||||
this.q = 42;
|
||||
}
|
||||
}
|
||||
|
||||
function SomeFakeClass() {
|
||||
/** @type {string|number} */
|
||||
this.p = "bar";
|
||||
}
|
||||
|
||||
// Type assertion should check for assignability in either direction
|
||||
var someBase = new SomeBase();
|
||||
var someDerived = new SomeDerived();
|
||||
var someOther = new SomeOther();
|
||||
var someFakeClass = new SomeFakeClass();
|
||||
|
||||
someBase = /** @type {SomeBase} */(someDerived);
|
||||
someBase = /** @type {SomeBase} */(someBase);
|
||||
someBase = /** @type {SomeBase} */(someOther); // Error
|
||||
|
||||
someDerived = /** @type {SomeDerived} */(someDerived);
|
||||
someDerived = /** @type {SomeDerived} */(someBase);
|
||||
someDerived = /** @type {SomeDerived} */(someOther); // Error
|
||||
|
||||
someOther = /** @type {SomeOther} */(someDerived); // Error
|
||||
someOther = /** @type {SomeOther} */(someBase); // Error
|
||||
someOther = /** @type {SomeOther} */(someOther);
|
||||
|
||||
someFakeClass = someBase;
|
||||
someFakeClass = someDerived;
|
||||
|
||||
someBase = someFakeClass; // Error
|
||||
someBase = /** @type {SomeBase} */(someFakeClass);
|
||||
|
||||
// Type assertion cannot be a type-predicate type
|
||||
/** @type {number | string} */
|
||||
var numOrStr;
|
||||
/** @type {string} */
|
||||
var str;
|
||||
if(/** @type {numOrStr is string} */(numOrStr === undefined)) { // Error
|
||||
str = numOrStr; // Error, no narrowing occurred
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//// [a.js]
|
||||
var W;
|
||||
//// [b.js]
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
// @ts-check
|
||||
var W = ((4));
|
||||
var W = (4); // Error
|
||||
/** @type {*} */
|
||||
var a;
|
||||
/** @type {string} */
|
||||
var s;
|
||||
var a = ("" + 4);
|
||||
var s = "" + (4);
|
||||
var SomeBase = (function () {
|
||||
function SomeBase() {
|
||||
this.p = 42;
|
||||
}
|
||||
return SomeBase;
|
||||
}());
|
||||
var SomeDerived = (function (_super) {
|
||||
__extends(SomeDerived, _super);
|
||||
function SomeDerived() {
|
||||
var _this = _super.call(this) || this;
|
||||
_this.x = 42;
|
||||
return _this;
|
||||
}
|
||||
return SomeDerived;
|
||||
}(SomeBase));
|
||||
var SomeOther = (function () {
|
||||
function SomeOther() {
|
||||
this.q = 42;
|
||||
}
|
||||
return SomeOther;
|
||||
}());
|
||||
function SomeFakeClass() {
|
||||
/** @type {string|number} */
|
||||
this.p = "bar";
|
||||
}
|
||||
// Type assertion should check for assignability in either direction
|
||||
var someBase = new SomeBase();
|
||||
var someDerived = new SomeDerived();
|
||||
var someOther = new SomeOther();
|
||||
var someFakeClass = new SomeFakeClass();
|
||||
someBase = (someDerived);
|
||||
someBase = (someBase);
|
||||
someBase = (someOther); // Error
|
||||
someDerived = (someDerived);
|
||||
someDerived = (someBase);
|
||||
someDerived = (someOther); // Error
|
||||
someOther = (someDerived); // Error
|
||||
someOther = (someBase); // Error
|
||||
someOther = (someOther);
|
||||
someFakeClass = someBase;
|
||||
someFakeClass = someDerived;
|
||||
someBase = someFakeClass; // Error
|
||||
someBase = (someFakeClass);
|
||||
// Type assertion cannot be a type-predicate type
|
||||
/** @type {number | string} */
|
||||
var numOrStr;
|
||||
/** @type {string} */
|
||||
var str;
|
||||
if ((numOrStr === undefined)) {
|
||||
str = numOrStr; // Error, no narrowing occurred
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
tests/cases/compiler/keyofIsLiteralContexualType.ts(5,9): error TS2322: Type '("a" | "b" | "c")[]' is not assignable to type 'keyof T[]'.
|
||||
tests/cases/compiler/keyofIsLiteralContexualType.ts(5,9): error TS2322: Type '("a" | "b" | "c")[]' is not assignable to type '(keyof T)[]'.
|
||||
Type '"a" | "b" | "c"' is not assignable to type 'keyof T'.
|
||||
Type '"c"' is not assignable to type 'keyof T'.
|
||||
Type '"c"' is not assignable to type '"a" | "b"'.
|
||||
@@ -12,7 +12,7 @@ tests/cases/compiler/keyofIsLiteralContexualType.ts(13,11): error TS2339: Proper
|
||||
let a: (keyof T)[] = ["a", "b"];
|
||||
let b: (keyof T)[] = ["a", "b", "c"];
|
||||
~
|
||||
!!! error TS2322: Type '("a" | "b" | "c")[]' is not assignable to type 'keyof T[]'.
|
||||
!!! error TS2322: Type '("a" | "b" | "c")[]' is not assignable to type '(keyof T)[]'.
|
||||
!!! error TS2322: Type '"a" | "b" | "c"' is not assignable to type 'keyof T'.
|
||||
!!! error TS2322: Type '"c"' is not assignable to type 'keyof T'.
|
||||
!!! error TS2322: Type '"c"' is not assignable to type '"a" | "b"'.
|
||||
|
||||
@@ -66,45 +66,47 @@ class Y {
|
||||
>Y : Symbol(Y, Decl(input.js, 19, 10))
|
||||
|
||||
mistake() {
|
||||
>mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 26, 35), Decl(input.js, 29, 1))
|
||||
>mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 29, 1))
|
||||
}
|
||||
m() {
|
||||
>m : Symbol(Y.m, Decl(input.js, 22, 5), Decl(input.js, 25, 19))
|
||||
>m : Symbol(Y.m, Decl(input.js, 22, 5))
|
||||
}
|
||||
constructor() {
|
||||
this.m = this.m.bind(this);
|
||||
>this.m : Symbol(Y.m, Decl(input.js, 22, 5), Decl(input.js, 25, 19))
|
||||
>this.m : Symbol(Y.m, Decl(input.js, 22, 5))
|
||||
>this : Symbol(Y, Decl(input.js, 19, 10))
|
||||
>m : Symbol(Y.m, Decl(input.js, 22, 5), Decl(input.js, 25, 19))
|
||||
>this.m : Symbol(Y.m, Decl(input.js, 22, 5), Decl(input.js, 25, 19))
|
||||
>m : Symbol(Y.m, Decl(input.js, 22, 5))
|
||||
>this.m.bind : Symbol(Function.bind, Decl(lib.d.ts, --, --))
|
||||
>this.m : Symbol(Y.m, Decl(input.js, 22, 5))
|
||||
>this : Symbol(Y, Decl(input.js, 19, 10))
|
||||
>m : Symbol(Y.m, Decl(input.js, 22, 5), Decl(input.js, 25, 19))
|
||||
>m : Symbol(Y.m, Decl(input.js, 22, 5))
|
||||
>bind : Symbol(Function.bind, Decl(lib.d.ts, --, --))
|
||||
>this : Symbol(Y, Decl(input.js, 19, 10))
|
||||
|
||||
this.mistake = 'even more nonsense';
|
||||
>this.mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 26, 35), Decl(input.js, 29, 1))
|
||||
>this.mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 29, 1))
|
||||
>this : Symbol(Y, Decl(input.js, 19, 10))
|
||||
>mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 26, 35), Decl(input.js, 29, 1))
|
||||
>mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 29, 1))
|
||||
}
|
||||
}
|
||||
Y.prototype.mistake = true;
|
||||
>Y.prototype.mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 26, 35), Decl(input.js, 29, 1))
|
||||
>Y.prototype : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 26, 35), Decl(input.js, 29, 1))
|
||||
>Y.prototype.mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 29, 1))
|
||||
>Y.prototype : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 29, 1))
|
||||
>Y : Symbol(Y, Decl(input.js, 19, 10))
|
||||
>prototype : Symbol(Y.prototype)
|
||||
>mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 26, 35), Decl(input.js, 29, 1))
|
||||
>mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 29, 1))
|
||||
|
||||
let y = new Y();
|
||||
>y : Symbol(y, Decl(input.js, 31, 3))
|
||||
>Y : Symbol(Y, Decl(input.js, 19, 10))
|
||||
|
||||
y.m();
|
||||
>y.m : Symbol(Y.m, Decl(input.js, 22, 5), Decl(input.js, 25, 19))
|
||||
>y.m : Symbol(Y.m, Decl(input.js, 22, 5))
|
||||
>y : Symbol(y, Decl(input.js, 31, 3))
|
||||
>m : Symbol(Y.m, Decl(input.js, 22, 5), Decl(input.js, 25, 19))
|
||||
>m : Symbol(Y.m, Decl(input.js, 22, 5))
|
||||
|
||||
y.mistake();
|
||||
>y.mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 26, 35), Decl(input.js, 29, 1))
|
||||
>y.mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 29, 1))
|
||||
>y : Symbol(y, Decl(input.js, 31, 3))
|
||||
>mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 26, 35), Decl(input.js, 29, 1))
|
||||
>mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 29, 1))
|
||||
|
||||
|
||||
@@ -87,20 +87,20 @@ class Y {
|
||||
>mistake : any
|
||||
}
|
||||
m() {
|
||||
>m : any
|
||||
>m : () => void
|
||||
}
|
||||
constructor() {
|
||||
this.m = this.m.bind(this);
|
||||
>this.m = this.m.bind(this) : any
|
||||
>this.m : any
|
||||
>this.m : () => void
|
||||
>this : this
|
||||
>m : any
|
||||
>m : () => void
|
||||
>this.m.bind(this) : any
|
||||
>this.m.bind : any
|
||||
>this.m : any
|
||||
>this.m.bind : (this: Function, thisArg: any, ...argArray: any[]) => any
|
||||
>this.m : () => void
|
||||
>this : this
|
||||
>m : any
|
||||
>bind : any
|
||||
>m : () => void
|
||||
>bind : (this: Function, thisArg: any, ...argArray: any[]) => any
|
||||
>this : this
|
||||
|
||||
this.mistake = 'even more nonsense';
|
||||
@@ -126,10 +126,10 @@ let y = new Y();
|
||||
>Y : typeof Y
|
||||
|
||||
y.m();
|
||||
>y.m() : any
|
||||
>y.m : any
|
||||
>y.m() : void
|
||||
>y.m : () => void
|
||||
>y : Y
|
||||
>m : any
|
||||
>m : () => void
|
||||
|
||||
y.mistake();
|
||||
>y.mistake() : any
|
||||
|
||||
@@ -62,9 +62,21 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(123,20
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(128,34): error TS1230: A type predicate cannot reference element 'p1' in a binding pattern.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(132,34): error TS1230: A type predicate cannot reference element 'p1' in a binding pattern.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(136,39): error TS1230: A type predicate cannot reference element 'p1' in a binding pattern.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(152,68): error TS2344: Type 'T | "d"' does not satisfy the constraint 'Keys'.
|
||||
Type '"d"' is not assignable to type 'Keys'.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(159,31): error TS2344: Type 'Bar' does not satisfy the constraint 'Foo'.
|
||||
Types of property ''a'' are incompatible.
|
||||
Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(162,31): error TS2344: Type 'Bar' does not satisfy the constraint 'Foo'.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(163,35): error TS2344: Type 'number' does not satisfy the constraint 'Foo'.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(164,51): error TS2344: Type 'Bar' does not satisfy the constraint 'Foo'.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(165,51): error TS2344: Type 'number' does not satisfy the constraint 'Foo'.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(166,45): error TS2677: A type predicate's type must be assignable to its parameter's type.
|
||||
Type 'NeedsFoo<number>' is not assignable to type 'number'.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(166,54): error TS2344: Type 'number' does not satisfy the constraint 'Foo'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts (54 errors) ====
|
||||
==== tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts (62 errors) ====
|
||||
class A {
|
||||
~
|
||||
!!! error TS2300: Duplicate identifier 'A'.
|
||||
@@ -175,7 +187,7 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(136,39
|
||||
|
||||
// No type guard in if statement
|
||||
if (hasNoTypeGuard(a)) {
|
||||
a.propB;
|
||||
a.propB;
|
||||
~~~~~
|
||||
!!! error TS2551: Property 'propB' does not exist on type 'A'. Did you mean 'propA'?
|
||||
}
|
||||
@@ -208,7 +220,7 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(136,39
|
||||
return true;
|
||||
};
|
||||
|
||||
// No matching signature
|
||||
// No matching signature
|
||||
var assign3: (p1, p2) => p1 is A;
|
||||
assign3 = function(p1, p2, p3): p1 is A {
|
||||
~~~~~~~
|
||||
@@ -326,4 +338,47 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(136,39
|
||||
var x: A;
|
||||
if (hasMissingParameter()) {
|
||||
x.propA;
|
||||
}
|
||||
}
|
||||
|
||||
// repro #17297
|
||||
|
||||
type Keys = 'a'|'b'|'c'
|
||||
type KeySet<T extends Keys> = { [k in T]: true }
|
||||
|
||||
// expected an error, since Keys doesn't have a 'd'
|
||||
declare function hasKey<T extends Keys>(x: KeySet<T>): x is KeySet<T|'d'>;
|
||||
~~~~~
|
||||
!!! error TS2344: Type 'T | "d"' does not satisfy the constraint 'Keys'.
|
||||
!!! error TS2344: Type '"d"' is not assignable to type 'Keys'.
|
||||
|
||||
type Foo = { 'a': string; }
|
||||
type Bar = { 'a': number; }
|
||||
|
||||
interface NeedsFoo<T extends Foo> {
|
||||
foo: T;
|
||||
isFoo(): this is NeedsFoo<Bar>; // should error
|
||||
~~~
|
||||
!!! error TS2344: Type 'Bar' does not satisfy the constraint 'Foo'.
|
||||
!!! error TS2344: Types of property ''a'' are incompatible.
|
||||
!!! error TS2344: Type 'number' is not assignable to type 'string'.
|
||||
};
|
||||
|
||||
declare var anError: NeedsFoo<Bar>; // error, as expected
|
||||
~~~
|
||||
!!! error TS2344: Type 'Bar' does not satisfy the constraint 'Foo'.
|
||||
declare var alsoAnError: NeedsFoo<number>; // also error, as expected
|
||||
~~~~~~
|
||||
!!! error TS2344: Type 'number' does not satisfy the constraint 'Foo'.
|
||||
declare function newError1(x: any): x is NeedsFoo<Bar>; // should error
|
||||
~~~
|
||||
!!! error TS2344: Type 'Bar' does not satisfy the constraint 'Foo'.
|
||||
declare function newError2(x: any): x is NeedsFoo<number>; // should error
|
||||
~~~~~~
|
||||
!!! error TS2344: Type 'number' does not satisfy the constraint 'Foo'.
|
||||
declare function newError3(x: number): x is NeedsFoo<number>; // should error
|
||||
~~~~~~~~~~~~~~~~
|
||||
!!! error TS2677: A type predicate's type must be assignable to its parameter's type.
|
||||
!!! error TS2677: Type 'NeedsFoo<number>' is not assignable to type 'number'.
|
||||
~~~~~~
|
||||
!!! error TS2344: Type 'number' does not satisfy the constraint 'Foo'.
|
||||
|
||||
@@ -67,7 +67,7 @@ if (funA(0, a)) {
|
||||
|
||||
// No type guard in if statement
|
||||
if (hasNoTypeGuard(a)) {
|
||||
a.propB;
|
||||
a.propB;
|
||||
}
|
||||
|
||||
// Type predicate type is not assignable
|
||||
@@ -86,7 +86,7 @@ assign2 = function(p1, p2): p2 is A {
|
||||
return true;
|
||||
};
|
||||
|
||||
// No matching signature
|
||||
// No matching signature
|
||||
var assign3: (p1, p2) => p1 is A;
|
||||
assign3 = function(p1, p2, p3): p1 is A {
|
||||
return true;
|
||||
@@ -142,7 +142,30 @@ function b7({a, b, c: {p1}}, p2, p3): p1 is A {
|
||||
var x: A;
|
||||
if (hasMissingParameter()) {
|
||||
x.propA;
|
||||
}
|
||||
}
|
||||
|
||||
// repro #17297
|
||||
|
||||
type Keys = 'a'|'b'|'c'
|
||||
type KeySet<T extends Keys> = { [k in T]: true }
|
||||
|
||||
// expected an error, since Keys doesn't have a 'd'
|
||||
declare function hasKey<T extends Keys>(x: KeySet<T>): x is KeySet<T|'d'>;
|
||||
|
||||
type Foo = { 'a': string; }
|
||||
type Bar = { 'a': number; }
|
||||
|
||||
interface NeedsFoo<T extends Foo> {
|
||||
foo: T;
|
||||
isFoo(): this is NeedsFoo<Bar>; // should error
|
||||
};
|
||||
|
||||
declare var anError: NeedsFoo<Bar>; // error, as expected
|
||||
declare var alsoAnError: NeedsFoo<number>; // also error, as expected
|
||||
declare function newError1(x: any): x is NeedsFoo<Bar>; // should error
|
||||
declare function newError2(x: any): x is NeedsFoo<number>; // should error
|
||||
declare function newError3(x: number): x is NeedsFoo<number>; // should error
|
||||
|
||||
|
||||
//// [typeGuardFunctionErrors.js]
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
@@ -224,7 +247,7 @@ var assign2;
|
||||
assign2 = function (p1, p2) {
|
||||
return true;
|
||||
};
|
||||
// No matching signature
|
||||
// No matching signature
|
||||
var assign3;
|
||||
assign3 = function (p1, p2, p3) {
|
||||
return true;
|
||||
@@ -290,3 +313,4 @@ var x;
|
||||
if (hasMissingParameter()) {
|
||||
x.propA;
|
||||
}
|
||||
;
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
// @strictNullChecks: true
|
||||
type foo = {
|
||||
bar: number | null;
|
||||
baz: string;
|
||||
nested: {
|
||||
a: number;
|
||||
b: string | null;
|
||||
}
|
||||
};
|
||||
|
||||
const aFoo: foo = { bar: 3, baz: "b", nested: { a: 1, b: "y" } };
|
||||
|
||||
if (aFoo.bar && aFoo.nested.b) {
|
||||
const { bar, baz, nested: {a, b: text} } = aFoo;
|
||||
const right: number = aFoo.bar;
|
||||
const wrong: number = bar;
|
||||
const another: string = baz;
|
||||
const aAgain: number = a;
|
||||
const bAgain: string = text;
|
||||
}
|
||||
|
||||
type bar = {
|
||||
elem1: number | null;
|
||||
elem2: foo | null;
|
||||
};
|
||||
|
||||
const bBar = { elem1: 7, elem2: aFoo };
|
||||
|
||||
if (bBar.elem2 && bBar.elem2.bar && bBar.elem2.nested.b) {
|
||||
const { bar, baz, nested: {a, b: text} } = bBar.elem2;
|
||||
const right: number = bBar.elem2.bar;
|
||||
const wrong: number = bar;
|
||||
const another: string = baz;
|
||||
const aAgain: number = a;
|
||||
const bAgain: string = text;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @noEmit: true
|
||||
// @noImplicitThis: true
|
||||
|
||||
// @Filename: /a.js
|
||||
const o = {
|
||||
a() {
|
||||
// Should not be treated as a declaration. Should be an error.
|
||||
this.a = 0;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,12 @@
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @noEmit: true
|
||||
// @noImplicitThis: true
|
||||
|
||||
// @Filename: /a.js
|
||||
const o = {
|
||||
a() {
|
||||
// Should not be treated as a declaration.
|
||||
this.a = () => {};
|
||||
}
|
||||
};
|
||||
@@ -67,7 +67,7 @@ if (funA(0, a)) {
|
||||
|
||||
// No type guard in if statement
|
||||
if (hasNoTypeGuard(a)) {
|
||||
a.propB;
|
||||
a.propB;
|
||||
}
|
||||
|
||||
// Type predicate type is not assignable
|
||||
@@ -86,7 +86,7 @@ assign2 = function(p1, p2): p2 is A {
|
||||
return true;
|
||||
};
|
||||
|
||||
// No matching signature
|
||||
// No matching signature
|
||||
var assign3: (p1, p2) => p1 is A;
|
||||
assign3 = function(p1, p2, p3): p1 is A {
|
||||
return true;
|
||||
@@ -142,4 +142,26 @@ function b7({a, b, c: {p1}}, p2, p3): p1 is A {
|
||||
var x: A;
|
||||
if (hasMissingParameter()) {
|
||||
x.propA;
|
||||
}
|
||||
}
|
||||
|
||||
// repro #17297
|
||||
|
||||
type Keys = 'a'|'b'|'c'
|
||||
type KeySet<T extends Keys> = { [k in T]: true }
|
||||
|
||||
// expected an error, since Keys doesn't have a 'd'
|
||||
declare function hasKey<T extends Keys>(x: KeySet<T>): x is KeySet<T|'d'>;
|
||||
|
||||
type Foo = { 'a': string; }
|
||||
type Bar = { 'a': number; }
|
||||
|
||||
interface NeedsFoo<T extends Foo> {
|
||||
foo: T;
|
||||
isFoo(): this is NeedsFoo<Bar>; // should error
|
||||
};
|
||||
|
||||
declare var anError: NeedsFoo<Bar>; // error, as expected
|
||||
declare var alsoAnError: NeedsFoo<number>; // also error, as expected
|
||||
declare function newError1(x: any): x is NeedsFoo<Bar>; // should error
|
||||
declare function newError2(x: any): x is NeedsFoo<number>; // should error
|
||||
declare function newError3(x: number): x is NeedsFoo<number>; // should error
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @noEmit: true
|
||||
// @Filename: indices.js
|
||||
/** @type {Object.<string, number>} */
|
||||
var o1;
|
||||
/** @type {Object.<number, boolean>} */
|
||||
var o2;
|
||||
/** @type {Object.<boolean, string>} */
|
||||
var o3;
|
||||
@@ -0,0 +1,78 @@
|
||||
// @allowJS: true
|
||||
// @suppressOutputPathCheck: true
|
||||
// @strictNullChecks: true
|
||||
|
||||
// @filename: a.ts
|
||||
var W: string;
|
||||
|
||||
// @filename: b.js
|
||||
// @ts-check
|
||||
var W = /** @type {string} */(/** @type {*} */ (4));
|
||||
|
||||
var W = /** @type {string} */(4); // Error
|
||||
|
||||
/** @type {*} */
|
||||
var a;
|
||||
|
||||
/** @type {string} */
|
||||
var s;
|
||||
|
||||
var a = /** @type {*} */("" + 4);
|
||||
var s = "" + /** @type {*} */(4);
|
||||
|
||||
class SomeBase {
|
||||
constructor() {
|
||||
this.p = 42;
|
||||
}
|
||||
}
|
||||
class SomeDerived extends SomeBase {
|
||||
constructor() {
|
||||
super();
|
||||
this.x = 42;
|
||||
}
|
||||
}
|
||||
class SomeOther {
|
||||
constructor() {
|
||||
this.q = 42;
|
||||
}
|
||||
}
|
||||
|
||||
function SomeFakeClass() {
|
||||
/** @type {string|number} */
|
||||
this.p = "bar";
|
||||
}
|
||||
|
||||
// Type assertion should check for assignability in either direction
|
||||
var someBase = new SomeBase();
|
||||
var someDerived = new SomeDerived();
|
||||
var someOther = new SomeOther();
|
||||
var someFakeClass = new SomeFakeClass();
|
||||
|
||||
someBase = /** @type {SomeBase} */(someDerived);
|
||||
someBase = /** @type {SomeBase} */(someBase);
|
||||
someBase = /** @type {SomeBase} */(someOther); // Error
|
||||
|
||||
someDerived = /** @type {SomeDerived} */(someDerived);
|
||||
someDerived = /** @type {SomeDerived} */(someBase);
|
||||
someDerived = /** @type {SomeDerived} */(someOther); // Error
|
||||
|
||||
someOther = /** @type {SomeOther} */(someDerived); // Error
|
||||
someOther = /** @type {SomeOther} */(someBase); // Error
|
||||
someOther = /** @type {SomeOther} */(someOther);
|
||||
|
||||
someFakeClass = someBase;
|
||||
someFakeClass = someDerived;
|
||||
|
||||
someBase = someFakeClass; // Error
|
||||
someBase = /** @type {SomeBase} */(someFakeClass);
|
||||
|
||||
// Type assertion cannot be a type-predicate type
|
||||
/** @type {number | string} */
|
||||
var numOrStr;
|
||||
/** @type {string} */
|
||||
var str;
|
||||
if(/** @type {numOrStr is string} */(numOrStr === undefined)) { // Error
|
||||
str = numOrStr; // Error, no narrowing occurred
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @noEmit: true
|
||||
// @Filename: context.js
|
||||
const obj = {
|
||||
prop: 2,
|
||||
method() {
|
||||
this;
|
||||
this.prop;
|
||||
this.method;
|
||||
this.unknown; // ok, obj has a string indexer
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
//// var x: [|?|] = 12;
|
||||
|
||||
verify.rangeAfterCodeFix("any");
|
||||
@@ -0,0 +1,4 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
//// var x: [|*|] = 12;
|
||||
|
||||
verify.rangeAfterCodeFix("any");
|
||||
@@ -0,0 +1,4 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
//// var x: [|......number[][]|] = 12;
|
||||
|
||||
verify.rangeAfterCodeFix("number[][][][]");
|
||||
@@ -0,0 +1,4 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
//// var x: [|Array.<number>|] = 12;
|
||||
|
||||
verify.rangeAfterCodeFix("number[]");
|
||||
@@ -0,0 +1,5 @@
|
||||
// @strict: true
|
||||
/// <reference path='fourslash.ts' />
|
||||
//// var x: [|?number|] = 12;
|
||||
|
||||
verify.rangeAfterCodeFix("number | null", /*includeWhiteSpace*/ false, /*errorCode*/ 8020, 0);
|
||||
@@ -0,0 +1,5 @@
|
||||
// @strict: true
|
||||
/// <reference path='fourslash.ts' />
|
||||
//// var x: [|number?|] = 12;
|
||||
|
||||
verify.rangeAfterCodeFix("number | null | undefined", /*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, 1);
|
||||
@@ -0,0 +1,4 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
//// var x: [|!number|] = 12;
|
||||
|
||||
verify.rangeAfterCodeFix("number");
|
||||
@@ -0,0 +1,4 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
//// var x: [|function(this: number, number): string|] = 12;
|
||||
|
||||
verify.rangeAfterCodeFix("(this: number, arg1: number) => string");
|
||||
@@ -0,0 +1,4 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
//// var x: [|function(new: number)|] = 12;
|
||||
|
||||
verify.rangeAfterCodeFix("new () => number");
|
||||
@@ -0,0 +1,17 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// See also `jsPropertyAssignedAfterMethodDeclaration.ts`
|
||||
|
||||
// @noLib: true
|
||||
// @allowJs: true
|
||||
// @noImplicitThis: true
|
||||
|
||||
// @Filename: /a.js
|
||||
////const o = {
|
||||
//// test/*1*/() {
|
||||
//// this./*2*/test = 0;
|
||||
//// }
|
||||
////};
|
||||
|
||||
verify.quickInfoAt("1", "(method) test(): void");
|
||||
verify.quickInfoAt("2", "(method) test(): void");
|
||||
@@ -0,0 +1,21 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
// @Filename: keyof.ts
|
||||
//// function doSomethingWithKeys<T>(...keys: (keyof T)[]) { }
|
||||
////
|
||||
//// const /*1*/utilityFunctions = {
|
||||
//// doSomethingWithKeys
|
||||
//// };
|
||||
|
||||
// @Filename: typeof.ts
|
||||
//// class Foo { static a: number; }
|
||||
//// function doSomethingWithTypes(...statics: (typeof Foo)[]) {}
|
||||
////
|
||||
//// const /*2*/utilityFunctions = {
|
||||
//// doSomethingWithTypes
|
||||
//// };
|
||||
|
||||
verify.quickInfos({
|
||||
1: "const utilityFunctions: {\n doSomethingWithKeys: <T>(...keys: (keyof T)[]) => void;\n}",
|
||||
2: "const utilityFunctions: {\n doSomethingWithTypes: (...statics: (typeof Foo)[]) => void;\n}"
|
||||
});
|
||||
Reference in New Issue
Block a user