Merge branch 'master' into transitiveReferences

This commit is contained in:
Sheetal Nandi committed 2018-10-09 14:03:58 -07:00
commit 88f79de9f4
196 files changed
+3482 -770

No files matched your search

+1
View File
@@ -0,0 +1 @@
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
+6 -3
View File
@@ -1181,7 +1181,6 @@ namespace ts {
}
const preCaseLabel = createBranchLabel();
addAntecedent(preCaseLabel, createFlowSwitchClause(preSwitchCaseFlow!, node.parent, clauseStart, i + 1));
addAntecedent(preCaseLabel, createFlowSwitchClause(preSwitchCaseFlow!, node.parent, clauseStart, i + 1));
addAntecedent(preCaseLabel, fallthroughFlow);
currentFlow = finishFlowLabel(preCaseLabel);
const clause = clauses[i];
@@ -3445,7 +3444,9 @@ namespace ts {
// ES6 syntax, and requires a lexical `this` binding.
if (transformFlags & TransformFlags.Super) {
transformFlags ^= TransformFlags.Super;
transformFlags |= TransformFlags.ContainsSuper;
// super inside of an async function requires hoisting the super access (ES2017).
// same for super inside of an async generator, which is ESNext.
transformFlags |= TransformFlags.ContainsSuper | TransformFlags.ContainsES2017 | TransformFlags.ContainsESNext;
}
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
@@ -3461,7 +3462,9 @@ namespace ts {
// ES6 syntax, and requires a lexical `this` binding.
if (expressionFlags & TransformFlags.Super) {
transformFlags &= ~TransformFlags.Super;
transformFlags |= TransformFlags.ContainsSuper;
// super inside of an async function requires hoisting the super access (ES2017).
// same for super inside of an async generator, which is ESNext.
transformFlags |= TransformFlags.ContainsSuper | TransformFlags.ContainsES2017 | TransformFlags.ContainsESNext;
}
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
+31
View File
@@ -148,8 +148,39 @@ namespace ts.BuilderState {
});
}
// Add module augmentation as references
if (sourceFile.moduleAugmentations.length) {
const checker = program.getTypeChecker();
for (const moduleName of sourceFile.moduleAugmentations) {
if (!isStringLiteral(moduleName)) { continue; }
const symbol = checker.getSymbolAtLocation(moduleName);
if (!symbol) { continue; }
// Add any file other than our own as reference
addReferenceFromAmbientModule(symbol);
}
}
// From ambient modules
for (const ambientModule of program.getTypeChecker().getAmbientModules()) {
if (ambientModule.declarations.length > 1) {
addReferenceFromAmbientModule(ambientModule);
}
}
return referencedFiles;
function addReferenceFromAmbientModule(symbol: Symbol) {
// Add any file other than our own as reference
for (const declaration of symbol.declarations) {
const declarationSourceFile = getSourceFileOfNode(declaration);
if (declarationSourceFile &&
declarationSourceFile !== sourceFile) {
addReferencedFile(declarationSourceFile.resolvedPath);
}
}
}
function addReferencedFile(referencedPath: Path) {
if (!referencedFiles) {
referencedFiles = createMap<true>();
+164 -99
View File
@@ -523,7 +523,6 @@ namespace ts {
let deferredGlobalImportMetaType: ObjectType;
let deferredGlobalExtractSymbol: Symbol;
let deferredNodes: Map<Node> | undefined;
const allPotentiallyUnusedIdentifiers = createMap<PotentiallyUnusedIdentifier[]>(); // key is file name
let flowLoopStart = 0;
@@ -667,6 +666,7 @@ namespace ts {
ResolvedReturnType,
ImmediateBaseConstraint,
EnumTagType,
JSDocTypeReference,
}
const enum CheckMode {
@@ -1466,7 +1466,7 @@ namespace ts {
if (!result) {
if (lastLocation) {
Debug.assert(lastLocation.kind === SyntaxKind.SourceFile);
if ((lastLocation as SourceFile).commonJsModuleIndicator && name === "exports") {
if ((lastLocation as SourceFile).commonJsModuleIndicator && name === "exports" && meaning & lastLocation.symbol.flags) {
return lastLocation.symbol;
}
}
@@ -1935,7 +1935,7 @@ namespace ts {
combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) :
symbolFromModule || symbolFromVariable;
if (!symbol) {
const moduleName = getFullyQualifiedName(moduleSymbol);
const moduleName = getFullyQualifiedName(moduleSymbol, node);
const declarationName = declarationNameToString(name);
const suggestion = getSuggestedSymbolForNonexistentModule(name, targetSymbol);
if (suggestion !== undefined) {
@@ -2101,8 +2101,8 @@ namespace ts {
}
}
function getFullyQualifiedName(symbol: Symbol): string {
return symbol.parent ? getFullyQualifiedName(symbol.parent) + "." + symbolToString(symbol) : symbolToString(symbol);
function getFullyQualifiedName(symbol: Symbol, containingLocation?: Node): string {
return symbol.parent ? getFullyQualifiedName(symbol.parent, containingLocation) + "." + symbolToString(symbol) : symbolToString(symbol, containingLocation, /*meaning*/ undefined, SymbolFormatFlags.DoNotIncludeSymbolChain | SymbolFormatFlags.AllowAnyNodeKind);
}
/**
@@ -3078,6 +3078,9 @@ namespace ts {
if (flags & SymbolFormatFlags.UseAliasDefinedOutsideCurrentScope) {
nodeFlags |= NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope;
}
if (flags & SymbolFormatFlags.DoNotIncludeSymbolChain) {
nodeFlags |= NodeBuilderFlags.DoNotIncludeSymbolChain;
}
const builder = flags & SymbolFormatFlags.AllowAnyNodeKind ? nodeBuilder.symbolToExpression : nodeBuilder.symbolToEntityName;
return writer ? symbolToStringWorker(writer).getText() : usingSingleLineStringWriter(symbolToStringWorker);
@@ -3155,7 +3158,12 @@ namespace ts {
const context: NodeBuilderContext = {
enclosingDeclaration,
flags: flags || NodeBuilderFlags.None,
tracker: tracker && tracker.trackSymbol ? tracker : { trackSymbol: noop },
// If no full tracker is provided, fake up a dummy one with a basic limited-functionality moduleResolverHost
tracker: tracker && tracker.trackSymbol ? tracker : { trackSymbol: noop, moduleResolverHost: flags! & NodeBuilderFlags.DoNotIncludeSymbolChain ? {
getCommonSourceDirectory: (host as Program).getCommonSourceDirectory ? () => (host as Program).getCommonSourceDirectory() : () => "",
getSourceFiles: () => host.getSourceFiles(),
getCurrentDirectory: host.getCurrentDirectory && (() => host.getCurrentDirectory!())
} : undefined },
encounteredError: false,
visitedSymbols: undefined,
inferTypeParameters: undefined,
@@ -3308,6 +3316,9 @@ namespace ts {
}
if (type.flags & (TypeFlags.Union | TypeFlags.Intersection)) {
const types = type.flags & TypeFlags.Union ? formatUnionTypes((<UnionType>type).types) : (<IntersectionType>type).types;
if (length(types) === 1) {
return typeToTypeNodeHelper(types[0], context);
}
const typeNodes = mapToTypeNodes(types, context, /*isBareList*/ true);
if (typeNodes && typeNodes.length > 0) {
const unionOrIntersectionTypeNode = createUnionOrIntersectionTypeNode(type.flags & TypeFlags.Union ? SyntaxKind.UnionType : SyntaxKind.IntersectionType, typeNodes);
@@ -3882,7 +3893,7 @@ namespace ts {
// Try to get qualified name if the symbol is not a type parameter and there is an enclosing declaration.
let chain: Symbol[];
const isTypeParameter = symbol.flags & SymbolFlags.TypeParameter;
if (!isTypeParameter && (context.enclosingDeclaration || context.flags & NodeBuilderFlags.UseFullyQualifiedType)) {
if (!isTypeParameter && (context.enclosingDeclaration || context.flags & NodeBuilderFlags.UseFullyQualifiedType) && !(context.flags & NodeBuilderFlags.DoNotIncludeSymbolChain)) {
chain = Debug.assertDefined(getSymbolChain(symbol, meaning, /*endOfChain*/ true));
Debug.assert(chain && chain.length > 0);
}
@@ -4137,6 +4148,9 @@ namespace ts {
function createExpressionFromSymbolChain(chain: Symbol[], index: number): Expression {
const typeParameterNodes = lookupTypeParameterNodes(chain, index, context);
const symbol = chain[index];
if (some(symbol.declarations, hasNonGlobalAugmentationExternalModuleSymbol)) {
return createLiteral(getSpecifierForModuleSymbol(symbol, context));
}
if (index === 0) {
context.flags |= NodeBuilderFlags.InInitialEntityName;
@@ -4501,6 +4515,8 @@ namespace ts {
return !!(<Signature>target).resolvedReturnType;
case TypeSystemPropertyName.ImmediateBaseConstraint:
return !!(<Type>target).immediateBaseConstraint;
case TypeSystemPropertyName.JSDocTypeReference:
return !!getSymbolLinks(target as Symbol).resolvedJSDocType;
}
return Debug.assertNever(propertyName);
}
@@ -8273,7 +8289,7 @@ namespace ts {
return type;
}
// JS are 'string' or 'number', not an enum type.
// JS enums are 'string' or 'number', not an enum type.
const enumTag = isInJSFile(node) && symbol.valueDeclaration && getJSDocEnumTag(symbol.valueDeclaration);
if (enumTag) {
const links = getNodeLinks(enumTag);
@@ -8316,12 +8332,21 @@ namespace ts {
* the type of this reference is just the type of the value we resolved to.
*/
function getJSDocTypeReference(node: NodeWithTypeArguments, symbol: Symbol, typeArguments: Type[] | undefined): Type | undefined {
if (!pushTypeResolution(symbol, TypeSystemPropertyName.JSDocTypeReference)) {
return errorType;
}
const assignedType = getAssignedClassType(symbol);
const valueType = getTypeOfSymbol(symbol);
const referenceType = valueType.symbol && valueType.symbol !== symbol && !isInferredClassType(valueType) && getTypeReferenceTypeWorker(node, valueType.symbol, typeArguments);
if (!popTypeResolution()) {
getSymbolLinks(symbol).resolvedJSDocType = errorType;
error(node, Diagnostics.JSDoc_type_0_circularly_references_itself, symbolToString(symbol));
return errorType;
}
if (referenceType || assignedType) {
// TODO: GH#18217 (should the `|| assignedType` be at a lower precedence?)
return (referenceType && assignedType ? getIntersectionType([assignedType, referenceType]) : referenceType || assignedType)!;
const type = (referenceType && assignedType ? getIntersectionType([assignedType, referenceType]) : referenceType || assignedType)!;
return getSymbolLinks(symbol).resolvedJSDocType = type;
}
}
@@ -8458,7 +8483,7 @@ namespace ts {
symbol = resolveTypeReferenceName(getTypeReferenceName(node), meaning);
type = getTypeReferenceType(node, symbol);
}
// Cache both the resolved symbol and the resolved type. The resolved symbol is needed in when we check the
// Cache both the resolved symbol and the resolved type. The resolved symbol is needed when we check the
// type reference in checkTypeReferenceNode.
links.resolvedSymbol = symbol;
links.resolvedType = type;
@@ -9305,7 +9330,9 @@ namespace ts {
}
}
const propType = getTypeOfSymbol(prop);
return accessExpression ? getFlowTypeOfReference(accessExpression, propType) : propType;
return accessExpression && getAssignmentTargetKind(accessExpression) !== AssignmentKind.Definite ?
getFlowTypeOfReference(accessExpression, propType) :
propType;
}
if (isTupleType(objectType)) {
const restType = getRestTypeOfTupleType(objectType);
@@ -10618,7 +10645,7 @@ namespace ts {
target.flags & TypeFlags.Union ? some((<UnionType>target).types, t => isTypeDerivedFrom(source, t)) :
source.flags & TypeFlags.InstantiableNonPrimitive ? isTypeDerivedFrom(getBaseConstraintOfType(source) || emptyObjectType, target) :
target === globalObjectType ? !!(source.flags & (TypeFlags.Object | TypeFlags.NonPrimitive)) :
target === globalFunctionType ? isFunctionObjectType(source as ObjectType) :
target === globalFunctionType ? !!(source.flags & TypeFlags.Object) && isFunctionObjectType(source as ObjectType) :
hasBaseType(source, getTargetType(target));
}
@@ -11639,27 +11666,14 @@ namespace ts {
// Keep this up-to-date with the same logic within `getApparentTypeOfContextualType`, since they should behave similarly
function findMatchingDiscriminantType(source: Type, target: UnionOrIntersectionType) {
let match: Type | undefined;
const sourceProperties = getPropertiesOfObjectType(source);
if (sourceProperties) {
const sourcePropertiesFiltered = findDiscriminantProperties(sourceProperties, target);
if (sourcePropertiesFiltered) {
for (const sourceProperty of sourcePropertiesFiltered) {
const sourceType = getTypeOfSymbol(sourceProperty);
for (const type of target.types) {
const targetType = getTypeOfPropertyOfType(type, sourceProperty.escapedName);
if (targetType && isRelatedTo(sourceType, targetType)) {
if (type === match) continue; // Finding multiple fields which discriminate to the same type is fine
if (match) {
return undefined;
}
match = type;
}
}
}
return discriminateTypeByDiscriminableItems(target, map(sourcePropertiesFiltered, p => ([() => getTypeOfSymbol(p), p.escapedName] as [() => Type, __String])), isRelatedTo);
}
}
return match;
return undefined;
}
function typeRelatedToEachType(source: Type, target: IntersectionType, reportErrors: boolean): Ternary {
@@ -12474,6 +12488,25 @@ namespace ts {
}
}
function discriminateTypeByDiscriminableItems(target: UnionType, discriminators: [() => Type, __String][], related: (source: Type, target: Type) => boolean | Ternary): Type | undefined;
function discriminateTypeByDiscriminableItems(target: UnionType, discriminators: [() => Type, __String][], related: (source: Type, target: Type) => boolean | Ternary, defaultValue: Type): Type;
function discriminateTypeByDiscriminableItems(target: UnionType, discriminators: [() => Type, __String][], related: (source: Type, target: Type) => boolean | Ternary, defaultValue?: Type) {
let match: Type | undefined;
for (const [getDiscriminatingType, propertyName] of discriminators) {
for (const type of target.types) {
const targetType = getTypeOfPropertyOfType(type, propertyName);
if (targetType && related(getDiscriminatingType(), targetType)) {
if (match) {
if (type === match) continue; // Finding multiple fields which discriminate to the same type is fine
return defaultValue;
}
match = type;
}
}
}
return match || defaultValue;
}
/**
* A type is 'weak' if it is an object type with at least one optional property
* and no required properties, call/construct signatures or index signatures
@@ -14186,7 +14219,7 @@ namespace ts {
if ((<TransientSymbol>prop).isDiscriminantProperty === undefined) {
(<TransientSymbol>prop).isDiscriminantProperty = !!((<TransientSymbol>prop).checkFlags & CheckFlags.HasNonUniformType) && isLiteralType(getTypeOfSymbol(prop));
}
return (<TransientSymbol>prop).isDiscriminantProperty;
return !!(<TransientSymbol>prop).isDiscriminantProperty;
}
}
return false;
@@ -14950,9 +14983,12 @@ namespace ts {
}
function getTypeAtSwitchClause(flow: FlowSwitchClause): FlowType {
const expr = flow.switchStatement.expression;
if (containsMatchingReferenceDiscriminant(reference, expr)) {
return declaredType;
}
const flowType = getTypeAtFlowNode(flow.antecedent);
let type = getTypeFromFlowType(flowType);
const expr = flow.switchStatement.expression;
if (isMatchingReference(reference, expr)) {
type = narrowTypeBySwitchOnDiscriminant(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd);
}
@@ -16173,16 +16209,18 @@ namespace ts {
// // js
// ...
// asyncMethod() {
// const _super = name => super[name];
// const _super = Object.create(null, {
// asyncMethod: { get: () => super.asyncMethod },
// });
// return __awaiter(this, arguments, Promise, function *() {
// let x = yield _super("asyncMethod").call(this);
// let x = yield _super.asyncMethod.call(this);
// return x;
// });
// }
// ...
//
// The more complex case is when we wish to assign a value, especially as part of a destructuring assignment. As both cases
// are legal in ES6, but also likely less frequent, we emit the same more complex helper for both scenarios:
// are legal in ES6, but also likely less frequent, we only emit setters if there is an assignment:
//
// // ts
// ...
@@ -16194,19 +16232,20 @@ namespace ts {
// // js
// ...
// asyncMethod(ar) {
// const _super = (function (geti, seti) {
// const cache = Object.create(null);
// return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } });
// })(name => super[name], (name, value) => super[name] = value);
// const _super = Object.create(null, {
// a: { get: () => super.a, set: (v) => super.a = v },
// b: { get: () => super.b, set: (v) => super.b = v }
// };
// return __awaiter(this, arguments, Promise, function *() {
// [_super("a").value, _super("b").value] = yield ar;
// [_super.a, _super.b] = yield ar;
// });
// }
// ...
//
// This helper creates an object with a "value" property that wraps the `super` property or indexed access for both get and set.
// This is required for destructuring assignments, as a call expression cannot be used as the target of a destructuring assignment
// while a property access can.
// Creating an object that has getter and setters instead of just an accessor function is required for destructuring assignments
// as a call expression cannot be used as the target of a destructuring assignment while a property access can.
//
// For element access expressions (`super[x]`), we emit a generic helper that forwards the element access in both situations.
if (container.kind === SyntaxKind.MethodDeclaration && hasModifier(container, ModifierFlags.Async)) {
if (isSuperProperty(node.parent) && isAssignmentTarget(node.parent)) {
getNodeLinks(container).flags |= NodeCheckFlags.AsyncMethodWithSuperBinding;
@@ -16761,43 +16800,53 @@ namespace ts {
case SyntaxKind.FalseKeyword:
case SyntaxKind.NullKeyword:
case SyntaxKind.Identifier:
case SyntaxKind.UndefinedKeyword:
return true;
case SyntaxKind.PropertyAccessExpression:
case SyntaxKind.ParenthesizedExpression:
return isPossiblyDiscriminantValue((<PropertyAccessExpression | ParenthesizedExpression>node).expression);
case SyntaxKind.JsxExpression:
return !(node as JsxExpression).expression || isPossiblyDiscriminantValue((node as JsxExpression).expression!);
}
return false;
}
function discriminateContextualTypeByObjectMembers(node: ObjectLiteralExpression, contextualType: UnionType) {
return discriminateTypeByDiscriminableItems(contextualType,
map(
filter(node.properties, p => !!p.symbol && p.kind === SyntaxKind.PropertyAssignment && isPossiblyDiscriminantValue(p.initializer) && isDiscriminantProperty(contextualType, p.symbol.escapedName)),
prop => ([() => checkExpression((prop as PropertyAssignment).initializer), prop.symbol.escapedName] as [() => Type, __String])
),
isTypeAssignableTo,
contextualType
);
}
function discriminateContextualTypeByJSXAttributes(node: JsxAttributes, contextualType: UnionType) {
return discriminateTypeByDiscriminableItems(contextualType,
map(
filter(node.properties, p => !!p.symbol && p.kind === SyntaxKind.JsxAttribute && isDiscriminantProperty(contextualType, p.symbol.escapedName) && (!p.initializer || isPossiblyDiscriminantValue(p.initializer))),
prop => ([!(prop as JsxAttribute).initializer ? (() => trueType) : (() => checkExpression((prop as JsxAttribute).initializer!)), prop.symbol.escapedName] as [() => Type, __String])
),
isTypeAssignableTo,
contextualType
);
}
// Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily
// be "pushed" onto a node using the contextualType property.
function getApparentTypeOfContextualType(node: Expression): Type | undefined {
let contextualType = getContextualType(node);
contextualType = contextualType && mapType(contextualType, getApparentType);
if (!(contextualType && contextualType.flags & TypeFlags.Union && isObjectLiteralExpression(node))) {
return contextualType;
}
// Keep the below up-to-date with the work done within `isRelatedTo` by `findMatchingDiscriminantType`
let match: Type | undefined;
propLoop: for (const prop of node.properties) {
if (!prop.symbol) continue;
if (prop.kind !== SyntaxKind.PropertyAssignment) continue;
if (isPossiblyDiscriminantValue(prop.initializer) && isDiscriminantProperty(contextualType, prop.symbol.escapedName)) {
const discriminatingType = checkExpression(prop.initializer);
for (const type of (contextualType as UnionType).types) {
const targetType = getTypeOfPropertyOfType(type, prop.symbol.escapedName);
if (targetType && isTypeAssignableTo(discriminatingType, targetType)) {
if (match) {
if (type === match) continue; // Finding multiple fields which discriminate to the same type is fine
match = undefined;
break propLoop;
}
match = type;
}
}
if (contextualType && contextualType.flags & TypeFlags.Union) {
if (isObjectLiteralExpression(node)) {
return discriminateContextualTypeByObjectMembers(node, contextualType as UnionType);
}
else if (isJsxAttributes(node)) {
return discriminateContextualTypeByJSXAttributes(node, contextualType as UnionType);
}
}
return match || contextualType;
return contextualType;
}
/**
@@ -17189,31 +17238,14 @@ namespace ts {
const minLength = elementCount - (hasRestElement ? 1 : 0);
// If array literal is actually a destructuring pattern, mark it as an implied type. We do this such
// that we get the same behavior for "var [x, y] = []" and "[x, y] = []".
let tupleResult: Type | undefined;
if (inDestructuringPattern && minLength > 0) {
const type = cloneTypeReference(<TypeReference>createTupleType(elementTypes, minLength, hasRestElement));
type.pattern = node;
return type;
}
if (contextualType && contextualTypeIsTupleLikeType(contextualType)) {
const pattern = contextualType.pattern;
// If array literal is contextually typed by a binding pattern or an assignment pattern, pad the resulting
// tuple type with the corresponding binding or assignment element types to make the lengths equal.
if (!hasRestElement && pattern && (pattern.kind === SyntaxKind.ArrayBindingPattern || pattern.kind === SyntaxKind.ArrayLiteralExpression)) {
const patternElements = (<BindingPattern | ArrayLiteralExpression>pattern).elements;
for (let i = elementCount; i < patternElements.length; i++) {
const e = patternElements[i];
if (hasDefaultValue(e)) {
elementTypes.push((<TypeReference>contextualType).typeArguments![i]);
}
else if (i < patternElements.length - 1 || !(e.kind === SyntaxKind.BindingElement && (<BindingElement>e).dotDotDotToken || e.kind === SyntaxKind.SpreadElement)) {
if (e.kind !== SyntaxKind.OmittedExpression) {
error(e, Diagnostics.Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value);
}
elementTypes.push(strictNullChecks ? implicitNeverType : undefinedWideningType);
}
}
}
return createTupleType(elementTypes, minLength, hasRestElement);
else if (tupleResult = getArrayLiteralTupleTypeIfApplicable(elementTypes, contextualType, hasRestElement, elementCount)) {
return tupleResult;
}
else if (forceTuple) {
return createTupleType(elementTypes, minLength, hasRestElement);
@@ -17222,6 +17254,31 @@ namespace ts {
return getArrayLiteralType(elementTypes, UnionReduction.Subtype);
}
function getArrayLiteralTupleTypeIfApplicable(elementTypes: Type[], contextualType: Type | undefined, hasRestElement: boolean, elementCount = elementTypes.length) {
if (contextualType && contextualTypeIsTupleLikeType(contextualType)) {
const minLength = elementCount - (hasRestElement ? 1 : 0);
const pattern = contextualType.pattern;
// If array literal is contextually typed by a binding pattern or an assignment pattern, pad the resulting
// tuple type with the corresponding binding or assignment element types to make the lengths equal.
if (!hasRestElement && pattern && (pattern.kind === SyntaxKind.ArrayBindingPattern || pattern.kind === SyntaxKind.ArrayLiteralExpression)) {
const patternElements = (<BindingPattern | ArrayLiteralExpression>pattern).elements;
for (let i = elementCount; i < patternElements.length; i++) {
const e = patternElements[i];
if (hasDefaultValue(e)) {
elementTypes.push((<TypeReference>contextualType).typeArguments![i]);
}
else if (i < patternElements.length - 1 || !(e.kind === SyntaxKind.BindingElement && (<BindingElement>e).dotDotDotToken || e.kind === SyntaxKind.SpreadElement)) {
if (e.kind !== SyntaxKind.OmittedExpression) {
error(e, Diagnostics.Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value);
}
elementTypes.push(strictNullChecks ? implicitNeverType : undefinedWideningType);
}
}
}
return createTupleType(elementTypes, minLength, hasRestElement);
}
}
function getArrayLiteralType(elementTypes: Type[], unionReduction = UnionReduction.Literal) {
return createArrayType(elementTypes.length ?
getUnionType(elementTypes, unionReduction) :
@@ -17637,11 +17694,13 @@ namespace ts {
error(attributes, Diagnostics._0_are_specified_twice_The_attribute_named_0_will_be_overwritten, unescapeLeadingUnderscores(jsxChildrenPropertyName));
}
const contextualType = getApparentTypeOfContextualType(openingLikeElement.attributes);
const childrenContextualType = contextualType && getTypeOfPropertyOfContextualType(contextualType, jsxChildrenPropertyName);
// If there are children in the body of JSX element, create dummy attribute "children" with the union of children types so that it will pass the attribute checking process
const childrenPropSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, jsxChildrenPropertyName);
childrenPropSymbol.type = childrenTypes.length === 1 ?
childrenTypes[0] :
createArrayType(getUnionType(childrenTypes));
(getArrayLiteralTupleTypeIfApplicable(childrenTypes, childrenContextualType, /*hasRestElement*/ false) || createArrayType(getUnionType(childrenTypes)));
const childPropMap = createSymbolTable();
childPropMap.set(jsxChildrenPropertyName, childrenPropSymbol);
spread = getSpreadType(spread, createAnonymousType(attributes.symbol, childPropMap, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined),
@@ -20364,18 +20423,20 @@ namespace ts {
* file.
*/
function isJSConstructor(node: Declaration | undefined): boolean {
if (node && isInJSFile(node)) {
if (!node || !isInJSFile(node)) {
return false;
}
const func = isFunctionDeclaration(node) || isFunctionExpression(node) ? node :
isVariableDeclaration(node) && node.initializer && isFunctionExpression(node.initializer) ? node.initializer :
undefined;
if (func) {
// If the node has a @class tag, treat it like a constructor.
if (getJSDocClassTag(node)) return true;
// If the symbol of the node has members, treat it like a constructor.
const symbol = isFunctionDeclaration(node) || isFunctionExpression(node) ? getSymbolOfNode(node) :
isVariableDeclaration(node) && node.initializer && isFunctionExpression(node.initializer) ? getSymbolOfNode(node.initializer) :
undefined;
const symbol = getSymbolOfNode(func);
return !!symbol && symbol.members !== undefined;
}
return false;
}
@@ -20409,7 +20470,7 @@ namespace ts {
isBinaryExpression(decl.parent) && getSymbolOfNode(decl.parent.left) ||
isVariableDeclaration(decl.parent) && getSymbolOfNode(decl.parent));
const prototype = assignmentSymbol && assignmentSymbol.exports && assignmentSymbol.exports.get("prototype" as __String);
const init = prototype && getAssignedJSPrototype(prototype.valueDeclaration);
const init = prototype && prototype.valueDeclaration && getAssignedJSPrototype(prototype.valueDeclaration);
return init ? checkExpression(init) : undefined;
}
@@ -21211,6 +21272,7 @@ namespace ts {
function checkFunctionExpressionOrObjectLiteralMethod(node: FunctionExpression | MethodDeclaration, checkMode?: CheckMode): Type {
Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
checkNodeDeferred(node);
// The identityMapper object is used to indicate that function expressions are wildcards
if (checkMode === CheckMode.SkipContextSensitive && isContextSensitive(node)) {
@@ -21268,7 +21330,6 @@ namespace ts {
}
}
checkSignatureDeclaration(node);
checkNodeDeferred(node);
}
}
@@ -27341,14 +27402,21 @@ namespace ts {
// determining the type of foo would cause foo to be given type any because of the recursive reference.
// Delaying the type check of the body ensures foo has been assigned a type.
function checkNodeDeferred(node: Node) {
if (deferredNodes) {
const enclosingFile = getSourceFileOfNode(node);
const links = getNodeLinks(enclosingFile);
if (!(links.flags & NodeCheckFlags.TypeChecked)) {
links.deferredNodes = links.deferredNodes || createMap();
const id = "" + getNodeId(node);
deferredNodes.set(id, node);
links.deferredNodes.set(id, node);
}
}
function checkDeferredNodes() {
deferredNodes!.forEach(node => {
function checkDeferredNodes(context: SourceFile) {
const links = getNodeLinks(context);
if (!links.deferredNodes) {
return;
}
links.deferredNodes.forEach(node => {
switch (node.kind) {
case SyntaxKind.FunctionExpression:
case SyntaxKind.ArrowFunction:
@@ -27409,10 +27477,9 @@ namespace ts {
clear(potentialThisCollisions);
clear(potentialNewTargetCollisions);
deferredNodes = createMap<Node>();
forEach(node.statements, checkSourceElement);
checkDeferredNodes();
checkDeferredNodes(node);
if (isExternalOrCommonJsModule(node)) {
registerForUnusedIdentifiersCheck(node);
@@ -27426,8 +27493,6 @@ namespace ts {
});
}
deferredNodes = undefined;
if (isExternalOrCommonJsModule(node)) {
checkExternalModuleExports(node);
}
+4
View File
@@ -2116,6 +2116,10 @@
"category": "Error",
"code": 2586
},
"JSDoc type '{0}' circularly references itself.": {
"category": "Error",
"code": 2587
},
"JSX element attributes type '{0}' may not be a union type.": {
"category": "Error",
"code": 2600
+7 -3
View File
@@ -260,6 +260,9 @@ namespace ts.moduleSpecifiers {
}
function tryGetModuleNameAsNodeModule(moduleFileName: string, { getCanonicalFileName, sourceDirectory }: Info, host: ModuleSpecifierResolutionHost, options: CompilerOptions): string | undefined {
if (!host.fileExists || !host.readFile) {
return undefined;
}
const parts: NodeModulePathParts = getNodeModulePathParts(moduleFileName)!;
if (!parts) {
return undefined;
@@ -267,8 +270,8 @@ namespace ts.moduleSpecifiers {
const packageRootPath = moduleFileName.substring(0, parts.packageRootIndex);
const packageJsonPath = combinePaths(packageRootPath, "package.json");
const packageJsonContent = host.fileExists!(packageJsonPath)
? JSON.parse(host.readFile!(packageJsonPath)!)
const packageJsonContent = host.fileExists(packageJsonPath)
? JSON.parse(host.readFile(packageJsonPath)!)
: undefined;
const versionPaths = packageJsonContent && packageJsonContent.typesVersions
? getPackageJsonTypesVersionsPaths(packageJsonContent.typesVersions)
@@ -325,11 +328,12 @@ namespace ts.moduleSpecifiers {
}
function tryGetAnyFileFromPath(host: ModuleSpecifierResolutionHost, path: string) {
if (!host.fileExists) return;
// We check all js, `node` and `json` extensions in addition to TS, since node module resolution would also choose those over the directory
const extensions = getSupportedExtensions({ allowJs: true }, [{ extension: "node", isMixedContent: false }, { extension: "json", isMixedContent: false, scriptKind: ScriptKind.JSON }]);
for (const e of extensions) {
const fullPath = path + e;
if (host.fileExists!(fullPath)) { // TODO: GH#18217
if (host.fileExists(fullPath)) {
return fullPath;
}
}
+13 -19
View File
@@ -6308,7 +6308,7 @@ namespace ts {
// Parses out a JSDoc type expression.
export function parseJSDocTypeExpression(mayOmitBraces?: boolean): JSDocTypeExpression {
const result = <JSDocTypeExpression>createNode(SyntaxKind.JSDocTypeExpression, scanner.getTokenPos());
const result = <JSDocTypeExpression>createNode(SyntaxKind.JSDocTypeExpression);
const hasBrace = (mayOmitBraces ? parseOptional : parseExpected)(SyntaxKind.OpenBraceToken);
result.type = doInsideOfContext(NodeFlags.JSDoc, parseJSDocType);
@@ -6441,13 +6441,6 @@ namespace ts {
indent += asterisk.length;
}
break;
case SyntaxKind.Identifier:
// Anything else is doc comment text. We just save it. Because it
// wasn't a tag, we can no longer parse a tag on this line until we hit the next
// line break.
pushComment(scanner.getTokenText());
state = JSDocState.SavingComments;
break;
case SyntaxKind.WhitespaceTrivia:
// only collect whitespace if we're already saving comments or have just crossed the comment indent margin
const whitespace = scanner.getTokenText();
@@ -6462,7 +6455,9 @@ namespace ts {
case SyntaxKind.EndOfFileToken:
break loop;
default:
// anything other than whitespace or asterisk at the beginning of the line starts the comment text
// Anything else is doc comment text. We just save it. Because it
// wasn't a tag, we can no longer parse a tag on this line until we hit the next
// line break.
state = JSDocState.SavingComments;
pushComment(scanner.getTokenText());
break;
@@ -6517,7 +6512,7 @@ namespace ts {
}
}
function skipWhitespaceOrAsterisk(next: () => void): void {
function skipWhitespaceOrAsterisk(): void {
if (token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) {
if (lookAhead(isNextNonwhitespaceTokenEndOfFile)) {
return; // Don't skip whitespace prior to EoF (or end of comment) - that shouldn't be included in any node's range
@@ -6532,7 +6527,7 @@ namespace ts {
else if (token() === SyntaxKind.AsteriskToken) {
precedingLineBreak = false;
}
next();
nextJSDocToken();
}
}
@@ -6542,9 +6537,8 @@ namespace ts {
atToken.end = scanner.getTextPos();
nextJSDocToken();
// Use 'nextToken' instead of 'nextJsDocToken' so we can parse a type like 'number' in `@enum number`
const tagName = parseJSDocIdentifierName(/*message*/ undefined, nextToken);
skipWhitespaceOrAsterisk(nextToken);
const tagName = parseJSDocIdentifierName(/*message*/ undefined);
skipWhitespaceOrAsterisk();
let tag: JSDocTag | undefined;
switch (tagName.escapedText) {
@@ -6688,7 +6682,7 @@ namespace ts {
}
function tryParseTypeExpression(): JSDocTypeExpression | undefined {
skipWhitespaceOrAsterisk(nextJSDocToken);
skipWhitespaceOrAsterisk();
return token() === SyntaxKind.OpenBraceToken ? parseJSDocTypeExpression() : undefined;
}
@@ -6728,7 +6722,7 @@ namespace ts {
function parseParameterOrPropertyTag(atToken: AtToken, tagName: Identifier, target: PropertyLikeParse, indent: number): JSDocParameterTag | JSDocPropertyTag {
let typeExpression = tryParseTypeExpression();
let isNameFirst = !typeExpression;
skipWhitespaceOrAsterisk(nextJSDocToken);
skipWhitespaceOrAsterisk();
const { name, isBracketed } = parseBracketNameInPropertyAndParamTag();
skipWhitespace();
@@ -6862,7 +6856,7 @@ namespace ts {
function parseTypedefTag(atToken: AtToken, tagName: Identifier, indent: number): JSDocTypedefTag {
const typeExpression = tryParseTypeExpression();
skipWhitespaceOrAsterisk(nextJSDocToken);
skipWhitespaceOrAsterisk();
const typedefTag = <JSDocTypedefTag>createNode(SyntaxKind.JSDocTypedefTag, atToken.pos);
typedefTag.atToken = atToken;
@@ -7115,7 +7109,7 @@ namespace ts {
return entity;
}
function parseJSDocIdentifierName(message?: DiagnosticMessage, next: () => void = nextJSDocToken): Identifier {
function parseJSDocIdentifierName(message?: DiagnosticMessage): Identifier {
if (!tokenIsIdentifierOrKeyword(token())) {
return createMissingNode<Identifier>(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ !message, message || Diagnostics.Identifier_expected);
}
@@ -7126,7 +7120,7 @@ namespace ts {
result.escapedText = escapeLeadingUnderscores(scanner.getTokenText());
finishNode(result, end);
next();
nextJSDocToken();
return result;
}
}
+86 -80
View File
@@ -60,81 +60,87 @@ namespace ts {
tryScan<T>(callback: () => T): T;
}
const textToToken = createMapFromTemplate({
"abstract": SyntaxKind.AbstractKeyword,
"any": SyntaxKind.AnyKeyword,
"as": SyntaxKind.AsKeyword,
"boolean": SyntaxKind.BooleanKeyword,
"break": SyntaxKind.BreakKeyword,
"case": SyntaxKind.CaseKeyword,
"catch": SyntaxKind.CatchKeyword,
"class": SyntaxKind.ClassKeyword,
"continue": SyntaxKind.ContinueKeyword,
"const": SyntaxKind.ConstKeyword,
"constructor": SyntaxKind.ConstructorKeyword,
"debugger": SyntaxKind.DebuggerKeyword,
"declare": SyntaxKind.DeclareKeyword,
"default": SyntaxKind.DefaultKeyword,
"delete": SyntaxKind.DeleteKeyword,
"do": SyntaxKind.DoKeyword,
"else": SyntaxKind.ElseKeyword,
"enum": SyntaxKind.EnumKeyword,
"export": SyntaxKind.ExportKeyword,
"extends": SyntaxKind.ExtendsKeyword,
"false": SyntaxKind.FalseKeyword,
"finally": SyntaxKind.FinallyKeyword,
"for": SyntaxKind.ForKeyword,
"from": SyntaxKind.FromKeyword,
"function": SyntaxKind.FunctionKeyword,
"get": SyntaxKind.GetKeyword,
"if": SyntaxKind.IfKeyword,
"implements": SyntaxKind.ImplementsKeyword,
"import": SyntaxKind.ImportKeyword,
"in": SyntaxKind.InKeyword,
"infer": SyntaxKind.InferKeyword,
"instanceof": SyntaxKind.InstanceOfKeyword,
"interface": SyntaxKind.InterfaceKeyword,
"is": SyntaxKind.IsKeyword,
"keyof": SyntaxKind.KeyOfKeyword,
"let": SyntaxKind.LetKeyword,
"module": SyntaxKind.ModuleKeyword,
"namespace": SyntaxKind.NamespaceKeyword,
"never": SyntaxKind.NeverKeyword,
"new": SyntaxKind.NewKeyword,
"null": SyntaxKind.NullKeyword,
"number": SyntaxKind.NumberKeyword,
"object": SyntaxKind.ObjectKeyword,
"package": SyntaxKind.PackageKeyword,
"private": SyntaxKind.PrivateKeyword,
"protected": SyntaxKind.ProtectedKeyword,
"public": SyntaxKind.PublicKeyword,
"readonly": SyntaxKind.ReadonlyKeyword,
"require": SyntaxKind.RequireKeyword,
"global": SyntaxKind.GlobalKeyword,
"return": SyntaxKind.ReturnKeyword,
"set": SyntaxKind.SetKeyword,
"static": SyntaxKind.StaticKeyword,
"string": SyntaxKind.StringKeyword,
"super": SyntaxKind.SuperKeyword,
"switch": SyntaxKind.SwitchKeyword,
"symbol": SyntaxKind.SymbolKeyword,
"this": SyntaxKind.ThisKeyword,
"throw": SyntaxKind.ThrowKeyword,
"true": SyntaxKind.TrueKeyword,
"try": SyntaxKind.TryKeyword,
"type": SyntaxKind.TypeKeyword,
"typeof": SyntaxKind.TypeOfKeyword,
"undefined": SyntaxKind.UndefinedKeyword,
"unique": SyntaxKind.UniqueKeyword,
"unknown": SyntaxKind.UnknownKeyword,
"var": SyntaxKind.VarKeyword,
"void": SyntaxKind.VoidKeyword,
"while": SyntaxKind.WhileKeyword,
"with": SyntaxKind.WithKeyword,
"yield": SyntaxKind.YieldKeyword,
"async": SyntaxKind.AsyncKeyword,
"await": SyntaxKind.AwaitKeyword,
"of": SyntaxKind.OfKeyword,
const textToKeywordObj: MapLike<KeywordSyntaxKind> = {
abstract: SyntaxKind.AbstractKeyword,
any: SyntaxKind.AnyKeyword,
as: SyntaxKind.AsKeyword,
boolean: SyntaxKind.BooleanKeyword,
break: SyntaxKind.BreakKeyword,
case: SyntaxKind.CaseKeyword,
catch: SyntaxKind.CatchKeyword,
class: SyntaxKind.ClassKeyword,
continue: SyntaxKind.ContinueKeyword,
const: SyntaxKind.ConstKeyword,
["" + "constructor"]: SyntaxKind.ConstructorKeyword,
debugger: SyntaxKind.DebuggerKeyword,
declare: SyntaxKind.DeclareKeyword,
default: SyntaxKind.DefaultKeyword,
delete: SyntaxKind.DeleteKeyword,
do: SyntaxKind.DoKeyword,
else: SyntaxKind.ElseKeyword,
enum: SyntaxKind.EnumKeyword,
export: SyntaxKind.ExportKeyword,
extends: SyntaxKind.ExtendsKeyword,
false: SyntaxKind.FalseKeyword,
finally: SyntaxKind.FinallyKeyword,
for: SyntaxKind.ForKeyword,
from: SyntaxKind.FromKeyword,
function: SyntaxKind.FunctionKeyword,
get: SyntaxKind.GetKeyword,
if: SyntaxKind.IfKeyword,
implements: SyntaxKind.ImplementsKeyword,
import: SyntaxKind.ImportKeyword,
in: SyntaxKind.InKeyword,
infer: SyntaxKind.InferKeyword,
instanceof: SyntaxKind.InstanceOfKeyword,
interface: SyntaxKind.InterfaceKeyword,
is: SyntaxKind.IsKeyword,
keyof: SyntaxKind.KeyOfKeyword,
let: SyntaxKind.LetKeyword,
module: SyntaxKind.ModuleKeyword,
namespace: SyntaxKind.NamespaceKeyword,
never: SyntaxKind.NeverKeyword,
new: SyntaxKind.NewKeyword,
null: SyntaxKind.NullKeyword,
number: SyntaxKind.NumberKeyword,
object: SyntaxKind.ObjectKeyword,
package: SyntaxKind.PackageKeyword,
private: SyntaxKind.PrivateKeyword,
protected: SyntaxKind.ProtectedKeyword,
public: SyntaxKind.PublicKeyword,
readonly: SyntaxKind.ReadonlyKeyword,
require: SyntaxKind.RequireKeyword,
global: SyntaxKind.GlobalKeyword,
return: SyntaxKind.ReturnKeyword,
set: SyntaxKind.SetKeyword,
static: SyntaxKind.StaticKeyword,
string: SyntaxKind.StringKeyword,
super: SyntaxKind.SuperKeyword,
switch: SyntaxKind.SwitchKeyword,
symbol: SyntaxKind.SymbolKeyword,
this: SyntaxKind.ThisKeyword,
throw: SyntaxKind.ThrowKeyword,
true: SyntaxKind.TrueKeyword,
try: SyntaxKind.TryKeyword,
type: SyntaxKind.TypeKeyword,
typeof: SyntaxKind.TypeOfKeyword,
undefined: SyntaxKind.UndefinedKeyword,
unique: SyntaxKind.UniqueKeyword,
unknown: SyntaxKind.UnknownKeyword,
var: SyntaxKind.VarKeyword,
void: SyntaxKind.VoidKeyword,
while: SyntaxKind.WhileKeyword,
with: SyntaxKind.WithKeyword,
yield: SyntaxKind.YieldKeyword,
async: SyntaxKind.AsyncKeyword,
await: SyntaxKind.AwaitKeyword,
of: SyntaxKind.OfKeyword,
};
const textToKeyword = createMapFromTemplate(textToKeywordObj);
const textToToken = createMapFromTemplate<SyntaxKind>({
...textToKeywordObj,
"{": SyntaxKind.OpenBraceToken,
"}": SyntaxKind.CloseBraceToken,
"(": SyntaxKind.OpenParenToken,
@@ -1288,15 +1294,15 @@ namespace ts {
return result;
}
function getIdentifierToken(): SyntaxKind {
function getIdentifierToken(): SyntaxKind.Identifier | KeywordSyntaxKind {
// Reserved words are between 2 and 11 characters long and start with a lowercase letter
const len = tokenValue.length;
if (len >= 2 && len <= 11) {
const ch = tokenValue.charCodeAt(0);
if (ch >= CharacterCodes.a && ch <= CharacterCodes.z) {
token = textToToken.get(tokenValue)!;
if (token !== undefined) {
return token;
const keyword = textToKeyword.get(tokenValue);
if (keyword !== undefined) {
return token = keyword;
}
}
}
@@ -2016,7 +2022,7 @@ namespace ts {
pos++;
}
tokenValue = text.substring(tokenPos, pos);
return token = SyntaxKind.Identifier;
return token = getIdentifierToken();
}
else {
return token = SyntaxKind.Unknown;
+4 -5
View File
@@ -796,11 +796,10 @@ namespace ts {
dirName,
(_eventName: string, relativeFileName) => {
// When files are deleted from disk, the triggered "rename" event would have a relativefileName of "undefined"
const fileName = !isString(relativeFileName)
? undefined! // TODO: GH#18217
: getNormalizedAbsolutePath(relativeFileName, dirName);
if (!isString(relativeFileName)) { return; }
const fileName = getNormalizedAbsolutePath(relativeFileName, dirName);
// Some applications save a working file via rename operations
const callbacks = fileWatcherCallbacks.get(toCanonicalName(fileName));
const callbacks = fileName && fileWatcherCallbacks.get(toCanonicalName(fileName));
if (callbacks) {
for (const fileCallback of callbacks) {
fileCallback(fileName, FileWatcherEventKind.Changed);
@@ -847,7 +846,7 @@ namespace ts {
}
}
type FsWatchCallback = (eventName: "rename" | "change", relativeFileName: string) => void;
type FsWatchCallback = (eventName: "rename" | "change", relativeFileName: string | undefined) => void;
function createFileWatcherCallback(callback: FsWatchCallback): FileWatcherCallback {
return (_fileName, eventKind) => callback(eventKind === FileWatcherEventKind.Changed ? "change" : "rename", "");
@@ -466,4 +466,4 @@ namespace ts {
};
}
}
}
}
+144 -14
View File
@@ -32,6 +32,15 @@ namespace ts {
let enclosingFunctionParameterNames: UnderscoreEscapedMap<true>;
/**
* Keeps track of property names accessed on super (`super.x`) within async functions.
*/
let capturedSuperProperties: UnderscoreEscapedMap<true>;
/** Whether the async function contains an element access on super (`super[x]`). */
let hasSuperElementAccess: boolean;
/** A set of node IDs for generated super accessors (variable statements). */
const substitutedSuperAccessors: boolean[] = [];
// Save the previous transformation hooks.
const previousOnEmitNode = context.onEmitNode;
const previousOnSubstituteNode = context.onSubstituteNode;
@@ -56,7 +65,6 @@ namespace ts {
if ((node.transformFlags & TransformFlags.ContainsES2017) === 0) {
return node;
}
switch (node.kind) {
case SyntaxKind.AsyncKeyword:
// ES2017 async modifier should be elided for targets < ES2017
@@ -77,6 +85,18 @@ namespace ts {
case SyntaxKind.ArrowFunction:
return visitArrowFunction(<ArrowFunction>node);
case SyntaxKind.PropertyAccessExpression:
if (capturedSuperProperties && isPropertyAccessExpression(node) && node.expression.kind === SyntaxKind.SuperKeyword) {
capturedSuperProperties.set(node.name.escapedText, true);
}
return visitEachChild(node, visitor, context);
case SyntaxKind.ElementAccessExpression:
if (capturedSuperProperties && (<ElementAccessExpression>node).expression.kind === SyntaxKind.SuperKeyword) {
hasSuperElementAccess = true;
}
return visitEachChild(node, visitor, context);
default:
return visitEachChild(node, visitor, context);
}
@@ -398,6 +418,11 @@ namespace ts {
recordDeclarationName(parameter, enclosingFunctionParameterNames);
}
const savedCapturedSuperProperties = capturedSuperProperties;
const savedHasSuperElementAccess = hasSuperElementAccess;
capturedSuperProperties = createUnderscoreEscapedMap<true>();
hasSuperElementAccess = false;
let result: ConciseBody;
if (!isArrowFunction) {
const statements: Statement[] = [];
@@ -415,18 +440,26 @@ namespace ts {
addStatementsAfterPrologue(statements, endLexicalEnvironment());
// Minor optimization, emit `_super` helper to capture `super` access in an arrow.
// This step isn't needed if we eventually transform this to ES5.
const emitSuperHelpers = languageVersion >= ScriptTarget.ES2015 && resolver.getNodeCheckFlags(node) & (NodeCheckFlags.AsyncMethodWithSuperBinding | NodeCheckFlags.AsyncMethodWithSuper);
if (emitSuperHelpers) {
enableSubstitutionForAsyncMethodsWithSuper();
const variableStatement = createSuperAccessVariableStatement(resolver, node, capturedSuperProperties);
substitutedSuperAccessors[getNodeId(variableStatement)] = true;
addStatementsAfterPrologue(statements, [variableStatement]);
}
const block = createBlock(statements, /*multiLine*/ true);
setTextRange(block, node.body);
// Minor optimization, emit `_super` helper to capture `super` access in an arrow.
// This step isn't needed if we eventually transform this to ES5.
if (languageVersion >= ScriptTarget.ES2015) {
if (emitSuperHelpers && hasSuperElementAccess) {
// Emit helpers for super element access expressions (`super[x]`).
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuperBinding) {
enableSubstitutionForAsyncMethodsWithSuper();
addEmitHelper(block, advancedAsyncSuperHelper);
}
else if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuper) {
enableSubstitutionForAsyncMethodsWithSuper();
addEmitHelper(block, asyncSuperHelper);
}
}
@@ -452,6 +485,8 @@ namespace ts {
}
enclosingFunctionParameterNames = savedEnclosingFunctionParameterNames;
capturedSuperProperties = savedCapturedSuperProperties;
hasSuperElementAccess = savedHasSuperElementAccess;
return result;
}
@@ -493,6 +528,8 @@ namespace ts {
context.enableEmitNotification(SyntaxKind.GetAccessor);
context.enableEmitNotification(SyntaxKind.SetAccessor);
context.enableEmitNotification(SyntaxKind.Constructor);
// We need to be notified when entering the generated accessor arrow functions.
context.enableEmitNotification(SyntaxKind.VariableStatement);
}
}
@@ -516,6 +553,14 @@ namespace ts {
return;
}
}
// Disable substitution in the generated super accessor itself.
else if (enabledSubstitutions && substitutedSuperAccessors[getNodeId(node)]) {
const savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
enclosingSuperContainerFlags = 0;
previousOnEmitNode(hint, node, emitCallback);
enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags;
return;
}
previousOnEmitNode(hint, node, emitCallback);
}
@@ -548,8 +593,10 @@ namespace ts {
function substitutePropertyAccessExpression(node: PropertyAccessExpression) {
if (node.expression.kind === SyntaxKind.SuperKeyword) {
return createSuperAccessInAsyncMethod(
createLiteral(idText(node.name)),
return setTextRange(
createPropertyAccess(
createFileLevelUniqueName("_super"),
node.name),
node
);
}
@@ -558,7 +605,7 @@ namespace ts {
function substituteElementAccessExpression(node: ElementAccessExpression) {
if (node.expression.kind === SyntaxKind.SuperKeyword) {
return createSuperAccessInAsyncMethod(
return createSuperElementAccessInAsyncMethod(
node.argumentExpression,
node
);
@@ -593,12 +640,12 @@ namespace ts {
|| kind === SyntaxKind.SetAccessor;
}
function createSuperAccessInAsyncMethod(argumentExpression: Expression, location: TextRange): LeftHandSideExpression {
function createSuperElementAccessInAsyncMethod(argumentExpression: Expression, location: TextRange): LeftHandSideExpression {
if (enclosingSuperContainerFlags & NodeCheckFlags.AsyncMethodWithSuperBinding) {
return setTextRange(
createPropertyAccess(
createCall(
createFileLevelUniqueName("_super"),
createFileLevelUniqueName("_superIndex"),
/*typeArguments*/ undefined,
[argumentExpression]
),
@@ -610,7 +657,7 @@ namespace ts {
else {
return setTextRange(
createCall(
createFileLevelUniqueName("_super"),
createFileLevelUniqueName("_superIndex"),
/*typeArguments*/ undefined,
[argumentExpression]
),
@@ -620,6 +667,89 @@ namespace ts {
}
}
/** Creates a variable named `_super` with accessor properties for the given property names. */
export function createSuperAccessVariableStatement(resolver: EmitResolver, node: FunctionLikeDeclaration, names: UnderscoreEscapedMap<true>) {
// Create a variable declaration with a getter/setter (if binding) definition for each name:
// const _super = Object.create(null, { x: { get: () => super.x, set: (v) => super.x = v }, ... });
const hasBinding = (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuperBinding) !== 0;
const accessors: PropertyAssignment[] = [];
names.forEach((_, key) => {
const name = unescapeLeadingUnderscores(key);
const getterAndSetter: PropertyAssignment[] = [];
getterAndSetter.push(createPropertyAssignment(
"get",
createArrowFunction(
/* modifiers */ undefined,
/* typeParameters */ undefined,
/* parameters */ [],
/* type */ undefined,
/* equalsGreaterThanToken */ undefined,
createPropertyAccess(
createSuper(),
name
)
)
));
if (hasBinding) {
getterAndSetter.push(
createPropertyAssignment(
"set",
createArrowFunction(
/* modifiers */ undefined,
/* typeParameters */ undefined,
/* parameters */ [
createParameter(
/* decorators */ undefined,
/* modifiers */ undefined,
/* dotDotDotToken */ undefined,
"v",
/* questionToken */ undefined,
/* type */ undefined,
/* initializer */ undefined
)
],
/* type */ undefined,
/* equalsGreaterThanToken */ undefined,
createAssignment(
createPropertyAccess(
createSuper(),
name),
createIdentifier("v")
)
)
)
);
}
accessors.push(
createPropertyAssignment(
name,
createObjectLiteral(getterAndSetter),
)
);
});
return createVariableStatement(
/* modifiers */ undefined,
createVariableDeclarationList(
[
createVariableDeclaration(
createFileLevelUniqueName("_super"),
/* type */ undefined,
createCall(
createPropertyAccess(
createIdentifier("Object"),
"create"
),
/* typeArguments */ undefined,
[
createNull(),
createObjectLiteral(accessors, /* multiline */ true)
]
)
)
],
NodeFlags.Const));
}
const awaiterHelper: EmitHelper = {
name: "typescript:awaiter",
scoped: false,
@@ -667,14 +797,14 @@ namespace ts {
name: "typescript:async-super",
scoped: true,
text: helperString`
const ${"_super"} = name => super[name];`
const ${"_superIndex"} = name => super[name];`
};
export const advancedAsyncSuperHelper: EmitHelper = {
name: "typescript:advanced-async-super",
scoped: true,
text: helperString`
const ${"_super"} = (function (geti, seti) {
const ${"_superIndex"} = (function (geti, seti) {
const cache = Object.create(null);
return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } });
})(name => super[name], (name, value) => super[name] = value);`
+71 -27
View File
@@ -26,6 +26,13 @@ namespace ts {
let enclosingFunctionFlags: FunctionFlags;
let enclosingSuperContainerFlags: NodeCheckFlags = 0;
/** Keeps track of property names accessed on super (`super.x`) within async functions. */
let capturedSuperProperties: UnderscoreEscapedMap<true>;
/** Whether the async function contains an element access on super (`super[x]`). */
let hasSuperElementAccess: boolean;
/** A set of node IDs for generated super accessors. */
const substitutedSuperAccessors: boolean[] = [];
return chainBundle(transformSourceFile);
function transformSourceFile(node: SourceFile) {
@@ -57,7 +64,6 @@ namespace ts {
if ((node.transformFlags & TransformFlags.ContainsESNext) === 0) {
return node;
}
switch (node.kind) {
case SyntaxKind.AwaitExpression:
return visitAwaitExpression(node as AwaitExpression);
@@ -101,6 +107,16 @@ namespace ts {
return visitParenthesizedExpression(node as ParenthesizedExpression, noDestructuringValue);
case SyntaxKind.CatchClause:
return visitCatchClause(node as CatchClause);
case SyntaxKind.PropertyAccessExpression:
if (capturedSuperProperties && isPropertyAccessExpression(node) && node.expression.kind === SyntaxKind.SuperKeyword) {
capturedSuperProperties.set(node.name.escapedText, true);
}
return visitEachChild(node, visitor, context);
case SyntaxKind.ElementAccessExpression:
if (capturedSuperProperties && (<ElementAccessExpression>node).expression.kind === SyntaxKind.SuperKeyword) {
hasSuperElementAccess = true;
}
return visitEachChild(node, visitor, context);
default:
return visitEachChild(node, visitor, context);
}
@@ -655,41 +671,57 @@ namespace ts {
const statementOffset = addPrologue(statements, node.body!.statements, /*ensureUseStrict*/ false, visitor);
appendObjectRestAssignmentsIfNeeded(statements, node);
statements.push(
createReturn(
createAsyncGeneratorHelper(
context,
createFunctionExpression(
/*modifiers*/ undefined,
createToken(SyntaxKind.AsteriskToken),
node.name && getGeneratedNameForNode(node.name),
/*typeParameters*/ undefined,
/*parameters*/ [],
/*type*/ undefined,
updateBlock(
node.body!,
visitLexicalEnvironment(node.body!.statements, visitor, context, statementOffset)
)
const savedCapturedSuperProperties = capturedSuperProperties;
const savedHasSuperElementAccess = hasSuperElementAccess;
capturedSuperProperties = createUnderscoreEscapedMap<true>();
hasSuperElementAccess = false;
const returnStatement = createReturn(
createAsyncGeneratorHelper(
context,
createFunctionExpression(
/*modifiers*/ undefined,
createToken(SyntaxKind.AsteriskToken),
node.name && getGeneratedNameForNode(node.name),
/*typeParameters*/ undefined,
/*parameters*/ [],
/*type*/ undefined,
updateBlock(
node.body!,
visitLexicalEnvironment(node.body!.statements, visitor, context, statementOffset)
)
)
)
);
// Minor optimization, emit `_super` helper to capture `super` access in an arrow.
// This step isn't needed if we eventually transform this to ES5.
const emitSuperHelpers = languageVersion >= ScriptTarget.ES2015 && resolver.getNodeCheckFlags(node) & (NodeCheckFlags.AsyncMethodWithSuperBinding | NodeCheckFlags.AsyncMethodWithSuper);
if (emitSuperHelpers) {
enableSubstitutionForAsyncMethodsWithSuper();
const variableStatement = createSuperAccessVariableStatement(resolver, node, capturedSuperProperties);
substitutedSuperAccessors[getNodeId(variableStatement)] = true;
addStatementsAfterPrologue(statements, [variableStatement]);
}
statements.push(returnStatement);
addStatementsAfterPrologue(statements, endLexicalEnvironment());
const block = updateBlock(node.body!, statements);
// Minor optimization, emit `_super` helper to capture `super` access in an arrow.
// This step isn't needed if we eventually transform this to ES5.
if (languageVersion >= ScriptTarget.ES2015) {
if (emitSuperHelpers && hasSuperElementAccess) {
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuperBinding) {
enableSubstitutionForAsyncMethodsWithSuper();
addEmitHelper(block, advancedAsyncSuperHelper);
}
else if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuper) {
enableSubstitutionForAsyncMethodsWithSuper();
addEmitHelper(block, asyncSuperHelper);
}
}
capturedSuperProperties = savedCapturedSuperProperties;
hasSuperElementAccess = savedHasSuperElementAccess;
return block;
}
@@ -758,6 +790,8 @@ namespace ts {
context.enableEmitNotification(SyntaxKind.GetAccessor);
context.enableEmitNotification(SyntaxKind.SetAccessor);
context.enableEmitNotification(SyntaxKind.Constructor);
// We need to be notified when entering the generated accessor arrow functions.
context.enableEmitNotification(SyntaxKind.VariableStatement);
}
}
@@ -781,6 +815,14 @@ namespace ts {
return;
}
}
// Disable substitution in the generated super accessor itself.
else if (enabledSubstitutions && substitutedSuperAccessors[getNodeId(node)]) {
const savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
enclosingSuperContainerFlags = 0 as NodeCheckFlags;
previousOnEmitNode(hint, node, emitCallback);
enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags;
return;
}
previousOnEmitNode(hint, node, emitCallback);
}
@@ -813,8 +855,10 @@ namespace ts {
function substitutePropertyAccessExpression(node: PropertyAccessExpression) {
if (node.expression.kind === SyntaxKind.SuperKeyword) {
return createSuperAccessInAsyncMethod(
createLiteral(idText(node.name)),
return setTextRange(
createPropertyAccess(
createFileLevelUniqueName("_super"),
node.name),
node
);
}
@@ -823,7 +867,7 @@ namespace ts {
function substituteElementAccessExpression(node: ElementAccessExpression) {
if (node.expression.kind === SyntaxKind.SuperKeyword) {
return createSuperAccessInAsyncMethod(
return createSuperElementAccessInAsyncMethod(
node.argumentExpression,
node
);
@@ -858,12 +902,12 @@ namespace ts {
|| kind === SyntaxKind.SetAccessor;
}
function createSuperAccessInAsyncMethod(argumentExpression: Expression, location: TextRange): LeftHandSideExpression {
function createSuperElementAccessInAsyncMethod(argumentExpression: Expression, location: TextRange): LeftHandSideExpression {
if (enclosingSuperContainerFlags & NodeCheckFlags.AsyncMethodWithSuperBinding) {
return setTextRange(
createPropertyAccess(
createCall(
createIdentifier("_super"),
createIdentifier("_superIndex"),
/*typeArguments*/ undefined,
[argumentExpression]
),
@@ -875,7 +919,7 @@ namespace ts {
else {
return setTextRange(
createCall(
createIdentifier("_super"),
createIdentifier("_superIndex"),
/*typeArguments*/ undefined,
[argumentExpression]
),
+87 -3
View File
@@ -24,7 +24,84 @@ namespace ts {
| SyntaxKind.DotToken
| SyntaxKind.Identifier
| SyntaxKind.NoSubstitutionTemplateLiteral
| SyntaxKind.Unknown;
| SyntaxKind.Unknown
| KeywordSyntaxKind;
export type KeywordSyntaxKind =
| SyntaxKind.AbstractKeyword
| SyntaxKind.AnyKeyword
| SyntaxKind.AsKeyword
| SyntaxKind.BooleanKeyword
| SyntaxKind.BreakKeyword
| SyntaxKind.CaseKeyword
| SyntaxKind.CatchKeyword
| SyntaxKind.ClassKeyword
| SyntaxKind.ContinueKeyword
| SyntaxKind.ConstKeyword
| SyntaxKind.ConstructorKeyword
| SyntaxKind.DebuggerKeyword
| SyntaxKind.DeclareKeyword
| SyntaxKind.DefaultKeyword
| SyntaxKind.DeleteKeyword
| SyntaxKind.DoKeyword
| SyntaxKind.ElseKeyword
| SyntaxKind.EnumKeyword
| SyntaxKind.ExportKeyword
| SyntaxKind.ExtendsKeyword
| SyntaxKind.FalseKeyword
| SyntaxKind.FinallyKeyword
| SyntaxKind.ForKeyword
| SyntaxKind.FromKeyword
| SyntaxKind.FunctionKeyword
| SyntaxKind.GetKeyword
| SyntaxKind.IfKeyword
| SyntaxKind.ImplementsKeyword
| SyntaxKind.ImportKeyword
| SyntaxKind.InKeyword
| SyntaxKind.InferKeyword
| SyntaxKind.InstanceOfKeyword
| SyntaxKind.InterfaceKeyword
| SyntaxKind.IsKeyword
| SyntaxKind.KeyOfKeyword
| SyntaxKind.LetKeyword
| SyntaxKind.ModuleKeyword
| SyntaxKind.NamespaceKeyword
| SyntaxKind.NeverKeyword
| SyntaxKind.NewKeyword
| SyntaxKind.NullKeyword
| SyntaxKind.NumberKeyword
| SyntaxKind.ObjectKeyword
| SyntaxKind.PackageKeyword
| SyntaxKind.PrivateKeyword
| SyntaxKind.ProtectedKeyword
| SyntaxKind.PublicKeyword
| SyntaxKind.ReadonlyKeyword
| SyntaxKind.RequireKeyword
| SyntaxKind.GlobalKeyword
| SyntaxKind.ReturnKeyword
| SyntaxKind.SetKeyword
| SyntaxKind.StaticKeyword
| SyntaxKind.StringKeyword
| SyntaxKind.SuperKeyword
| SyntaxKind.SwitchKeyword
| SyntaxKind.SymbolKeyword
| SyntaxKind.ThisKeyword
| SyntaxKind.ThrowKeyword
| SyntaxKind.TrueKeyword
| SyntaxKind.TryKeyword
| SyntaxKind.TypeKeyword
| SyntaxKind.TypeOfKeyword
| SyntaxKind.UndefinedKeyword
| SyntaxKind.UniqueKeyword
| SyntaxKind.UnknownKeyword
| SyntaxKind.VarKeyword
| SyntaxKind.VoidKeyword
| SyntaxKind.WhileKeyword
| SyntaxKind.WithKeyword
| SyntaxKind.YieldKeyword
| SyntaxKind.AsyncKeyword
| SyntaxKind.AwaitKeyword
| SyntaxKind.OfKeyword;
export type JsxTokenSyntaxKind =
| SyntaxKind.LessThanSlashToken
@@ -2912,7 +2989,7 @@ namespace ts {
}
/* @internal */
export interface TypeCheckerHost {
export interface TypeCheckerHost extends ModuleSpecifierResolutionHost {
getCompilerOptions(): CompilerOptions;
getSourceFiles(): ReadonlyArray<SourceFile>;
@@ -3187,6 +3264,8 @@ namespace ts {
InTypeAlias = 1 << 23, // Writing type in type alias declaration
InInitialEntityName = 1 << 24, // Set when writing the LHS of an entity name or entity name expression
InReverseMappedType = 1 << 25,
/* @internal */ DoNotIncludeSymbolChain = 1 << 26, // Skip looking up and printing an accessible symbol chain
}
// Ensure the shared flags between this and `NodeBuilderFlags` stay in alignment
@@ -3249,6 +3328,9 @@ namespace ts {
// Prefer aliases which are not directly visible
UseAliasDefinedOutsideCurrentScope = 0x00000008,
// Skip building an accessible symbol chain
/* @internal */ DoNotIncludeSymbolChain = 0x00000010,
}
/* @internal */
@@ -3540,6 +3622,7 @@ namespace ts {
type?: Type; // Type of value symbol
uniqueESSymbolType?: Type; // UniqueESSymbol type for a symbol
declaredType?: Type; // Type of class, interface, enum, type alias, or type parameter
resolvedJSDocType?: Type; // Resolved type of a JSDoc type reference
typeParameters?: TypeParameter[]; // Type parameters of type alias (undefined if non-generic)
outerTypeParameters?: TypeParameter[]; // Outer type parameters of anonymous object type
inferredClassType?: Type; // Type of an inferred ES5 class
@@ -3706,6 +3789,7 @@ namespace ts {
switchTypes?: Type[]; // Cached array of switch case expression types
jsxNamespace?: Symbol | false; // Resolved jsx namespace symbol for this node
contextFreeType?: Type; // Cached context-free type used by the first pass of inference; used when a function's return is partially contextually sensitive
deferredNodes?: Map<Node>; // Set of nodes whose checking has been deferred
capturedBlockScopeBindings?: Symbol[]; // Block-scoped bindings captured beneath this part of an IterationStatement
}
@@ -5381,7 +5465,7 @@ namespace ts {
reportInaccessibleThisError?(): void;
reportPrivateInBaseOfClassExpression?(propertyName: string): void;
reportInaccessibleUniqueSymbolError?(): void;
moduleResolverHost?: EmitHost;
moduleResolverHost?: ModuleSpecifierResolutionHost & { getSourceFiles(): ReadonlyArray<SourceFile>, getCommonSourceDirectory(): string };
trackReferencedAmbientModule?(decl: ModuleDeclaration, symbol: Symbol): void;
trackExternalModuleSymbolOfImportTypeNode?(symbol: Symbol): void;
}
+1
View File
@@ -978,6 +978,7 @@ namespace ts {
case SyntaxKind.StringKeyword:
case SyntaxKind.BooleanKeyword:
case SyntaxKind.SymbolKeyword:
case SyntaxKind.ObjectKeyword:
case SyntaxKind.UndefinedKeyword:
case SyntaxKind.NeverKeyword:
return true;
+6 -2
View File
@@ -2516,10 +2516,10 @@ Actual: ${stringify(fullActual)}`);
* @param expectedContents The contents of the file after the fixes are applied.
* @param fileName The file to check. If not supplied, the current open file is used.
*/
public verifyFileAfterCodeFix(expectedContents: string, fileName?: string) {
public verifyFileAfterCodeFix(expectedContents: string, fileName?: string, index?: number) {
fileName = fileName ? fileName : this.activeFile.fileName;
this.applyCodeActions(this.getCodeFixes(fileName));
this.applyCodeActions(this.getCodeFixes(fileName), index);
const actualContents: string = this.getFileContent(fileName);
if (this.removeWhitespace(actualContents) !== this.removeWhitespace(expectedContents)) {
@@ -4388,6 +4388,10 @@ namespace FourSlashInterface {
this.state.verifyRangeAfterCodeFix(expectedText, includeWhiteSpace, errorCode, index);
}
public fileAfterCodeFix(expectedContents: string, fileName?: string, index?: number) {
this.state.verifyFileAfterCodeFix(expectedContents, fileName, index);
}
public codeFixAll(options: VerifyCodeFixAllOptions): void {
this.state.verifyCodeFixAll(options);
}
+71 -18
View File
@@ -5,6 +5,8 @@ namespace ts.server {
// tslint:disable variable-name
export const ProjectsUpdatedInBackgroundEvent = "projectsUpdatedInBackground";
export const ProjectLoadingStartEvent = "projectLoadingStart";
export const ProjectLoadingFinishEvent = "projectLoadingFinish";
export const SurveyReady = "surveyReady";
export const LargeFileReferencedEvent = "largeFileReferenced";
export const ConfigFileDiagEvent = "configFileDiag";
@@ -18,6 +20,16 @@ namespace ts.server {
data: { openFiles: string[]; };
}
export interface ProjectLoadingStartEvent {
eventName: typeof ProjectLoadingStartEvent;
data: { project: Project; reason: string; };
}
export interface ProjectLoadingFinishEvent {
eventName: typeof ProjectLoadingFinishEvent;
data: { project: Project; };
}
export interface SurveyReady {
eventName: typeof SurveyReady;
data: { surveyId: string; };
@@ -122,7 +134,15 @@ namespace ts.server {
readonly checkJs: boolean;
}
export type ProjectServiceEvent = LargeFileReferencedEvent | SurveyReady | ProjectsUpdatedInBackgroundEvent | ConfigFileDiagEvent | ProjectLanguageServiceStateEvent | ProjectInfoTelemetryEvent | OpenFileInfoTelemetryEvent;
export type ProjectServiceEvent = LargeFileReferencedEvent |
SurveyReady |
ProjectsUpdatedInBackgroundEvent |
ProjectLoadingStartEvent |
ProjectLoadingFinishEvent |
ConfigFileDiagEvent |
ProjectLanguageServiceStateEvent |
ProjectInfoTelemetryEvent |
OpenFileInfoTelemetryEvent;
export type ProjectServiceEventHandler = (event: ProjectServiceEvent) => void;
@@ -721,6 +741,33 @@ namespace ts.server {
this.eventHandler(event);
}
/* @internal */
sendProjectLoadingStartEvent(project: ConfiguredProject, reason: string) {
if (!this.eventHandler) {
return;
}
project.sendLoadingProjectFinish = true;
const event: ProjectLoadingStartEvent = {
eventName: ProjectLoadingStartEvent,
data: { project, reason }
};
this.eventHandler(event);
}
/* @internal */
sendProjectLoadingFinishEvent(project: ConfiguredProject) {
if (!this.eventHandler || !project.sendLoadingProjectFinish) {
return;
}
project.sendLoadingProjectFinish = false;
const event: ProjectLoadingFinishEvent = {
eventName: ProjectLoadingFinishEvent,
data: { project }
};
this.eventHandler(event);
}
/* @internal */
delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(project: Project) {
this.delayUpdateProjectGraph(project);
@@ -960,6 +1007,7 @@ namespace ts.server {
else {
this.logConfigFileWatchUpdate(project.getConfigFilePath(), project.canonicalConfigFilePath, configFileExistenceInfo, ConfigFileWatcherStatus.ReloadingInferredRootFiles);
project.pendingReload = ConfigFileProgramReloadLevel.Full;
project.pendingReloadReason = "Change in config file detected";
this.delayUpdateProjectGraph(project);
// As we scheduled the update on configured project graph,
// we would need to schedule the project reload for only the root of inferred projects
@@ -1618,22 +1666,23 @@ namespace ts.server {
}
/* @internal */
private createConfiguredProjectWithDelayLoad(configFileName: NormalizedPath) {
private createConfiguredProjectWithDelayLoad(configFileName: NormalizedPath, reason: string) {
const project = this.createConfiguredProject(configFileName);
project.pendingReload = ConfigFileProgramReloadLevel.Full;
project.pendingReloadReason = reason;
return project;
}
/* @internal */
private createAndLoadConfiguredProject(configFileName: NormalizedPath) {
private createAndLoadConfiguredProject(configFileName: NormalizedPath, reason: string) {
const project = this.createConfiguredProject(configFileName);
this.loadConfiguredProject(project);
this.loadConfiguredProject(project, reason);
return project;
}
/* @internal */
private createLoadAndUpdateConfiguredProject(configFileName: NormalizedPath) {
const project = this.createAndLoadConfiguredProject(configFileName);
private createLoadAndUpdateConfiguredProject(configFileName: NormalizedPath, reason: string) {
const project = this.createAndLoadConfiguredProject(configFileName, reason);
project.updateGraph();
return project;
}
@@ -1642,7 +1691,9 @@ namespace ts.server {
* Read the config file of the project, and update the project root file names.
*/
/* @internal */
private loadConfiguredProject(project: ConfiguredProject) {
private loadConfiguredProject(project: ConfiguredProject, reason: string) {
this.sendProjectLoadingStartEvent(project, reason);
// Read updated contents from disk
const configFilename = normalizePath(project.getConfigFilePath());
@@ -1781,7 +1832,7 @@ namespace ts.server {
* Read the config file of the project again by clearing the cache and update the project graph
*/
/* @internal */
reloadConfiguredProject(project: ConfiguredProject) {
reloadConfiguredProject(project: ConfiguredProject, reason: string) {
// At this point, there is no reason to not have configFile in the host
const host = project.getCachedDirectoryStructureHost();
@@ -1791,7 +1842,7 @@ namespace ts.server {
this.logger.info(`Reloading configured project ${configFileName}`);
// Load project from the disk
this.loadConfiguredProject(project);
this.loadConfiguredProject(project, reason);
project.updateGraph();
this.sendConfigFileDiagEvent(project, configFileName);
@@ -2144,7 +2195,6 @@ namespace ts.server {
if (project.hasExternalProjectRef() &&
project.pendingReload === ConfigFileProgramReloadLevel.Full &&
!this.pendingProjectUpdates.has(project.getProjectName())) {
this.loadConfiguredProject(project);
project.updateGraph();
}
});
@@ -2176,7 +2226,7 @@ namespace ts.server {
// as there is no need to load contents of the files from the disk
// Reload Projects
this.reloadConfiguredProjectForFiles(this.openFiles, /*delayReload*/ false, returnTrue);
this.reloadConfiguredProjectForFiles(this.openFiles, /*delayReload*/ false, returnTrue, "User requested reload projects");
this.ensureProjectForOpenFiles();
}
@@ -2187,7 +2237,8 @@ namespace ts.server {
/*delayReload*/ true,
ignoreIfNotRootOfInferredProject ?
isRootOfInferredProject => isRootOfInferredProject : // Reload open files if they are root of inferred project
returnTrue // Reload all the open files impacted by config file
returnTrue, // Reload all the open files impacted by config file
"Change in config file detected"
);
this.delayEnsureProjectForOpenFiles();
}
@@ -2199,7 +2250,7 @@ namespace ts.server {
* If the there is no existing project it just opens the configured project for the config file
* reloadForInfo provides a way to filter out files to reload configured project for
*/
private reloadConfiguredProjectForFiles<T>(openFiles: Map<T>, delayReload: boolean, shouldReloadProjectFor: (openFileValue: T) => boolean) {
private reloadConfiguredProjectForFiles<T>(openFiles: Map<T>, delayReload: boolean, shouldReloadProjectFor: (openFileValue: T) => boolean, reason: string) {
const updatedProjects = createMap<true>();
// try to reload config file for all open files
openFiles.forEach((openFileValue, path) => {
@@ -2220,11 +2271,12 @@ namespace ts.server {
if (!updatedProjects.has(configFileName)) {
if (delayReload) {
project.pendingReload = ConfigFileProgramReloadLevel.Full;
project.pendingReloadReason = reason;
this.delayUpdateProjectGraph(project);
}
else {
// reload from the disk
this.reloadConfiguredProject(project);
this.reloadConfiguredProject(project, reason);
}
updatedProjects.set(configFileName, true);
}
@@ -2311,7 +2363,8 @@ namespace ts.server {
const configFileName = this.getConfigFileNameForFile(originalFileInfo);
if (!configFileName) return undefined;
const configuredProject = this.findConfiguredProjectByProjectName(configFileName) || this.createAndLoadConfiguredProject(configFileName);
const configuredProject = this.findConfiguredProjectByProjectName(configFileName) ||
this.createAndLoadConfiguredProject(configFileName, `Creating project for original file: ${originalFileInfo.fileName} for location: ${location.fileName}`);
updateProjectIfDirty(configuredProject);
// Keep this configured project as referenced from project
addOriginalConfiguredProject(configuredProject);
@@ -2361,7 +2414,7 @@ namespace ts.server {
if (configFileName) {
project = this.findConfiguredProjectByProjectName(configFileName);
if (!project) {
project = this.createLoadAndUpdateConfiguredProject(configFileName);
project = this.createLoadAndUpdateConfiguredProject(configFileName, `Creating possible configured project for ${fileName} to open`);
// Send the event only if the project got created as part of this open request and info is part of the project
if (info.isOrphan()) {
// Since the file isnt part of configured project, do not send config file info
@@ -2799,8 +2852,8 @@ namespace ts.server {
if (!project) {
// errors are stored in the project, do not need to update the graph
project = this.getHostPreferences().lazyConfiguredProjectsFromExternalProject ?
this.createConfiguredProjectWithDelayLoad(tsconfigFile) :
this.createLoadAndUpdateConfiguredProject(tsconfigFile);
this.createConfiguredProjectWithDelayLoad(tsconfigFile, `Creating configured project in external project: ${proj.projectFileName}`) :
this.createLoadAndUpdateConfiguredProject(tsconfigFile, `Creating configured project in external project: ${proj.projectFileName}`);
}
if (project && !contains(exisingConfigFiles, tsconfigFile)) {
// keep project alive even if no documents are opened - its lifetime is bound to the lifetime of containing external project
+9 -1
View File
@@ -1326,6 +1326,8 @@ namespace ts.server {
/* @internal */
pendingReload: ConfigFileProgramReloadLevel;
/* @internal */
pendingReloadReason: string | undefined;
/*@internal*/
configFileSpecs: ConfigFileSpecs | undefined;
@@ -1345,6 +1347,9 @@ namespace ts.server {
protected isInitialLoadPending: () => boolean = returnTrue;
/*@internal*/
sendLoadingProjectFinish = false;
/*@internal*/
constructor(configFileName: NormalizedPath,
projectService: ProjectService,
@@ -1377,12 +1382,15 @@ namespace ts.server {
result = this.projectService.reloadFileNamesOfConfiguredProject(this);
break;
case ConfigFileProgramReloadLevel.Full:
this.projectService.reloadConfiguredProject(this);
const reason = Debug.assertDefined(this.pendingReloadReason);
this.pendingReloadReason = undefined;
this.projectService.reloadConfiguredProject(this, reason);
result = true;
break;
default:
result = super.updateGraph();
}
this.projectService.sendProjectLoadingFinishEvent(this);
this.projectService.sendProjectTelemetry(this);
this.projectService.sendSurveyReady(this);
return result;
+24
View File
@@ -2452,6 +2452,30 @@ namespace ts.server.protocol {
openFiles: string[];
}
export type ProjectLoadingStartEventName = "projectLoadingStart";
export interface ProjectLoadingStartEvent extends Event {
event: ProjectLoadingStartEventName;
body: ProjectLoadingStartEventBody;
}
export interface ProjectLoadingStartEventBody {
/** name of the project */
projectName: string;
/** reason for loading */
reason: string;
}
export type ProjectLoadingFinishEventName = "projectLoadingFinish";
export interface ProjectLoadingFinishEvent extends Event {
event: ProjectLoadingFinishEventName;
body: ProjectLoadingFinishEventBody;
}
export interface ProjectLoadingFinishEventBody {
/** name of the project */
projectName: string;
}
export type SurveyReadyEventName = "surveyReady";
export interface SurveyReadyEvent extends Event {
+15 -5
View File
@@ -568,9 +568,19 @@ namespace ts.server {
const { openFiles } = event.data;
this.projectsUpdatedInBackgroundEvent(openFiles);
break;
case ProjectLoadingStartEvent:
const { project, reason } = event.data;
this.event<protocol.ProjectLoadingStartEventBody>(
{ projectName: project.getProjectName(), reason },
ProjectLoadingStartEvent);
break;
case ProjectLoadingFinishEvent:
const { project: finishProject } = event.data;
this.event<protocol.ProjectLoadingFinishEventBody>({ projectName: finishProject.getProjectName() }, ProjectLoadingStartEvent);
break;
case LargeFileReferencedEvent:
const { file, fileSize, maxFileSize } = event.data;
this.event<protocol.LargeFileReferencedEventBody>({ file, fileSize, maxFileSize }, "largeFileReferenced");
this.event<protocol.LargeFileReferencedEventBody>({ file, fileSize, maxFileSize }, LargeFileReferencedEvent);
break;
case ConfigFileDiagEvent:
const { triggerFile, configFileName: configFile, diagnostics } = event.data;
@@ -579,14 +589,14 @@ namespace ts.server {
triggerFile,
configFile,
diagnostics: bakedDiags
}, "configFileDiag");
}, ConfigFileDiagEvent);
break;
case SurveyReady:
const { surveyId } = event.data;
this.event<protocol.SurveyReadyEventBody>({ surveyId }, "surveyReady");
this.event<protocol.SurveyReadyEventBody>({ surveyId }, SurveyReady);
break;
case ProjectLanguageServiceStateEvent: {
const eventName: protocol.ProjectLanguageServiceStateEventName = "projectLanguageServiceState";
const eventName: protocol.ProjectLanguageServiceStateEventName = ProjectLanguageServiceStateEvent;
this.event<protocol.ProjectLanguageServiceStateEventBody>({
projectName: event.data.project.getProjectName(),
languageServiceEnabled: event.data.languageServiceEnabled
@@ -617,7 +627,7 @@ namespace ts.server {
// Send project changed event
this.event<protocol.ProjectsUpdatedInBackgroundEventBody>({
openFiles
}, "projectsUpdatedInBackground");
}, ProjectsUpdatedInBackgroundEvent);
}
}
@@ -465,11 +465,11 @@ namespace ts.codefix {
return innerCbBody;
}
const type = transformer.checker.getTypeAtLocation(func);
const returnType = getLastCallSignature(type, transformer.checker)!.getReturnType();
const rightHandSide = getSynthesizedDeepClone(funcBody);
const possiblyAwaitedRightHandSide = !!transformer.checker.getPromisedTypeOfPromise(returnType) ? createAwait(rightHandSide) : rightHandSide;
if (!shouldReturn) {
const type = transformer.checker.getTypeAtLocation(func);
const returnType = getLastCallSignature(type, transformer.checker)!.getReturnType();
const rightHandSide = getSynthesizedDeepClone(funcBody);
const possiblyAwaitedRightHandSide = !!transformer.checker.getPromisedTypeOfPromise(returnType) ? createAwait(rightHandSide) : rightHandSide;
const transformedStatement = createTransformedStatement(prevArgName, possiblyAwaitedRightHandSide, transformer);
if (prevArgName) {
prevArgName.types.push(returnType);
@@ -477,7 +477,7 @@ namespace ts.codefix {
return transformedStatement;
}
else {
return [createReturn(getSynthesizedDeepClone(funcBody))];
return [createReturn(possiblyAwaitedRightHandSide)];
}
}
}
+95 -42
View File
@@ -25,24 +25,21 @@ namespace ts.codefix {
registerCodeFix({
errorCodes,
getCodeActions(context) {
const { sourceFile, program, span: { start }, errorCode, cancellationToken } = context;
if (isSourceFileJS(sourceFile)) {
return undefined; // TODO: GH#20113
}
const { sourceFile, program, span: { start }, errorCode, cancellationToken, host } = context;
const token = getTokenAtPosition(sourceFile, start);
let declaration!: Declaration | undefined;
const changes = textChanges.ChangeTracker.with(context, changes => { declaration = doChange(changes, sourceFile, token, errorCode, program, cancellationToken, /*markSeenseen*/ returnTrue); });
const changes = textChanges.ChangeTracker.with(context, changes => { declaration = doChange(changes, sourceFile, token, errorCode, program, cancellationToken, /*markSeen*/ returnTrue, host); });
const name = declaration && getNameOfDeclaration(declaration);
return !name || changes.length === 0 ? undefined
: [createCodeFixAction(fixId, changes, [getDiagnostic(errorCode, token), name.getText(sourceFile)], fixId, Diagnostics.Infer_all_types_from_usage)];
},
fixIds: [fixId],
getAllCodeActions(context) {
const { sourceFile, program, cancellationToken } = context;
const { sourceFile, program, cancellationToken, host } = context;
const markSeen = nodeSeenTracker();
return codeFixAll(context, errorCodes, (changes, err) => {
doChange(changes, sourceFile, getTokenAtPosition(err.file, err.start), err.code, program, cancellationToken, markSeen);
doChange(changes, sourceFile, getTokenAtPosition(err.file, err.start), err.code, program, cancellationToken, markSeen, host);
});
},
});
@@ -50,7 +47,7 @@ namespace ts.codefix {
function getDiagnostic(errorCode: number, token: Node): DiagnosticMessage {
switch (errorCode) {
case Diagnostics.Parameter_0_implicitly_has_an_1_type.code:
return isSetAccessor(getContainingFunction(token)!) ? Diagnostics.Infer_type_of_0_from_usage : Diagnostics.Infer_parameter_types_from_usage; // TODO: GH#18217
return isSetAccessorDeclaration(getContainingFunction(token)!) ? Diagnostics.Infer_type_of_0_from_usage : Diagnostics.Infer_parameter_types_from_usage; // TODO: GH#18217
case Diagnostics.Rest_parameter_0_implicitly_has_an_any_type.code:
return Diagnostics.Infer_parameter_types_from_usage;
default:
@@ -58,8 +55,8 @@ namespace ts.codefix {
}
}
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, token: Node, errorCode: number, program: Program, cancellationToken: CancellationToken, markSeen: NodeSeenTracker): Declaration | undefined {
if (!isParameterPropertyModifier(token.kind) && token.kind !== SyntaxKind.Identifier && token.kind !== SyntaxKind.DotDotDotToken) {
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, token: Node, errorCode: number, program: Program, cancellationToken: CancellationToken, markSeen: NodeSeenTracker, host: LanguageServiceHost): Declaration | undefined {
if (!isParameterPropertyModifier(token.kind) && token.kind !== SyntaxKind.Identifier && token.kind !== SyntaxKind.DotDotDotToken && token.kind !== SyntaxKind.ThisKeyword) {
return undefined;
}
@@ -69,7 +66,15 @@ namespace ts.codefix {
case Diagnostics.Member_0_implicitly_has_an_1_type.code:
case Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined.code:
if ((isVariableDeclaration(parent) && markSeen(parent)) || isPropertyDeclaration(parent) || isPropertySignature(parent)) { // handle bad location
annotateVariableDeclaration(changes, sourceFile, parent, program, cancellationToken);
annotateVariableDeclaration(changes, sourceFile, parent, program, host, cancellationToken);
return parent;
}
if (isPropertyAccessExpression(parent)) {
const type = inferTypeForVariableFromUsage(parent.name, program, cancellationToken);
const typeNode = type && getTypeNodeIfAccessible(type, parent, program, host);
if (typeNode) {
changes.tryInsertJSDocType(sourceFile, parent, typeNode);
}
return parent;
}
return undefined;
@@ -77,7 +82,7 @@ namespace ts.codefix {
case Diagnostics.Variable_0_implicitly_has_an_1_type.code: {
const symbol = program.getTypeChecker().getSymbolAtLocation(token);
if (symbol && symbol.valueDeclaration && isVariableDeclaration(symbol.valueDeclaration) && markSeen(symbol.valueDeclaration)) {
annotateVariableDeclaration(changes, sourceFile, symbol.valueDeclaration, program, cancellationToken);
annotateVariableDeclaration(changes, sourceFile, symbol.valueDeclaration, program, host, cancellationToken);
return symbol.valueDeclaration;
}
return undefined;
@@ -92,15 +97,15 @@ namespace ts.codefix {
switch (errorCode) {
// Parameter declarations
case Diagnostics.Parameter_0_implicitly_has_an_1_type.code:
if (isSetAccessor(containingFunction)) {
annotateSetAccessor(changes, sourceFile, containingFunction, program, cancellationToken);
if (isSetAccessorDeclaration(containingFunction)) {
annotateSetAccessor(changes, sourceFile, containingFunction, program, host, cancellationToken);
return containingFunction;
}
// falls through
case Diagnostics.Rest_parameter_0_implicitly_has_an_any_type.code:
if (markSeen(containingFunction)) {
const param = cast(parent, isParameter);
annotateParameters(changes, param, containingFunction, sourceFile, program, cancellationToken);
annotateParameters(changes, param, containingFunction, sourceFile, program, host, cancellationToken);
return param;
}
return undefined;
@@ -108,16 +113,16 @@ namespace ts.codefix {
// Get Accessor declarations
case Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation.code:
case Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type.code:
if (isGetAccessor(containingFunction) && isIdentifier(containingFunction.name)) {
annotate(changes, sourceFile, containingFunction, inferTypeForVariableFromUsage(containingFunction.name, program, cancellationToken), program);
if (isGetAccessorDeclaration(containingFunction) && isIdentifier(containingFunction.name)) {
annotate(changes, sourceFile, containingFunction, inferTypeForVariableFromUsage(containingFunction.name, program, cancellationToken), program, host);
return containingFunction;
}
return undefined;
// Set Accessor declarations
case Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation.code:
if (isSetAccessor(containingFunction)) {
annotateSetAccessor(changes, sourceFile, containingFunction, program, cancellationToken);
if (isSetAccessorDeclaration(containingFunction)) {
annotateSetAccessor(changes, sourceFile, containingFunction, program, host, cancellationToken);
return containingFunction;
}
return undefined;
@@ -127,9 +132,9 @@ namespace ts.codefix {
}
}
function annotateVariableDeclaration(changes: textChanges.ChangeTracker, sourceFile: SourceFile, declaration: VariableDeclaration | PropertyDeclaration | PropertySignature, program: Program, cancellationToken: CancellationToken): void {
function annotateVariableDeclaration(changes: textChanges.ChangeTracker, sourceFile: SourceFile, declaration: VariableDeclaration | PropertyDeclaration | PropertySignature, program: Program, host: LanguageServiceHost, cancellationToken: CancellationToken): void {
if (isIdentifier(declaration.name)) {
annotate(changes, sourceFile, declaration, inferTypeForVariableFromUsage(declaration.name, program, cancellationToken), program);
annotate(changes, sourceFile, declaration, inferTypeForVariableFromUsage(declaration.name, program, cancellationToken), program, host);
}
}
@@ -145,40 +150,67 @@ namespace ts.codefix {
return false;
}
function annotateParameters(changes: textChanges.ChangeTracker, parameterDeclaration: ParameterDeclaration, containingFunction: FunctionLike, sourceFile: SourceFile, program: Program, cancellationToken: CancellationToken): void {
function annotateParameters(changes: textChanges.ChangeTracker, parameterDeclaration: ParameterDeclaration, containingFunction: FunctionLike, sourceFile: SourceFile, program: Program, host: LanguageServiceHost, cancellationToken: CancellationToken): void {
if (!isIdentifier(parameterDeclaration.name) || !isApplicableFunctionForInference(containingFunction)) {
return;
}
const types = inferTypeForParametersFromUsage(containingFunction, sourceFile, program, cancellationToken) ||
containingFunction.parameters.map(p => isIdentifier(p.name) ? inferTypeForVariableFromUsage(p.name, program, cancellationToken) : undefined);
// We didn't actually find a set of type inference positions matching each parameter position
if (!types || containingFunction.parameters.length !== types.length) {
return;
}
const parameterInferences = inferTypeForParametersFromUsage(containingFunction, sourceFile, program, cancellationToken) ||
containingFunction.parameters.map<ParameterInference>(p => ({
declaration: p,
type: isIdentifier(p.name) ? inferTypeForVariableFromUsage(p.name, program, cancellationToken) : undefined
}));
Debug.assert(containingFunction.parameters.length === parameterInferences.length);
zipWith(containingFunction.parameters, types, (parameter, type) => {
if (!parameter.type && !parameter.initializer) {
annotate(changes, sourceFile, parameter, type, program);
if (isInJSFile(containingFunction)) {
annotateJSDocParameters(changes, sourceFile, parameterInferences, program, host);
}
else {
for (const { declaration, type } of parameterInferences) {
if (declaration && !declaration.type && !declaration.initializer) {
annotate(changes, sourceFile, declaration, type, program, host);
}
}
});
}
}
function annotateSetAccessor(changes: textChanges.ChangeTracker, sourceFile: SourceFile, setAccessorDeclaration: SetAccessorDeclaration, program: Program, cancellationToken: CancellationToken): void {
function annotateSetAccessor(changes: textChanges.ChangeTracker, sourceFile: SourceFile, setAccessorDeclaration: SetAccessorDeclaration, program: Program, host: LanguageServiceHost, cancellationToken: CancellationToken): void {
const param = firstOrUndefined(setAccessorDeclaration.parameters);
if (param && isIdentifier(setAccessorDeclaration.name) && isIdentifier(param.name)) {
const type = inferTypeForVariableFromUsage(setAccessorDeclaration.name, program, cancellationToken) ||
inferTypeForVariableFromUsage(param.name, program, cancellationToken);
annotate(changes, sourceFile, param, type, program);
if (isInJSFile(setAccessorDeclaration)) {
annotateJSDocParameters(changes, sourceFile, [{ declaration: param, type }], program, host);
}
else {
annotate(changes, sourceFile, param, type, program, host);
}
}
}
function annotate(changes: textChanges.ChangeTracker, sourceFile: SourceFile, declaration: textChanges.TypeAnnotatable, type: Type | undefined, program: Program): void {
const typeNode = type && getTypeNodeIfAccessible(type, declaration, program.getTypeChecker());
if (typeNode) changes.tryInsertTypeAnnotation(sourceFile, declaration, typeNode);
function annotate(changes: textChanges.ChangeTracker, sourceFile: SourceFile, declaration: textChanges.TypeAnnotatable, type: Type | undefined, program: Program, host: LanguageServiceHost): void {
const typeNode = type && getTypeNodeIfAccessible(type, declaration, program, host);
if (typeNode) {
if (isInJSFile(sourceFile) && declaration.kind !== SyntaxKind.PropertySignature) {
changes.tryInsertJSDocType(sourceFile, declaration, typeNode);
}
else {
changes.tryInsertTypeAnnotation(sourceFile, declaration, typeNode);
}
}
}
function getTypeNodeIfAccessible(type: Type, enclosingScope: Node, checker: TypeChecker): TypeNode | undefined {
function annotateJSDocParameters(changes: textChanges.ChangeTracker, sourceFile: SourceFile, parameterInferences: ParameterInference[], program: Program, host: LanguageServiceHost): void {
const result = mapDefined(parameterInferences, inference => {
const param = inference.declaration;
const typeNode = inference.type && getTypeNodeIfAccessible(inference.type, param, program, host);
return typeNode && !param.initializer && !getJSDocType(param) ? { ...inference, typeNode } : undefined;
});
changes.tryInsertJSDocParameters(sourceFile, result);
}
function getTypeNodeIfAccessible(type: Type, enclosingScope: Node, program: Program, host: LanguageServiceHost): TypeNode | undefined {
const checker = program.getTypeChecker();
let typeIsAccessible = true;
const notAccessible = () => { typeIsAccessible = false; };
const res = checker.typeToTypeNode(type, enclosingScope, /*flags*/ undefined, {
@@ -189,6 +221,14 @@ namespace ts.codefix {
reportInaccessibleThisError: notAccessible,
reportPrivateInBaseOfClassExpression: notAccessible,
reportInaccessibleUniqueSymbolError: notAccessible,
moduleResolverHost: {
readFile: host.readFile,
fileExists: host.fileExists,
directoryExists: host.directoryExists,
getSourceFiles: program.getSourceFiles,
getCurrentDirectory: program.getCurrentDirectory,
getCommonSourceDirectory: program.getCommonSourceDirectory,
}
});
return typeIsAccessible ? res : undefined;
}
@@ -203,7 +243,7 @@ namespace ts.codefix {
return InferFromReference.inferTypeFromReferences(getReferences(token, program, cancellationToken), program.getTypeChecker(), cancellationToken);
}
function inferTypeForParametersFromUsage(containingFunction: FunctionLikeDeclaration, sourceFile: SourceFile, program: Program, cancellationToken: CancellationToken): (Type | undefined)[] | undefined {
function inferTypeForParametersFromUsage(containingFunction: FunctionLikeDeclaration, sourceFile: SourceFile, program: Program, cancellationToken: CancellationToken): ParameterInference[] | undefined {
switch (containingFunction.kind) {
case SyntaxKind.Constructor:
case SyntaxKind.FunctionExpression:
@@ -219,6 +259,13 @@ namespace ts.codefix {
}
}
interface ParameterInference {
declaration: ParameterDeclaration;
type?: Type;
typeNode?: TypeNode;
isOptional?: boolean;
}
namespace InferFromReference {
interface CallContext {
argumentTypes: Type[];
@@ -246,7 +293,7 @@ namespace ts.codefix {
return getTypeFromUsageContext(usageContext, checker);
}
export function inferTypeForParametersFromReferences(references: ReadonlyArray<Identifier>, declaration: FunctionLikeDeclaration, checker: TypeChecker, cancellationToken: CancellationToken): (Type | undefined)[] | undefined {
export function inferTypeForParametersFromReferences(references: ReadonlyArray<Identifier>, declaration: FunctionLikeDeclaration, checker: TypeChecker, cancellationToken: CancellationToken): ParameterInference[] | undefined {
if (references.length === 0) {
return undefined;
}
@@ -265,8 +312,10 @@ namespace ts.codefix {
return callContexts && declaration.parameters.map((parameter, parameterIndex) => {
const types: Type[] = [];
const isRest = isRestParameter(parameter);
let isOptional = false;
for (const callContext of callContexts) {
if (callContext.argumentTypes.length <= parameterIndex) {
isOptional = isInJSFile(declaration);
continue;
}
@@ -280,10 +329,14 @@ namespace ts.codefix {
}
}
if (!types.length) {
return undefined;
return { declaration: parameter };
}
const type = checker.getWidenedType(checker.getUnionType(types, UnionReduction.Subtype));
return isRest ? checker.createArrayType(type) : type;
return {
type: isRest ? checker.createArrayType(type) : type,
isOptional: isOptional && !isRest,
declaration: parameter
};
});
}
+4 -3
View File
@@ -38,7 +38,8 @@ namespace ts.SignatureHelp {
return undefined;
}
const argumentInfo = getContainingArgumentInfo(startingToken, position, sourceFile, typeChecker);
const isManuallyInvoked = !!triggerReason && triggerReason.kind === "invoked";
const argumentInfo = getContainingArgumentInfo(startingToken, position, sourceFile, typeChecker, isManuallyInvoked);
if (!argumentInfo) return undefined;
cancellationToken.throwIfCancellationRequested();
@@ -450,8 +451,8 @@ namespace ts.SignatureHelp {
return createTextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart);
}
function getContainingArgumentInfo(node: Node, position: number, sourceFile: SourceFile, checker: TypeChecker): ArgumentListInfo | undefined {
for (let n = node; !isBlock(n) && !isSourceFile(n); n = n.parent) {
function getContainingArgumentInfo(node: Node, position: number, sourceFile: SourceFile, checker: TypeChecker, isManuallyInvoked: boolean): ArgumentListInfo | undefined {
for (let n = node; isManuallyInvoked || (!isBlock(n) && !isSourceFile(n)); n = n.parent) {
// If the node is not a subspan of its parent, this is a big problem.
// There have been crashes that might be caused by this violation.
Debug.assert(rangeContainsRange(n.parent, n), "Not a subspan", () => `Child: ${Debug.showSyntaxKind(n)}, parent: ${Debug.showSyntaxKind(n.parent)}`);
+1 -1
View File
@@ -82,7 +82,7 @@ namespace ts {
switch (statement.kind) {
case SyntaxKind.VariableStatement:
return (statement as VariableStatement).declarationList.declarations.some(decl =>
isRequireCall(propertyAccessLeftHandSide(decl.initializer!), /*checkArgumentIsStringLiteralLike*/ true)); // TODO: GH#18217
!!decl.initializer && isRequireCall(propertyAccessLeftHandSide(decl.initializer), /*checkArgumentIsStringLiteralLike*/ true));
case SyntaxKind.ExpressionStatement: {
const { expression } = statement as ExpressionStatement;
if (!isBinaryExpression(expression)) return isRequireCall(expression, /*checkArgumentIsStringLiteralLike*/ true);
+51 -1
View File
@@ -209,6 +209,12 @@ namespace ts.textChanges {
export type TypeAnnotatable = SignatureDeclaration | VariableDeclaration | ParameterDeclaration | PropertyDeclaration | PropertySignature;
interface JSDocParameter {
declaration: ParameterDeclaration;
typeNode: TypeNode;
isOptional?: boolean;
}
export class ChangeTracker {
private readonly changes: Change[] = [];
private readonly newFiles: { readonly oldFile: SourceFile | undefined, readonly fileName: string, readonly statements: ReadonlyArray<Statement> }[] = [];
@@ -339,6 +345,12 @@ namespace ts.textChanges {
this.insertText(sourceFile, token.getStart(sourceFile), text);
}
public insertCommentThenNewline(sourceFile: SourceFile, character: number, position: number, commentText: string): void {
const token = getTouchingToken(sourceFile, position);
const text = "/**" + commentText + "*/" + this.newLineCharacter + repeatString(" ", character);
this.insertText(sourceFile, token.getStart(sourceFile), text);
}
public replaceRangeWithText(sourceFile: SourceFile, range: TextRange, text: string) {
this.changes.push({ kind: ChangeKind.Text, sourceFile, range, text });
}
@@ -347,6 +359,23 @@ namespace ts.textChanges {
this.replaceRangeWithText(sourceFile, createRange(pos), text);
}
public tryInsertJSDocParameters(sourceFile: SourceFile, parameters: JSDocParameter[]) {
if (parameters.length === 0) {
return;
}
const parent = parameters[0].declaration.parent;
const indent = getLineAndCharacterOfPosition(sourceFile, parent.getStart()).character;
let commentText = "\n";
for (const { declaration, typeNode, isOptional } of parameters) {
if (isIdentifier(declaration.name)) {
const printed = changesToText.getNonformattedText(typeNode, sourceFile, this.newLineCharacter).text;
commentText += this.printJSDocParameter(indent, printed, declaration.name, isOptional);
}
}
commentText += repeatString(" ", indent + 1);
this.insertCommentThenNewline(sourceFile, indent, parent.getStart(), commentText);
}
/** Prefer this over replacing a node with another that has a type annotation, as it avoids reformatting the other parts of the node. */
public tryInsertTypeAnnotation(sourceFile: SourceFile, node: TypeAnnotatable, type: TypeNode): void {
let endNode: Node | undefined;
@@ -365,6 +394,27 @@ namespace ts.textChanges {
this.insertNodeAt(sourceFile, endNode.end, type, { prefix: ": " });
}
public tryInsertJSDocType(sourceFile: SourceFile, node: Node, type: TypeNode): void {
const printed = changesToText.getNonformattedText(type, sourceFile, this.newLineCharacter).text;
let commentText;
if (isGetAccessorDeclaration(node)) {
commentText = ` @return {${printed}} `;
}
else {
commentText = ` @type {${printed}} `;
node = node.parent;
}
this.insertCommentThenNewline(sourceFile, getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile)).character, node.getStart(sourceFile), commentText);
}
private printJSDocParameter(indent: number, printed: string, name: Identifier, isOptionalParameter: boolean | undefined) {
let printName = unescapeLeadingUnderscores(name.escapedText);
if (isOptionalParameter) {
printName = `[${printName}]`;
}
return repeatString(" ", indent) + ` * @param {${printed}} ${printName}\n`;
}
public insertTypeParameters(sourceFile: SourceFile, node: SignatureDeclaration, typeParameters: ReadonlyArray<TypeParameterDeclaration>): void {
// If no `(`, is an arrow function `x => x`, so use the pos of the first parameter
const start = (findChildOfKind(node, SyntaxKind.OpenParenToken, sourceFile) || first(node.parameters)).getStart(sourceFile);
@@ -806,7 +856,7 @@ namespace ts.textChanges {
}
/** Note: output node may be mutated input node. */
function getNonformattedText(node: Node, sourceFile: SourceFile | undefined, newLineCharacter: string): { text: string, node: Node } {
export function getNonformattedText(node: Node, sourceFile: SourceFile | undefined, newLineCharacter: string): { text: string, node: Node } {
const writer = new Writer(newLineCharacter);
const newLine = newLineCharacter === "\n" ? NewLineKind.LineFeed : NewLineKind.CarriageReturnLineFeed;
createPrinter({ newLine, neverAsciiEscape: true }, writer).writeNode(EmitHint.Unspecified, node, sourceFile, writer);
+15 -13
View File
@@ -1,6 +1,6 @@
const fs = require("fs");
const path = require("path");
const del = require("del");
const fs: typeof import("fs") = require("fs");
const path: typeof import("path") = require("path");
const del: typeof import("del") = require("del");
interface ExecResult {
stdout: Buffer;
@@ -49,12 +49,9 @@ abstract class ExternalCompileRunnerBase extends RunnerBase {
let types: string[] | undefined;
if (fs.existsSync(path.join(cwd, "test.json"))) {
const submoduleDir = path.join(cwd, directoryName);
const reset = cp.spawnSync("git", ["reset", "HEAD", "--hard"], { cwd: submoduleDir, timeout, shell: true, stdio });
if (reset.status !== 0) throw new Error(`git reset for ${directoryName} failed: ${reset.stderr.toString()}`);
const clean = cp.spawnSync("git", ["clean", "-f"], { cwd: submoduleDir, timeout, shell: true, stdio });
if (clean.status !== 0) throw new Error(`git clean for ${directoryName} failed: ${clean.stderr.toString()}`);
const update = cp.spawnSync("git", ["submodule", "update", "--init", "--remote", "."], { cwd: submoduleDir, timeout, shell: true, stdio });
if (update.status !== 0) throw new Error(`git submodule update for ${directoryName} failed: ${update.stderr.toString()}`);
exec("git", ["reset", "HEAD", "--hard"], { cwd: submoduleDir });
exec("git", ["clean", "-f"], { cwd: submoduleDir });
exec("git", ["submodule", "update", "--init", "--remote", "."], { cwd: submoduleDir });
const config = JSON.parse(fs.readFileSync(path.join(cwd, "test.json"), { encoding: "utf8" })) as UserConfig;
ts.Debug.assert(!!config.types, "Bad format from test.json: Types field must be present.");
@@ -69,18 +66,23 @@ abstract class ExternalCompileRunnerBase extends RunnerBase {
if (fs.existsSync(path.join(cwd, "node_modules"))) {
del.sync(path.join(cwd, "node_modules"), { force: true });
}
const install = cp.spawnSync(`npm`, ["i", "--ignore-scripts"], { cwd, timeout: timeout / 2, shell: true, stdio }); // NPM shouldn't take the entire timeout - if it takes a long time, it should be terminated and we should log the failure
if (install.status !== 0) throw new Error(`NPM Install for ${directoryName} failed: ${install.stderr.toString()}`);
exec("npm", ["i", "--ignore-scripts"], { cwd, timeout: timeout / 2 }); // NPM shouldn't take the entire timeout - if it takes a long time, it should be terminated and we should log the failure
}
const args = [path.join(Harness.IO.getWorkspaceRoot(), "built/local/tsc.js")];
if (types) {
args.push("--types", types.join(","));
// Also actually install those types (for, eg, the js projects which need node)
const install = cp.spawnSync(`npm`, ["i", ...types.map(t => `@types/${t}`), "--no-save", "--ignore-scripts"], { cwd: originalCwd, timeout: timeout / 2, shell: true, stdio }); // NPM shouldn't take the entire timeout - if it takes a long time, it should be terminated and we should log the failure
if (install.status !== 0) throw new Error(`NPM Install types for ${directoryName} failed: ${install.stderr.toString()}`);
exec("npm", ["i", ...types.map(t => `@types/${t}`), "--no-save", "--ignore-scripts"], { cwd: originalCwd, timeout: timeout / 2 }); // NPM shouldn't take the entire timeout - if it takes a long time, it should be terminated and we should log the failure
}
args.push("--noEmit");
Harness.Baseline.runBaseline(`${cls.kind()}/${directoryName}.log`, cls.report(cp.spawnSync(`node`, args, { cwd, timeout, shell: true }), cwd));
function exec(command: string, args: string[], options: { cwd: string, timeout?: number }): void {
const res = cp.spawnSync(command, args, { timeout, shell: true, stdio, ...options });
if (res.status !== 0) {
throw new Error(`${command} ${args.join(" ")} for ${directoryName} failed: ${res.stderr && res.stderr.toString()}`);
}
}
});
});
}
@@ -1236,6 +1236,13 @@ function [#|f|]() {
}
`);
_testConvertToAsyncFunction("convertToAsyncFunction_callbackReturnsRejectedPromiseInTryBlock", `
function [#|f|]() {
return Promise.resolve(1)
.then(x => Promise.reject(x))
.catch(err => console.log(err));
}
`);
_testConvertToAsyncFunction("convertToAsyncFunction_nestedPromises", `
function [#|f|]() {
+35
View File
@@ -1386,6 +1386,41 @@ foo().hello`
// File a need not be rewritten
assert.equal(host.getModifiedTime(`${currentDirectory}/a.js`), modifiedTimeOfAJs);
});
it("updates errors when ambient modules of program changes", () => {
const currentDirectory = "/user/username/projects/myproject";
const aFile: File = {
path: `${currentDirectory}/a.ts`,
content: `declare module 'a' {
type foo = number;
}`
};
const config: File = {
path: `${currentDirectory}/tsconfig.json`,
content: "{}"
};
const files = [aFile, config, libFile];
const host = createWatchedSystem(files, { currentDirectory });
const watch = createWatchOfConfigFile("tsconfig.json", host);
checkProgramActualFiles(watch(), [aFile.path, libFile.path]);
checkOutputErrorsInitial(host, emptyArray);
// Create bts with same file contents
const bTsPath = `${currentDirectory}/b.ts`;
host.writeFile(bTsPath, aFile.content);
host.runQueuedTimeoutCallbacks();
checkProgramActualFiles(watch(), [aFile.path, "b.ts", libFile.path]);
checkOutputErrorsIncremental(host, [
"a.ts(2,8): error TS2300: Duplicate identifier 'foo'.\n",
"b.ts(2,8): error TS2300: Duplicate identifier 'foo'.\n"
]);
// Delete bTs
host.deleteFile(bTsPath);
host.runQueuedTimeoutCallbacks();
checkProgramActualFiles(watch(), [aFile.path, libFile.path]);
checkOutputErrorsIncremental(host, emptyArray);
});
});
describe("tsc-watch emit with outFile or out setting", () => {
+181 -48
View File
@@ -330,6 +330,19 @@ namespace ts.projectSystem {
return new TestSession({ ...sessionOptions, ...opts });
}
function createSessionWithEventTracking<T extends server.ProjectServiceEvent, U extends server.ProjectServiceEvent = T>(host: server.ServerHost, eventName: T["eventName"], eventName2?: U["eventName"]) {
const events: (T | U)[] = [];
const session = createSession(host, {
eventHandler: e => {
if (e.eventName === eventName || (eventName2 && e.eventName === eventName2)) {
events.push(e as T | U);
}
}
});
return { session, events };
}
interface CreateProjectServiceParameters {
cancellationToken?: HostCancellationToken;
logger?: server.Logger;
@@ -2872,18 +2885,7 @@ namespace ts.projectSystem {
host.getFileSize = (filePath: string) =>
filePath === f2.path ? server.maxProgramSizeForNonTsFiles + 1 : originalGetFileSize.call(host, filePath);
let lastEvent!: server.ProjectLanguageServiceStateEvent;
const session = createSession(host, {
canUseEvents: true,
eventHandler: e => {
if (e.eventName === server.ConfigFileDiagEvent || e.eventName === server.ProjectsUpdatedInBackgroundEvent || e.eventName === server.ProjectInfoTelemetryEvent || e.eventName === server.OpenFileInfoTelemetryEvent || e.eventName === server.LargeFileReferencedEvent || e.eventName === server.SurveyReady) {
return;
}
assert.equal(e.eventName, server.ProjectLanguageServiceStateEvent);
assert.equal(e.data.project.getProjectName(), config.path, "project name");
lastEvent = e;
}
});
const { session, events } = createSessionWithEventTracking<server.ProjectLanguageServiceStateEvent>(host, server.ProjectLanguageServiceStateEvent);
session.executeCommand(<protocol.OpenRequest>{
seq: 0,
type: "request",
@@ -2894,17 +2896,19 @@ namespace ts.projectSystem {
checkNumberOfProjects(projectService, { configuredProjects: 1 });
const project = configuredProjectAt(projectService, 0);
assert.isFalse(project.languageServiceEnabled, "Language service enabled");
assert.isTrue(!!lastEvent, "should receive event");
assert.equal(lastEvent.data.project, project, "project name");
assert.equal(lastEvent.data.project.getProjectName(), config.path, "config path");
assert.isFalse(lastEvent.data.languageServiceEnabled, "Language service state");
assert.equal(events.length, 1, "should receive event");
assert.equal(events[0].data.project, project, "project name");
assert.equal(events[0].data.project.getProjectName(), config.path, "config path");
assert.isFalse(events[0].data.languageServiceEnabled, "Language service state");
host.reloadFS([f1, f2, configWithExclude]);
host.checkTimeoutQueueLengthAndRun(2);
checkNumberOfProjects(projectService, { configuredProjects: 1 });
assert.isTrue(project.languageServiceEnabled, "Language service enabled");
assert.equal(lastEvent.data.project, project, "project");
assert.isTrue(lastEvent.data.languageServiceEnabled, "Language service state");
assert.equal(events.length, 2, "should receive event");
assert.equal(events[1].data.project, project, "project");
assert.equal(events[1].data.project.getProjectName(), config.path, "config path");
assert.isTrue(events[1].data.languageServiceEnabled, "Language service state");
});
it("syntactic features work even if language service is disabled", () => {
@@ -2924,17 +2928,7 @@ namespace ts.projectSystem {
const originalGetFileSize = host.getFileSize;
host.getFileSize = (filePath: string) =>
filePath === f2.path ? server.maxProgramSizeForNonTsFiles + 1 : originalGetFileSize.call(host, filePath);
let lastEvent!: server.ProjectLanguageServiceStateEvent;
const session = createSession(host, {
canUseEvents: true,
eventHandler: e => {
if (e.eventName === server.ConfigFileDiagEvent || e.eventName === server.ProjectInfoTelemetryEvent || e.eventName === server.OpenFileInfoTelemetryEvent) {
return;
}
assert.equal(e.eventName, server.ProjectLanguageServiceStateEvent);
lastEvent = <server.ProjectLanguageServiceStateEvent>e;
}
});
const { session, events } = createSessionWithEventTracking<server.ProjectLanguageServiceStateEvent>(host, server.ProjectLanguageServiceStateEvent);
session.executeCommand(<protocol.OpenRequest>{
seq: 0,
type: "request",
@@ -2946,9 +2940,9 @@ namespace ts.projectSystem {
checkNumberOfProjects(projectService, { configuredProjects: 1 });
const project = configuredProjectAt(projectService, 0);
assert.isFalse(project.languageServiceEnabled, "Language service enabled");
assert.isTrue(!!lastEvent, "should receive event");
assert.equal(lastEvent.data.project, project, "project name");
assert.isFalse(lastEvent.data.languageServiceEnabled, "Language service state");
assert.equal(events.length, 1, "should receive event");
assert.equal(events[0].data.project, project, "project name");
assert.isFalse(events[0].data.languageServiceEnabled, "Language service state");
const options = projectService.getFormatCodeOptions(f1.path as server.NormalizedPath);
const edits = project.getLanguageService().getFormattingEditsForDocument(f1.path, options);
@@ -3553,14 +3547,7 @@ namespace ts.projectSystem {
});
function createSessionWithEventHandler(host: TestServerHost) {
const surveyEvents: server.SurveyReady[] = [];
const session = createSession(host, {
eventHandler: e => {
if (e.eventName === server.SurveyReady) {
surveyEvents.push(e);
}
}
});
const { session, events: surveyEvents } = createSessionWithEventTracking<server.SurveyReady>(host, server.SurveyReady);
return { session, verifySurveyReadyEvent };
@@ -9295,14 +9282,7 @@ export const x = 10;`
};
files.push(largeFile);
const host = createServerHost(files);
const largeFileReferencedEvents: server.LargeFileReferencedEvent[] = [];
const session = createSession(host, {
eventHandler: e => {
if (e.eventName === server.LargeFileReferencedEvent) {
largeFileReferencedEvents.push(e);
}
}
});
const { session, events: largeFileReferencedEvents } = createSessionWithEventTracking<server.LargeFileReferencedEvent>(host, server.LargeFileReferencedEvent);
return { session, verifyLargeFile };
@@ -9362,6 +9342,159 @@ export const x = 10;`
});
});
describe("tsserverProjectSystem ProjectLoadingStart and ProjectLoadingFinish events", () => {
const projectRoot = "/user/username/projects";
const aTs: File = {
path: `${projectRoot}/a/a.ts`,
content: "export class A { }"
};
const configA: File = {
path: `${projectRoot}/a/tsconfig.json`,
content: "{}"
};
const bTsPath = `${projectRoot}/b/b.ts`;
const configBPath = `${projectRoot}/b/tsconfig.json`;
const files = [libFile, aTs, configA];
function createSessionWithEventHandler(files: ReadonlyArray<File>) {
const host = createServerHost(files);
const originalReadFile = host.readFile;
host.readFile = file => {
if (file === configA.path || file === configBPath) {
assert.equal(events.length, 1, "Event for loading is sent before reading config file");
}
return originalReadFile.call(host, file);
};
const { session, events } = createSessionWithEventTracking<server.ProjectLoadingStartEvent, server.ProjectLoadingFinishEvent>(host, server.ProjectLoadingStartEvent, server.ProjectLoadingFinishEvent);
const service = session.getProjectService();
return { host, session, verifyEvent, verifyEventWithOpenTs, service, events };
function verifyEvent(project: server.Project, reason: string) {
assert.deepEqual(events, [
{ eventName: server.ProjectLoadingStartEvent, data: { project, reason } },
{ eventName: server.ProjectLoadingFinishEvent, data: { project } }
]);
events.length = 0;
}
function verifyEventWithOpenTs(file: File, configPath: string, configuredProjects: number) {
openFilesForSession([file], session);
checkNumberOfProjects(service, { configuredProjects });
const project = service.configuredProjects.get(configPath)!;
assert.isDefined(project);
verifyEvent(project, `Creating possible configured project for ${file.path} to open`);
}
}
it("when project is created by open file", () => {
const bTs: File = {
path: bTsPath,
content: "export class B {}"
};
const configB: File = {
path: configBPath,
content: "{}"
};
const { verifyEventWithOpenTs } = createSessionWithEventHandler(files.concat(bTs, configB));
verifyEventWithOpenTs(aTs, configA.path, 1);
verifyEventWithOpenTs(bTs, configB.path, 2);
});
it("when change is detected in the config file", () => {
const { host, verifyEvent, verifyEventWithOpenTs, service } = createSessionWithEventHandler(files);
verifyEventWithOpenTs(aTs, configA.path, 1);
host.writeFile(configA.path, configA.content);
host.checkTimeoutQueueLengthAndRun(2);
const project = service.configuredProjects.get(configA.path)!;
verifyEvent(project, `Change in config file detected`);
});
it("when opening original location project", () => {
const aDTs: File = {
path: `${projectRoot}/a/a.d.ts`,
content: `export declare class A {
}
//# sourceMappingURL=a.d.ts.map
`
};
const aDTsMap: File = {
path: `${projectRoot}/a/a.d.ts.map`,
content: `{"version":3,"file":"a.d.ts","sourceRoot":"","sources":["./a.ts"],"names":[],"mappings":"AAAA,qBAAa,CAAC;CAAI"}`
};
const bTs: File = {
path: bTsPath,
content: `import {A} from "../a/a"; new A();`
};
const configB: File = {
path: configBPath,
content: JSON.stringify({
references: [{ path: "../a" }]
})
};
const { service, session, verifyEventWithOpenTs, verifyEvent } = createSessionWithEventHandler(files.concat(aDTs, aDTsMap, bTs, configB));
verifyEventWithOpenTs(bTs, configB.path, 1);
session.executeCommandSeq<protocol.ReferencesRequest>({
command: protocol.CommandTypes.References,
arguments: {
file: bTs.path,
...protocolLocationFromSubstring(bTs.content, "A()")
}
});
checkNumberOfProjects(service, { configuredProjects: 2 });
const project = service.configuredProjects.get(configA.path)!;
assert.isDefined(project);
verifyEvent(project, `Creating project for original file: ${aTs.path} for location: ${aDTs.path}`);
});
describe("with external projects and config files ", () => {
const projectFileName = `${projectRoot}/a/project.csproj`;
function createSession(lazyConfiguredProjectsFromExternalProject: boolean) {
const { session, service, verifyEvent: verifyEventWorker, events } = createSessionWithEventHandler(files);
service.setHostConfiguration({ preferences: { lazyConfiguredProjectsFromExternalProject } });
service.openExternalProject(<protocol.ExternalProject>{
projectFileName,
rootFiles: toExternalFiles([aTs.path, configA.path]),
options: {}
});
checkNumberOfProjects(service, { configuredProjects: 1 });
return { session, service, verifyEvent, events };
function verifyEvent() {
const projectA = service.configuredProjects.get(configA.path)!;
assert.isDefined(projectA);
verifyEventWorker(projectA, `Creating configured project in external project: ${projectFileName}`);
}
}
it("when lazyConfiguredProjectsFromExternalProject is false", () => {
const { verifyEvent } = createSession(/*lazyConfiguredProjectsFromExternalProject*/ false);
verifyEvent();
});
it("when lazyConfiguredProjectsFromExternalProject is true and file is opened", () => {
const { verifyEvent, events, session } = createSession(/*lazyConfiguredProjectsFromExternalProject*/ true);
assert.equal(events.length, 0);
openFilesForSession([aTs], session);
verifyEvent();
});
it("when lazyConfiguredProjectsFromExternalProject is disabled", () => {
const { verifyEvent, events, service } = createSession(/*lazyConfiguredProjectsFromExternalProject*/ true);
assert.equal(events.length, 0);
service.setHostConfiguration({ preferences: { lazyConfiguredProjectsFromExternalProject: false } });
verifyEvent();
});
});
});
describe("tsserverProjectSystem syntax operations", () => {
function navBarFull(session: TestSession, file: File) {
return JSON.stringify(session.executeCommandSeq<protocol.FileRequest>({
@@ -6,7 +6,7 @@
"0": {
"kind": "JSDocTag",
"pos": 63,
"end": 67,
"end": 68,
"atToken": {
"kind": "AtToken",
"pos": 63,
@@ -22,7 +22,7 @@
},
"length": 1,
"pos": 63,
"end": 67
"end": 68
},
"comment": "{@link first link}\nInside {@link link text} thing"
}
@@ -21,7 +21,7 @@
"typeParameters": {
"0": {
"kind": "TypeParameter",
"pos": 17,
"pos": 18,
"end": 19,
"name": {
"kind": "Identifier",
@@ -31,7 +31,7 @@
}
},
"length": 1,
"pos": 17,
"pos": 18,
"end": 19
}
},
@@ -21,7 +21,7 @@
"typeParameters": {
"0": {
"kind": "TypeParameter",
"pos": 17,
"pos": 18,
"end": 19,
"name": {
"kind": "Identifier",
@@ -42,7 +42,7 @@
}
},
"length": 2,
"pos": 17,
"pos": 18,
"end": 21
}
},
@@ -21,7 +21,7 @@
"typeParameters": {
"0": {
"kind": "TypeParameter",
"pos": 17,
"pos": 18,
"end": 19,
"name": {
"kind": "Identifier",
@@ -42,7 +42,7 @@
}
},
"length": 2,
"pos": 17,
"pos": 18,
"end": 22
}
},
@@ -21,7 +21,7 @@
"typeParameters": {
"0": {
"kind": "TypeParameter",
"pos": 17,
"pos": 18,
"end": 19,
"name": {
"kind": "Identifier",
@@ -42,7 +42,7 @@
}
},
"length": 2,
"pos": 17,
"pos": 18,
"end": 22
}
},
@@ -21,7 +21,7 @@
"typeParameters": {
"0": {
"kind": "TypeParameter",
"pos": 17,
"pos": 18,
"end": 19,
"name": {
"kind": "Identifier",
@@ -42,7 +42,7 @@
}
},
"length": 2,
"pos": 17,
"pos": 18,
"end": 23
}
},
@@ -21,7 +21,7 @@
"typeParameters": {
"0": {
"kind": "TypeParameter",
"pos": 17,
"pos": 18,
"end": 19,
"name": {
"kind": "Identifier",
@@ -42,7 +42,7 @@
}
},
"length": 2,
"pos": 17,
"pos": 18,
"end": 24
},
"comment": "Description of type parameters."
@@ -6,7 +6,7 @@ declare namespace demoNS {
>f : Symbol(f, Decl(demo.d.ts, 0, 26))
}
declare module 'demoModule' {
>'demoModule' : Symbol('demoModule', Decl(demo.d.ts, 2, 1))
>'demoModule' : Symbol("demoModule", Decl(demo.d.ts, 2, 1))
import alias = demoNS;
>alias : Symbol(alias, Decl(demo.d.ts, 3, 29))
@@ -1,4 +1,4 @@
tests/cases/compiler/a.ts(1,10): error TS2305: Module '"tests/cases/compiler/b"' has no exported member 'default'.
tests/cases/compiler/a.ts(1,10): error TS2305: Module '"./b"' has no exported member 'default'.
==== tests/cases/compiler/b.d.ts (0 errors) ====
@@ -9,6 +9,6 @@ tests/cases/compiler/a.ts(1,10): error TS2305: Module '"tests/cases/compiler/b"'
==== tests/cases/compiler/a.ts (1 errors) ====
import { default as Foo } from "./b";
~~~~~~~
!!! error TS2305: Module '"tests/cases/compiler/b"' has no exported member 'default'.
!!! error TS2305: Module '"./b"' has no exported member 'default'.
Foo.bar();
Foo.foo();
@@ -160,7 +160,7 @@ var q = M1.fn();
// Ambient external module in the global module
// Ambient external module with a string literal name that is a top level external module name
declare module 'external1' {
>'external1' : Symbol('external1', Decl(ambientDeclarations.ts, 67, 16))
>'external1' : Symbol("external1", Decl(ambientDeclarations.ts, 67, 16))
var q;
>q : Symbol(q, Decl(ambientDeclarations.ts, 72, 7))
@@ -20,7 +20,7 @@ var n: number;
=== tests/cases/conformance/ambient/decls.ts ===
// Ambient external module with export assignment
declare module 'equ' {
>'equ' : Symbol('equ', Decl(decls.ts, 0, 0))
>'equ' : Symbol("equ", Decl(decls.ts, 0, 0))
var x;
>x : Symbol(x, Decl(decls.ts, 2, 7))
@@ -30,7 +30,7 @@ declare module 'equ' {
}
declare module 'equ2' {
>'equ2' : Symbol('equ2', Decl(decls.ts, 4, 1))
>'equ2' : Symbol("equ2", Decl(decls.ts, 4, 1))
var x: number;
>x : Symbol(x, Decl(decls.ts, 7, 7))
@@ -90,16 +90,16 @@ module M2 {
>M2 : Symbol(M2, Decl(ambientErrors.ts, 42, 1))
declare module 'nope' { }
>'nope' : Symbol('nope', Decl(ambientErrors.ts, 45, 11))
>'nope' : Symbol("nope", Decl(ambientErrors.ts, 45, 11))
}
// Ambient external module with a string literal name that isn't a top level external module name
declare module '../foo' { }
>'../foo' : Symbol('../foo', Decl(ambientErrors.ts, 47, 1))
>'../foo' : Symbol("../foo", Decl(ambientErrors.ts, 47, 1))
// Ambient external module with export assignment and other exported members
declare module 'bar' {
>'bar' : Symbol('bar', Decl(ambientErrors.ts, 50, 27))
>'bar' : Symbol("bar", Decl(ambientErrors.ts, 50, 27))
var n;
>n : Symbol(n, Decl(ambientErrors.ts, 54, 7))
@@ -9,7 +9,7 @@ var c = new A();
=== tests/cases/compiler/ambientExternalModuleWithInternalImportDeclaration_0.ts ===
declare module 'M' {
>'M' : Symbol('M', Decl(ambientExternalModuleWithInternalImportDeclaration_0.ts, 0, 0))
>'M' : Symbol("M", Decl(ambientExternalModuleWithInternalImportDeclaration_0.ts, 0, 0))
module C {
>C : Symbol(C, Decl(ambientExternalModuleWithInternalImportDeclaration_0.ts, 0, 20), Decl(ambientExternalModuleWithInternalImportDeclaration_0.ts, 3, 5))
@@ -9,7 +9,7 @@ var c = new A();
=== tests/cases/compiler/ambientExternalModuleWithoutInternalImportDeclaration_0.ts ===
declare module 'M' {
>'M' : Symbol('M', Decl(ambientExternalModuleWithoutInternalImportDeclaration_0.ts, 0, 0))
>'M' : Symbol("M", Decl(ambientExternalModuleWithoutInternalImportDeclaration_0.ts, 0, 0))
module C {
>C : Symbol(C, Decl(ambientExternalModuleWithoutInternalImportDeclaration_0.ts, 0, 20), Decl(ambientExternalModuleWithoutInternalImportDeclaration_0.ts, 3, 5))
+38 -2
View File
@@ -69,7 +69,8 @@ declare namespace ts {
pos: number;
end: number;
}
type JsDocSyntaxKind = SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.NoSubstitutionTemplateLiteral | SyntaxKind.Unknown;
type JsDocSyntaxKind = SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.NoSubstitutionTemplateLiteral | SyntaxKind.Unknown | KeywordSyntaxKind;
type KeywordSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InKeyword | SyntaxKind.InferKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.RequireKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.OfKeyword;
type JsxTokenSyntaxKind = SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken;
enum SyntaxKind {
Unknown = 0,
@@ -7515,6 +7516,26 @@ declare namespace ts.server.protocol {
*/
openFiles: string[];
}
type ProjectLoadingStartEventName = "projectLoadingStart";
interface ProjectLoadingStartEvent extends Event {
event: ProjectLoadingStartEventName;
body: ProjectLoadingStartEventBody;
}
interface ProjectLoadingStartEventBody {
/** name of the project */
projectName: string;
/** reason for loading */
reason: string;
}
type ProjectLoadingFinishEventName = "projectLoadingFinish";
interface ProjectLoadingFinishEvent extends Event {
event: ProjectLoadingFinishEventName;
body: ProjectLoadingFinishEventBody;
}
interface ProjectLoadingFinishEventBody {
/** name of the project */
projectName: string;
}
type SurveyReadyEventName = "surveyReady";
interface SurveyReadyEvent extends Event {
event: SurveyReadyEventName;
@@ -8267,6 +8288,8 @@ declare namespace ts.server {
declare namespace ts.server {
const maxProgramSizeForNonTsFiles: number;
const ProjectsUpdatedInBackgroundEvent = "projectsUpdatedInBackground";
const ProjectLoadingStartEvent = "projectLoadingStart";
const ProjectLoadingFinishEvent = "projectLoadingFinish";
const SurveyReady = "surveyReady";
const LargeFileReferencedEvent = "largeFileReferenced";
const ConfigFileDiagEvent = "configFileDiag";
@@ -8279,6 +8302,19 @@ declare namespace ts.server {
openFiles: string[];
};
}
interface ProjectLoadingStartEvent {
eventName: typeof ProjectLoadingStartEvent;
data: {
project: Project;
reason: string;
};
}
interface ProjectLoadingFinishEvent {
eventName: typeof ProjectLoadingFinishEvent;
data: {
project: Project;
};
}
interface SurveyReady {
eventName: typeof SurveyReady;
data: {
@@ -8363,7 +8399,7 @@ declare namespace ts.server {
interface OpenFileInfo {
readonly checkJs: boolean;
}
type ProjectServiceEvent = LargeFileReferencedEvent | SurveyReady | ProjectsUpdatedInBackgroundEvent | ConfigFileDiagEvent | ProjectLanguageServiceStateEvent | ProjectInfoTelemetryEvent | OpenFileInfoTelemetryEvent;
type ProjectServiceEvent = LargeFileReferencedEvent | SurveyReady | ProjectsUpdatedInBackgroundEvent | ProjectLoadingStartEvent | ProjectLoadingFinishEvent | ConfigFileDiagEvent | ProjectLanguageServiceStateEvent | ProjectInfoTelemetryEvent | OpenFileInfoTelemetryEvent;
type ProjectServiceEventHandler = (event: ProjectServiceEvent) => void;
interface SafeList {
[name: string]: {
+2 -1
View File
@@ -69,7 +69,8 @@ declare namespace ts {
pos: number;
end: number;
}
type JsDocSyntaxKind = SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.NoSubstitutionTemplateLiteral | SyntaxKind.Unknown;
type JsDocSyntaxKind = SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.NoSubstitutionTemplateLiteral | SyntaxKind.Unknown | KeywordSyntaxKind;
type KeywordSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InKeyword | SyntaxKind.InferKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.RequireKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.OfKeyword;
type JsxTokenSyntaxKind = SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken;
enum SyntaxKind {
Unknown = 0,
@@ -2,14 +2,19 @@
class A {
x() {
}
y() {
}
}
class B extends A {
// async method with only call/get on 'super' does not require a binding
async simple() {
const _super = null;
const _superIndex = null;
// call with property access
super.x();
// call additional property.
super.y();
// call with element access
super["x"]();
@@ -24,6 +29,7 @@ class B extends A {
// async method with assignment/destructuring on 'super' requires a binding
async advanced() {
const _super = null;
const _superIndex = null;
const f = () => {};
// call with property access
@@ -50,7 +56,8 @@ class B extends A {
// destructuring assign with element access
({ f: super["x"] } = { f });
}
}
}
//// [asyncMethodWithSuperConflict_es6.js]
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
@@ -64,48 +71,61 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
class A {
x() {
}
y() {
}
}
class B extends A {
// async method with only call/get on 'super' does not require a binding
simple() {
const _super_1 = name => super[name];
const _superIndex_1 = name => super[name];
const _super_1 = Object.create(null, {
x: { get: () => super.x },
y: { get: () => super.y }
});
return __awaiter(this, void 0, void 0, function* () {
const _super = null;
const _superIndex = null;
// call with property access
_super_1("x").call(this);
_super_1.x.call(this);
// call additional property.
_super_1.y.call(this);
// call with element access
_super_1("x").call(this);
_superIndex_1("x").call(this);
// property access (read)
const a = _super_1("x");
const a = _super_1.x;
// element access (read)
const b = _super_1("x");
const b = _superIndex_1("x");
});
}
// async method with assignment/destructuring on 'super' requires a binding
advanced() {
const _super_1 = (function (geti, seti) {
const _superIndex_1 = (function (geti, seti) {
const cache = Object.create(null);
return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } });
})(name => super[name], (name, value) => super[name] = value);
const _super_1 = Object.create(null, {
x: { get: () => super.x, set: v => super.x = v }
});
return __awaiter(this, void 0, void 0, function* () {
const _super = null;
const _superIndex = null;
const f = () => { };
// call with property access
_super_1("x").value.call(this);
_super_1.x.call(this);
// call with element access
_super_1("x").value.call(this);
_superIndex_1("x").value.call(this);
// property access (read)
const a = _super_1("x").value;
const a = _super_1.x;
// element access (read)
const b = _super_1("x").value;
const b = _superIndex_1("x").value;
// property access (assign)
_super_1("x").value = f;
_super_1.x = f;
// element access (assign)
_super_1("x").value = f;
_superIndex_1("x").value = f;
// destructuring assign with property access
({ f: _super_1("x").value } = { f });
({ f: _super_1.x } = { f });
// destructuring assign with element access
({ f: _super_1("x").value } = { f });
({ f: _superIndex_1("x").value } = { f });
});
}
}
@@ -5,18 +5,24 @@ class A {
x() {
>x : Symbol(A.x, Decl(asyncMethodWithSuperConflict_es6.ts, 0, 9))
}
y() {
>y : Symbol(A.y, Decl(asyncMethodWithSuperConflict_es6.ts, 2, 5))
}
}
class B extends A {
>B : Symbol(B, Decl(asyncMethodWithSuperConflict_es6.ts, 3, 1))
>B : Symbol(B, Decl(asyncMethodWithSuperConflict_es6.ts, 5, 1))
>A : Symbol(A, Decl(asyncMethodWithSuperConflict_es6.ts, 0, 0))
// async method with only call/get on 'super' does not require a binding
async simple() {
>simple : Symbol(B.simple, Decl(asyncMethodWithSuperConflict_es6.ts, 5, 19))
>simple : Symbol(B.simple, Decl(asyncMethodWithSuperConflict_es6.ts, 7, 19))
const _super = null;
>_super : Symbol(_super, Decl(asyncMethodWithSuperConflict_es6.ts, 8, 13))
>_super : Symbol(_super, Decl(asyncMethodWithSuperConflict_es6.ts, 10, 13))
const _superIndex = null;
>_superIndex : Symbol(_superIndex, Decl(asyncMethodWithSuperConflict_es6.ts, 11, 13))
// call with property access
super.x();
@@ -24,6 +30,12 @@ class B extends A {
>super : Symbol(A, Decl(asyncMethodWithSuperConflict_es6.ts, 0, 0))
>x : Symbol(A.x, Decl(asyncMethodWithSuperConflict_es6.ts, 0, 9))
// call additional property.
super.y();
>super.y : Symbol(A.y, Decl(asyncMethodWithSuperConflict_es6.ts, 2, 5))
>super : Symbol(A, Decl(asyncMethodWithSuperConflict_es6.ts, 0, 0))
>y : Symbol(A.y, Decl(asyncMethodWithSuperConflict_es6.ts, 2, 5))
// call with element access
super["x"]();
>super : Symbol(A, Decl(asyncMethodWithSuperConflict_es6.ts, 0, 0))
@@ -31,27 +43,30 @@ class B extends A {
// property access (read)
const a = super.x;
>a : Symbol(a, Decl(asyncMethodWithSuperConflict_es6.ts, 16, 13))
>a : Symbol(a, Decl(asyncMethodWithSuperConflict_es6.ts, 21, 13))
>super.x : Symbol(A.x, Decl(asyncMethodWithSuperConflict_es6.ts, 0, 9))
>super : Symbol(A, Decl(asyncMethodWithSuperConflict_es6.ts, 0, 0))
>x : Symbol(A.x, Decl(asyncMethodWithSuperConflict_es6.ts, 0, 9))
// element access (read)
const b = super["x"];
>b : Symbol(b, Decl(asyncMethodWithSuperConflict_es6.ts, 19, 13))
>b : Symbol(b, Decl(asyncMethodWithSuperConflict_es6.ts, 24, 13))
>super : Symbol(A, Decl(asyncMethodWithSuperConflict_es6.ts, 0, 0))
>"x" : Symbol(A.x, Decl(asyncMethodWithSuperConflict_es6.ts, 0, 9))
}
// async method with assignment/destructuring on 'super' requires a binding
async advanced() {
>advanced : Symbol(B.advanced, Decl(asyncMethodWithSuperConflict_es6.ts, 20, 5))
>advanced : Symbol(B.advanced, Decl(asyncMethodWithSuperConflict_es6.ts, 25, 5))
const _super = null;
>_super : Symbol(_super, Decl(asyncMethodWithSuperConflict_es6.ts, 24, 13))
>_super : Symbol(_super, Decl(asyncMethodWithSuperConflict_es6.ts, 29, 13))
const _superIndex = null;
>_superIndex : Symbol(_superIndex, Decl(asyncMethodWithSuperConflict_es6.ts, 30, 13))
const f = () => {};
>f : Symbol(f, Decl(asyncMethodWithSuperConflict_es6.ts, 25, 13))
>f : Symbol(f, Decl(asyncMethodWithSuperConflict_es6.ts, 31, 13))
// call with property access
super.x();
@@ -66,14 +81,14 @@ class B extends A {
// property access (read)
const a = super.x;
>a : Symbol(a, Decl(asyncMethodWithSuperConflict_es6.ts, 34, 13))
>a : Symbol(a, Decl(asyncMethodWithSuperConflict_es6.ts, 40, 13))
>super.x : Symbol(A.x, Decl(asyncMethodWithSuperConflict_es6.ts, 0, 9))
>super : Symbol(A, Decl(asyncMethodWithSuperConflict_es6.ts, 0, 0))
>x : Symbol(A.x, Decl(asyncMethodWithSuperConflict_es6.ts, 0, 9))
// element access (read)
const b = super["x"];
>b : Symbol(b, Decl(asyncMethodWithSuperConflict_es6.ts, 37, 13))
>b : Symbol(b, Decl(asyncMethodWithSuperConflict_es6.ts, 43, 13))
>super : Symbol(A, Decl(asyncMethodWithSuperConflict_es6.ts, 0, 0))
>"x" : Symbol(A.x, Decl(asyncMethodWithSuperConflict_es6.ts, 0, 9))
@@ -82,27 +97,28 @@ class B extends A {
>super.x : Symbol(A.x, Decl(asyncMethodWithSuperConflict_es6.ts, 0, 9))
>super : Symbol(A, Decl(asyncMethodWithSuperConflict_es6.ts, 0, 0))
>x : Symbol(A.x, Decl(asyncMethodWithSuperConflict_es6.ts, 0, 9))
>f : Symbol(f, Decl(asyncMethodWithSuperConflict_es6.ts, 25, 13))
>f : Symbol(f, Decl(asyncMethodWithSuperConflict_es6.ts, 31, 13))
// element access (assign)
super["x"] = f;
>super : Symbol(A, Decl(asyncMethodWithSuperConflict_es6.ts, 0, 0))
>"x" : Symbol(A.x, Decl(asyncMethodWithSuperConflict_es6.ts, 0, 9))
>f : Symbol(f, Decl(asyncMethodWithSuperConflict_es6.ts, 25, 13))
>f : Symbol(f, Decl(asyncMethodWithSuperConflict_es6.ts, 31, 13))
// destructuring assign with property access
({ f: super.x } = { f });
>f : Symbol(f, Decl(asyncMethodWithSuperConflict_es6.ts, 46, 10))
>f : Symbol(f, Decl(asyncMethodWithSuperConflict_es6.ts, 52, 10))
>super.x : Symbol(A.x, Decl(asyncMethodWithSuperConflict_es6.ts, 0, 9))
>super : Symbol(A, Decl(asyncMethodWithSuperConflict_es6.ts, 0, 0))
>x : Symbol(A.x, Decl(asyncMethodWithSuperConflict_es6.ts, 0, 9))
>f : Symbol(f, Decl(asyncMethodWithSuperConflict_es6.ts, 46, 27))
>f : Symbol(f, Decl(asyncMethodWithSuperConflict_es6.ts, 52, 27))
// destructuring assign with element access
({ f: super["x"] } = { f });
>f : Symbol(f, Decl(asyncMethodWithSuperConflict_es6.ts, 49, 10))
>f : Symbol(f, Decl(asyncMethodWithSuperConflict_es6.ts, 55, 10))
>super : Symbol(A, Decl(asyncMethodWithSuperConflict_es6.ts, 0, 0))
>"x" : Symbol(A.x, Decl(asyncMethodWithSuperConflict_es6.ts, 0, 9))
>f : Symbol(f, Decl(asyncMethodWithSuperConflict_es6.ts, 49, 30))
>f : Symbol(f, Decl(asyncMethodWithSuperConflict_es6.ts, 55, 30))
}
}
@@ -5,6 +5,9 @@ class A {
x() {
>x : () => void
}
y() {
>y : () => void
}
}
class B extends A {
@@ -17,6 +20,10 @@ class B extends A {
const _super = null;
>_super : any
>null : null
const _superIndex = null;
>_superIndex : any
>null : null
// call with property access
@@ -26,6 +33,13 @@ class B extends A {
>super : A
>x : () => void
// call additional property.
super.y();
>super.y() : void
>super.y : () => void
>super : A
>y : () => void
// call with element access
super["x"]();
>super["x"]() : void
@@ -54,6 +68,10 @@ class B extends A {
const _super = null;
>_super : any
>null : null
const _superIndex = null;
>_superIndex : any
>null : null
const f = () => {};
@@ -129,3 +147,4 @@ class B extends A {
>f : () => void
}
}
@@ -2,6 +2,8 @@
class A {
x() {
}
y() {
}
}
class B extends A {
@@ -9,6 +11,8 @@ class B extends A {
async simple() {
// call with property access
super.x();
// call additional property.
super.y();
// call with element access
super["x"]();
@@ -48,18 +52,23 @@ class B extends A {
// destructuring assign with element access
({ f: super["x"] } = { f });
}
}
}
//// [asyncMethodWithSuper_es2017.js]
class A {
x() {
}
y() {
}
}
class B extends A {
// async method with only call/get on 'super' does not require a binding
async simple() {
// call with property access
super.x();
// call additional property.
super.y();
// call with element access
super["x"]();
// property access (read)
@@ -5,15 +5,18 @@ class A {
x() {
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9))
}
y() {
>y : Symbol(A.y, Decl(asyncMethodWithSuper_es2017.ts, 2, 5))
}
}
class B extends A {
>B : Symbol(B, Decl(asyncMethodWithSuper_es2017.ts, 3, 1))
>B : Symbol(B, Decl(asyncMethodWithSuper_es2017.ts, 5, 1))
>A : Symbol(A, Decl(asyncMethodWithSuper_es2017.ts, 0, 0))
// async method with only call/get on 'super' does not require a binding
async simple() {
>simple : Symbol(B.simple, Decl(asyncMethodWithSuper_es2017.ts, 5, 19))
>simple : Symbol(B.simple, Decl(asyncMethodWithSuper_es2017.ts, 7, 19))
// call with property access
super.x();
@@ -21,6 +24,12 @@ class B extends A {
>super : Symbol(A, Decl(asyncMethodWithSuper_es2017.ts, 0, 0))
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9))
// call additional property.
super.y();
>super.y : Symbol(A.y, Decl(asyncMethodWithSuper_es2017.ts, 2, 5))
>super : Symbol(A, Decl(asyncMethodWithSuper_es2017.ts, 0, 0))
>y : Symbol(A.y, Decl(asyncMethodWithSuper_es2017.ts, 2, 5))
// call with element access
super["x"]();
>super : Symbol(A, Decl(asyncMethodWithSuper_es2017.ts, 0, 0))
@@ -28,24 +37,24 @@ class B extends A {
// property access (read)
const a = super.x;
>a : Symbol(a, Decl(asyncMethodWithSuper_es2017.ts, 15, 13))
>a : Symbol(a, Decl(asyncMethodWithSuper_es2017.ts, 19, 13))
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9))
>super : Symbol(A, Decl(asyncMethodWithSuper_es2017.ts, 0, 0))
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9))
// element access (read)
const b = super["x"];
>b : Symbol(b, Decl(asyncMethodWithSuper_es2017.ts, 18, 13))
>b : Symbol(b, Decl(asyncMethodWithSuper_es2017.ts, 22, 13))
>super : Symbol(A, Decl(asyncMethodWithSuper_es2017.ts, 0, 0))
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9))
}
// async method with assignment/destructuring on 'super' requires a binding
async advanced() {
>advanced : Symbol(B.advanced, Decl(asyncMethodWithSuper_es2017.ts, 19, 5))
>advanced : Symbol(B.advanced, Decl(asyncMethodWithSuper_es2017.ts, 23, 5))
const f = () => {};
>f : Symbol(f, Decl(asyncMethodWithSuper_es2017.ts, 23, 13))
>f : Symbol(f, Decl(asyncMethodWithSuper_es2017.ts, 27, 13))
// call with property access
super.x();
@@ -60,14 +69,14 @@ class B extends A {
// property access (read)
const a = super.x;
>a : Symbol(a, Decl(asyncMethodWithSuper_es2017.ts, 32, 13))
>a : Symbol(a, Decl(asyncMethodWithSuper_es2017.ts, 36, 13))
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9))
>super : Symbol(A, Decl(asyncMethodWithSuper_es2017.ts, 0, 0))
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9))
// element access (read)
const b = super["x"];
>b : Symbol(b, Decl(asyncMethodWithSuper_es2017.ts, 35, 13))
>b : Symbol(b, Decl(asyncMethodWithSuper_es2017.ts, 39, 13))
>super : Symbol(A, Decl(asyncMethodWithSuper_es2017.ts, 0, 0))
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9))
@@ -76,27 +85,28 @@ class B extends A {
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9))
>super : Symbol(A, Decl(asyncMethodWithSuper_es2017.ts, 0, 0))
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9))
>f : Symbol(f, Decl(asyncMethodWithSuper_es2017.ts, 23, 13))
>f : Symbol(f, Decl(asyncMethodWithSuper_es2017.ts, 27, 13))
// element access (assign)
super["x"] = f;
>super : Symbol(A, Decl(asyncMethodWithSuper_es2017.ts, 0, 0))
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9))
>f : Symbol(f, Decl(asyncMethodWithSuper_es2017.ts, 23, 13))
>f : Symbol(f, Decl(asyncMethodWithSuper_es2017.ts, 27, 13))
// destructuring assign with property access
({ f: super.x } = { f });
>f : Symbol(f, Decl(asyncMethodWithSuper_es2017.ts, 44, 10))
>f : Symbol(f, Decl(asyncMethodWithSuper_es2017.ts, 48, 10))
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9))
>super : Symbol(A, Decl(asyncMethodWithSuper_es2017.ts, 0, 0))
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9))
>f : Symbol(f, Decl(asyncMethodWithSuper_es2017.ts, 44, 27))
>f : Symbol(f, Decl(asyncMethodWithSuper_es2017.ts, 48, 27))
// destructuring assign with element access
({ f: super["x"] } = { f });
>f : Symbol(f, Decl(asyncMethodWithSuper_es2017.ts, 47, 10))
>f : Symbol(f, Decl(asyncMethodWithSuper_es2017.ts, 51, 10))
>super : Symbol(A, Decl(asyncMethodWithSuper_es2017.ts, 0, 0))
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9))
>f : Symbol(f, Decl(asyncMethodWithSuper_es2017.ts, 47, 30))
>f : Symbol(f, Decl(asyncMethodWithSuper_es2017.ts, 51, 30))
}
}
@@ -5,6 +5,9 @@ class A {
x() {
>x : () => void
}
y() {
>y : () => void
}
}
class B extends A {
@@ -22,6 +25,13 @@ class B extends A {
>super : A
>x : () => void
// call additional property.
super.y();
>super.y() : void
>super.y : () => void
>super : A
>y : () => void
// call with element access
super["x"]();
>super["x"]() : void
@@ -121,3 +131,4 @@ class B extends A {
>f : () => void
}
}
@@ -2,6 +2,8 @@
class A {
x() {
}
y() {
}
}
class B extends A {
@@ -9,6 +11,8 @@ class B extends A {
async simple() {
// call with property access
super.x();
// call additional property.
super.y();
// call with element access
super["x"]();
@@ -48,7 +52,8 @@ class B extends A {
// destructuring assign with element access
({ f: super["x"] } = { f });
}
}
}
//// [asyncMethodWithSuper_es5.js]
var A = /** @class */ (function () {
@@ -56,6 +61,8 @@ var A = /** @class */ (function () {
}
A.prototype.x = function () {
};
A.prototype.y = function () {
};
return A;
}());
var B = /** @class */ (function (_super) {
@@ -70,6 +77,8 @@ var B = /** @class */ (function (_super) {
return __generator(this, function (_a) {
// call with property access
_super.prototype.x.call(this);
// call additional property.
_super.prototype.y.call(this);
// call with element access
_super.prototype["x"].call(this);
a = _super.prototype.x;
@@ -5,15 +5,18 @@ class A {
x() {
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es5.ts, 0, 9))
}
y() {
>y : Symbol(A.y, Decl(asyncMethodWithSuper_es5.ts, 2, 5))
}
}
class B extends A {
>B : Symbol(B, Decl(asyncMethodWithSuper_es5.ts, 3, 1))
>B : Symbol(B, Decl(asyncMethodWithSuper_es5.ts, 5, 1))
>A : Symbol(A, Decl(asyncMethodWithSuper_es5.ts, 0, 0))
// async method with only call/get on 'super' does not require a binding
async simple() {
>simple : Symbol(B.simple, Decl(asyncMethodWithSuper_es5.ts, 5, 19))
>simple : Symbol(B.simple, Decl(asyncMethodWithSuper_es5.ts, 7, 19))
// call with property access
super.x();
@@ -21,6 +24,12 @@ class B extends A {
>super : Symbol(A, Decl(asyncMethodWithSuper_es5.ts, 0, 0))
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es5.ts, 0, 9))
// call additional property.
super.y();
>super.y : Symbol(A.y, Decl(asyncMethodWithSuper_es5.ts, 2, 5))
>super : Symbol(A, Decl(asyncMethodWithSuper_es5.ts, 0, 0))
>y : Symbol(A.y, Decl(asyncMethodWithSuper_es5.ts, 2, 5))
// call with element access
super["x"]();
>super : Symbol(A, Decl(asyncMethodWithSuper_es5.ts, 0, 0))
@@ -28,24 +37,24 @@ class B extends A {
// property access (read)
const a = super.x;
>a : Symbol(a, Decl(asyncMethodWithSuper_es5.ts, 15, 13))
>a : Symbol(a, Decl(asyncMethodWithSuper_es5.ts, 19, 13))
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es5.ts, 0, 9))
>super : Symbol(A, Decl(asyncMethodWithSuper_es5.ts, 0, 0))
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es5.ts, 0, 9))
// element access (read)
const b = super["x"];
>b : Symbol(b, Decl(asyncMethodWithSuper_es5.ts, 18, 13))
>b : Symbol(b, Decl(asyncMethodWithSuper_es5.ts, 22, 13))
>super : Symbol(A, Decl(asyncMethodWithSuper_es5.ts, 0, 0))
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es5.ts, 0, 9))
}
// async method with assignment/destructuring on 'super' requires a binding
async advanced() {
>advanced : Symbol(B.advanced, Decl(asyncMethodWithSuper_es5.ts, 19, 5))
>advanced : Symbol(B.advanced, Decl(asyncMethodWithSuper_es5.ts, 23, 5))
const f = () => {};
>f : Symbol(f, Decl(asyncMethodWithSuper_es5.ts, 23, 13))
>f : Symbol(f, Decl(asyncMethodWithSuper_es5.ts, 27, 13))
// call with property access
super.x();
@@ -60,14 +69,14 @@ class B extends A {
// property access (read)
const a = super.x;
>a : Symbol(a, Decl(asyncMethodWithSuper_es5.ts, 32, 13))
>a : Symbol(a, Decl(asyncMethodWithSuper_es5.ts, 36, 13))
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es5.ts, 0, 9))
>super : Symbol(A, Decl(asyncMethodWithSuper_es5.ts, 0, 0))
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es5.ts, 0, 9))
// element access (read)
const b = super["x"];
>b : Symbol(b, Decl(asyncMethodWithSuper_es5.ts, 35, 13))
>b : Symbol(b, Decl(asyncMethodWithSuper_es5.ts, 39, 13))
>super : Symbol(A, Decl(asyncMethodWithSuper_es5.ts, 0, 0))
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es5.ts, 0, 9))
@@ -76,27 +85,28 @@ class B extends A {
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es5.ts, 0, 9))
>super : Symbol(A, Decl(asyncMethodWithSuper_es5.ts, 0, 0))
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es5.ts, 0, 9))
>f : Symbol(f, Decl(asyncMethodWithSuper_es5.ts, 23, 13))
>f : Symbol(f, Decl(asyncMethodWithSuper_es5.ts, 27, 13))
// element access (assign)
super["x"] = f;
>super : Symbol(A, Decl(asyncMethodWithSuper_es5.ts, 0, 0))
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es5.ts, 0, 9))
>f : Symbol(f, Decl(asyncMethodWithSuper_es5.ts, 23, 13))
>f : Symbol(f, Decl(asyncMethodWithSuper_es5.ts, 27, 13))
// destructuring assign with property access
({ f: super.x } = { f });
>f : Symbol(f, Decl(asyncMethodWithSuper_es5.ts, 44, 10))
>f : Symbol(f, Decl(asyncMethodWithSuper_es5.ts, 48, 10))
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es5.ts, 0, 9))
>super : Symbol(A, Decl(asyncMethodWithSuper_es5.ts, 0, 0))
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es5.ts, 0, 9))
>f : Symbol(f, Decl(asyncMethodWithSuper_es5.ts, 44, 27))
>f : Symbol(f, Decl(asyncMethodWithSuper_es5.ts, 48, 27))
// destructuring assign with element access
({ f: super["x"] } = { f });
>f : Symbol(f, Decl(asyncMethodWithSuper_es5.ts, 47, 10))
>f : Symbol(f, Decl(asyncMethodWithSuper_es5.ts, 51, 10))
>super : Symbol(A, Decl(asyncMethodWithSuper_es5.ts, 0, 0))
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es5.ts, 0, 9))
>f : Symbol(f, Decl(asyncMethodWithSuper_es5.ts, 47, 30))
>f : Symbol(f, Decl(asyncMethodWithSuper_es5.ts, 51, 30))
}
}
@@ -5,6 +5,9 @@ class A {
x() {
>x : () => void
}
y() {
>y : () => void
}
}
class B extends A {
@@ -22,6 +25,13 @@ class B extends A {
>super : A
>x : () => void
// call additional property.
super.y();
>super.y() : void
>super.y : () => void
>super : A
>y : () => void
// call with element access
super["x"]();
>super["x"]() : void
@@ -121,3 +131,4 @@ class B extends A {
>f : () => void
}
}
@@ -2,6 +2,8 @@
class A {
x() {
}
y() {
}
}
class B extends A {
@@ -9,6 +11,8 @@ class B extends A {
async simple() {
// call with property access
super.x();
// call additional property.
super.y();
// call with element access
super["x"]();
@@ -48,52 +52,64 @@ class B extends A {
// destructuring assign with element access
({ f: super["x"] } = { f });
}
}
}
//// [asyncMethodWithSuper_es6.js]
class A {
x() {
}
y() {
}
}
class B extends A {
// async method with only call/get on 'super' does not require a binding
simple() {
const _super = name => super[name];
const _superIndex = name => super[name];
const _super = Object.create(null, {
x: { get: () => super.x },
y: { get: () => super.y }
});
return __awaiter(this, void 0, void 0, function* () {
// call with property access
_super("x").call(this);
_super.x.call(this);
// call additional property.
_super.y.call(this);
// call with element access
_super("x").call(this);
_superIndex("x").call(this);
// property access (read)
const a = _super("x");
const a = _super.x;
// element access (read)
const b = _super("x");
const b = _superIndex("x");
});
}
// async method with assignment/destructuring on 'super' requires a binding
advanced() {
const _super = (function (geti, seti) {
const _superIndex = (function (geti, seti) {
const cache = Object.create(null);
return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } });
})(name => super[name], (name, value) => super[name] = value);
const _super = Object.create(null, {
x: { get: () => super.x, set: v => super.x = v }
});
return __awaiter(this, void 0, void 0, function* () {
const f = () => { };
// call with property access
_super("x").value.call(this);
_super.x.call(this);
// call with element access
_super("x").value.call(this);
_superIndex("x").value.call(this);
// property access (read)
const a = _super("x").value;
const a = _super.x;
// element access (read)
const b = _super("x").value;
const b = _superIndex("x").value;
// property access (assign)
_super("x").value = f;
_super.x = f;
// element access (assign)
_super("x").value = f;
_superIndex("x").value = f;
// destructuring assign with property access
({ f: _super("x").value } = { f });
({ f: _super.x } = { f });
// destructuring assign with element access
({ f: _super("x").value } = { f });
({ f: _superIndex("x").value } = { f });
});
}
}
@@ -5,15 +5,18 @@ class A {
x() {
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
}
y() {
>y : Symbol(A.y, Decl(asyncMethodWithSuper_es6.ts, 2, 5))
}
}
class B extends A {
>B : Symbol(B, Decl(asyncMethodWithSuper_es6.ts, 3, 1))
>B : Symbol(B, Decl(asyncMethodWithSuper_es6.ts, 5, 1))
>A : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
// async method with only call/get on 'super' does not require a binding
async simple() {
>simple : Symbol(B.simple, Decl(asyncMethodWithSuper_es6.ts, 5, 19))
>simple : Symbol(B.simple, Decl(asyncMethodWithSuper_es6.ts, 7, 19))
// call with property access
super.x();
@@ -21,6 +24,12 @@ class B extends A {
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
// call additional property.
super.y();
>super.y : Symbol(A.y, Decl(asyncMethodWithSuper_es6.ts, 2, 5))
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>y : Symbol(A.y, Decl(asyncMethodWithSuper_es6.ts, 2, 5))
// call with element access
super["x"]();
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
@@ -28,24 +37,24 @@ class B extends A {
// property access (read)
const a = super.x;
>a : Symbol(a, Decl(asyncMethodWithSuper_es6.ts, 15, 13))
>a : Symbol(a, Decl(asyncMethodWithSuper_es6.ts, 19, 13))
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
// element access (read)
const b = super["x"];
>b : Symbol(b, Decl(asyncMethodWithSuper_es6.ts, 18, 13))
>b : Symbol(b, Decl(asyncMethodWithSuper_es6.ts, 22, 13))
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
}
// async method with assignment/destructuring on 'super' requires a binding
async advanced() {
>advanced : Symbol(B.advanced, Decl(asyncMethodWithSuper_es6.ts, 19, 5))
>advanced : Symbol(B.advanced, Decl(asyncMethodWithSuper_es6.ts, 23, 5))
const f = () => {};
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 23, 13))
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 27, 13))
// call with property access
super.x();
@@ -60,14 +69,14 @@ class B extends A {
// property access (read)
const a = super.x;
>a : Symbol(a, Decl(asyncMethodWithSuper_es6.ts, 32, 13))
>a : Symbol(a, Decl(asyncMethodWithSuper_es6.ts, 36, 13))
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
// element access (read)
const b = super["x"];
>b : Symbol(b, Decl(asyncMethodWithSuper_es6.ts, 35, 13))
>b : Symbol(b, Decl(asyncMethodWithSuper_es6.ts, 39, 13))
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
@@ -76,27 +85,28 @@ class B extends A {
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 23, 13))
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 27, 13))
// element access (assign)
super["x"] = f;
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 23, 13))
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 27, 13))
// destructuring assign with property access
({ f: super.x } = { f });
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 44, 10))
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 48, 10))
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 44, 27))
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 48, 27))
// destructuring assign with element access
({ f: super["x"] } = { f });
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 47, 10))
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 51, 10))
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 47, 30))
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 51, 30))
}
}
@@ -5,6 +5,9 @@ class A {
x() {
>x : () => void
}
y() {
>y : () => void
}
}
class B extends A {
@@ -22,6 +25,13 @@ class B extends A {
>super : A
>x : () => void
// call additional property.
super.y();
>super.y() : void
>super.y : () => void
>super : A
>y : () => void
// call with element access
super["x"]();
>super["x"]() : void
@@ -121,3 +131,4 @@ class B extends A {
>f : () => void
}
}
@@ -1,9 +1,9 @@
=== tests/cases/compiler/file1.ts ===
function foo() {}
>foo : Symbol(foo, Decl(file1.ts, 0, 0), Decl(file1.ts, 0, 17), Decl(file2.ts, 1, 8))
>foo : Symbol("tests/cases/compiler/file1.ts", Decl(file1.ts, 0, 0), Decl(file1.ts, 0, 17), Decl(file2.ts, 1, 8))
namespace foo {
>foo : Symbol(foo, Decl(file1.ts, 0, 0), Decl(file1.ts, 0, 17), Decl(file2.ts, 1, 8))
>foo : Symbol("tests/cases/compiler/file1.ts", Decl(file1.ts, 0, 0), Decl(file1.ts, 0, 17), Decl(file2.ts, 1, 8))
export var v = 1;
>v : Symbol(v, Decl(file1.ts, 2, 14))
@@ -3,10 +3,10 @@ declare module "file1" {
>"file1" : Symbol("file1", Decl(file1.d.ts, 0, 0))
function foo(): void;
>foo : Symbol(foo, Decl(file1.d.ts, 0, 24), Decl(file1.d.ts, 1, 25), Decl(file2.ts, 2, 8))
>foo : Symbol("tests/cases/compiler/file1.d.ts", Decl(file1.d.ts, 0, 24), Decl(file1.d.ts, 1, 25), Decl(file2.ts, 2, 8))
namespace foo {
>foo : Symbol(foo, Decl(file1.d.ts, 0, 24), Decl(file1.d.ts, 1, 25), Decl(file2.ts, 2, 8))
>foo : Symbol("tests/cases/compiler/file1.d.ts", Decl(file1.d.ts, 0, 24), Decl(file1.d.ts, 1, 25), Decl(file2.ts, 2, 8))
export var v: number;
>v : Symbol(v, Decl(file1.d.ts, 3, 18))
@@ -1,9 +1,9 @@
=== tests/cases/compiler/file1.ts ===
class foo {}
>foo : Symbol(foo, Decl(file1.ts, 0, 0), Decl(file1.ts, 0, 12), Decl(file2.ts, 1, 8))
>foo : Symbol("tests/cases/compiler/file1.ts", Decl(file1.ts, 0, 0), Decl(file1.ts, 0, 12), Decl(file2.ts, 1, 8))
namespace foo {
>foo : Symbol(foo, Decl(file1.ts, 0, 0), Decl(file1.ts, 0, 12), Decl(file2.ts, 1, 8))
>foo : Symbol("tests/cases/compiler/file1.ts", Decl(file1.ts, 0, 0), Decl(file1.ts, 0, 12), Decl(file2.ts, 1, 8))
export var v = 1;
>v : Symbol(v, Decl(file1.ts, 2, 14))
@@ -3,10 +3,10 @@ declare module "file1" {
>"file1" : Symbol("file1", Decl(file1.d.ts, 0, 0))
class foo {}
>foo : Symbol(foo, Decl(file1.d.ts, 0, 24), Decl(file1.d.ts, 1, 16), Decl(file2.ts, 2, 8))
>foo : Symbol("tests/cases/compiler/file1.d.ts", Decl(file1.d.ts, 0, 24), Decl(file1.d.ts, 1, 16), Decl(file2.ts, 2, 8))
namespace foo {
>foo : Symbol(foo, Decl(file1.d.ts, 0, 24), Decl(file1.d.ts, 1, 16), Decl(file2.ts, 2, 8))
>foo : Symbol("tests/cases/compiler/file1.d.ts", Decl(file1.d.ts, 0, 24), Decl(file1.d.ts, 1, 16), Decl(file2.ts, 2, 8))
export var v: number;
>v : Symbol(v, Decl(file1.d.ts, 3, 18))
@@ -16,12 +16,12 @@ declare module "express" {
>"express" : Symbol("express", Decl(express.d.ts, 4, 1))
function e(): e.Express;
>e : Symbol(e, Decl(express.d.ts, 6, 26), Decl(express.d.ts, 7, 28), Decl(augmentation.ts, 1, 29))
>e : Symbol("tests/cases/compiler/express.d.ts", Decl(express.d.ts, 6, 26), Decl(express.d.ts, 7, 28), Decl(augmentation.ts, 1, 29))
>e : Symbol(e, Decl(express.d.ts, 6, 26), Decl(express.d.ts, 7, 28))
>Express : Symbol(Express, Decl(express.d.ts, 52, 9))
namespace e {
>e : Symbol(e, Decl(express.d.ts, 6, 26), Decl(express.d.ts, 7, 28), Decl(augmentation.ts, 1, 29))
>e : Symbol("tests/cases/compiler/express.d.ts", Decl(express.d.ts, 6, 26), Decl(express.d.ts, 7, 28), Decl(augmentation.ts, 1, 29))
interface IRoute {
>IRoute : Symbol(IRoute, Decl(express.d.ts, 8, 17))
@@ -1,9 +1,9 @@
=== tests/cases/compiler/file1.ts ===
class foo {}
>foo : Symbol(foo, Decl(file1.ts, 0, 0), Decl(file1.ts, 0, 12), Decl(file2.ts, 1, 10))
>foo : Symbol("tests/cases/compiler/file1.ts", Decl(file1.ts, 0, 0), Decl(file1.ts, 0, 12), Decl(file2.ts, 1, 10))
namespace foo {
>foo : Symbol(foo, Decl(file1.ts, 0, 0), Decl(file1.ts, 0, 12), Decl(file2.ts, 1, 10))
>foo : Symbol("tests/cases/compiler/file1.ts", Decl(file1.ts, 0, 0), Decl(file1.ts, 0, 12), Decl(file2.ts, 1, 10))
export class A {}
>A : Symbol(A, Decl(file1.ts, 1, 15), Decl(file2.ts, 4, 26))
@@ -3,10 +3,10 @@ declare module "file1" {
>"file1" : Symbol("file1", Decl(file1.d.ts, 0, 0))
class foo {}
>foo : Symbol(foo, Decl(file1.d.ts, 0, 24), Decl(file1.d.ts, 1, 16), Decl(file2.ts, 1, 28))
>foo : Symbol("tests/cases/compiler/file1.d.ts", Decl(file1.d.ts, 0, 24), Decl(file1.d.ts, 1, 16), Decl(file2.ts, 1, 28))
namespace foo {
>foo : Symbol(foo, Decl(file1.d.ts, 0, 24), Decl(file1.d.ts, 1, 16), Decl(file2.ts, 1, 28))
>foo : Symbol("tests/cases/compiler/file1.d.ts", Decl(file1.d.ts, 0, 24), Decl(file1.d.ts, 1, 16), Decl(file2.ts, 1, 28))
class A {}
>A : Symbol(A, Decl(file1.d.ts, 2, 19), Decl(file2.ts, 4, 24))
@@ -10,7 +10,7 @@ declare module "http" {
}
declare module 'intern/dojo/node!http' {
>'intern/dojo/node!http' : Symbol('intern/dojo/node!http', Decl(a.d.ts, 1, 1))
>'intern/dojo/node!http' : Symbol("intern/dojo/node!http", Decl(a.d.ts, 1, 1))
import http = require('http');
>http : Symbol(http, Decl(a.d.ts, 3, 40))
@@ -0,0 +1,35 @@
tests/cases/conformance/jsx/checkJsxChildrenCanBeTupleType.tsx(17,18): error TS2322: Type '{ children: [Element, Element, Element]; }' is not assignable to type 'Readonly<ResizablePanelProps>'.
Types of property 'children' are incompatible.
Type '[Element, Element, Element]' is not assignable to type '[ReactNode, ReactNode]'.
Types of property 'length' are incompatible.
Type '3' is not assignable to type '2'.
==== tests/cases/conformance/jsx/checkJsxChildrenCanBeTupleType.tsx (1 errors) ====
/// <reference path="/.lib/react16.d.ts" />
import React from 'react'
interface ResizablePanelProps {
children: [React.ReactNode, React.ReactNode]
}
class ResizablePanel extends React.Component<
ResizablePanelProps, any> {}
const test = <ResizablePanel>
<div />
<div />
</ResizablePanel>
const testErr = <ResizablePanel>
~~~~~~~~~~~~~~
!!! error TS2322: Type '{ children: [Element, Element, Element]; }' is not assignable to type 'Readonly<ResizablePanelProps>'.
!!! error TS2322: Types of property 'children' are incompatible.
!!! error TS2322: Type '[Element, Element, Element]' is not assignable to type '[ReactNode, ReactNode]'.
!!! error TS2322: Types of property 'length' are incompatible.
!!! error TS2322: Type '3' is not assignable to type '2'.
<div />
<div />
<div />
</ResizablePanel>
@@ -0,0 +1,58 @@
//// [checkJsxChildrenCanBeTupleType.tsx]
/// <reference path="/.lib/react16.d.ts" />
import React from 'react'
interface ResizablePanelProps {
children: [React.ReactNode, React.ReactNode]
}
class ResizablePanel extends React.Component<
ResizablePanelProps, any> {}
const test = <ResizablePanel>
<div />
<div />
</ResizablePanel>
const testErr = <ResizablePanel>
<div />
<div />
<div />
</ResizablePanel>
//// [checkJsxChildrenCanBeTupleType.js]
"use strict";
/// <reference path="react16.d.ts" />
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
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 extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
exports.__esModule = true;
var react_1 = __importDefault(require("react"));
var ResizablePanel = /** @class */ (function (_super) {
__extends(ResizablePanel, _super);
function ResizablePanel() {
return _super !== null && _super.apply(this, arguments) || this;
}
return ResizablePanel;
}(react_1["default"].Component));
var test = react_1["default"].createElement(ResizablePanel, null,
react_1["default"].createElement("div", null),
react_1["default"].createElement("div", null));
var testErr = react_1["default"].createElement(ResizablePanel, null,
react_1["default"].createElement("div", null),
react_1["default"].createElement("div", null),
react_1["default"].createElement("div", null));
@@ -0,0 +1,55 @@
=== tests/cases/conformance/jsx/checkJsxChildrenCanBeTupleType.tsx ===
/// <reference path="react16.d.ts" />
import React from 'react'
>React : Symbol(React, Decl(checkJsxChildrenCanBeTupleType.tsx, 2, 6))
interface ResizablePanelProps {
>ResizablePanelProps : Symbol(ResizablePanelProps, Decl(checkJsxChildrenCanBeTupleType.tsx, 2, 25))
children: [React.ReactNode, React.ReactNode]
>children : Symbol(ResizablePanelProps.children, Decl(checkJsxChildrenCanBeTupleType.tsx, 4, 31))
>React : Symbol(React, Decl(checkJsxChildrenCanBeTupleType.tsx, 2, 6))
>ReactNode : Symbol(React.ReactNode, Decl(react16.d.ts, 216, 49))
>React : Symbol(React, Decl(checkJsxChildrenCanBeTupleType.tsx, 2, 6))
>ReactNode : Symbol(React.ReactNode, Decl(react16.d.ts, 216, 49))
}
class ResizablePanel extends React.Component<
>ResizablePanel : Symbol(ResizablePanel, Decl(checkJsxChildrenCanBeTupleType.tsx, 6, 1))
>React.Component : Symbol(React.Component, Decl(react16.d.ts, 345, 54), Decl(react16.d.ts, 349, 94))
>React : Symbol(React, Decl(checkJsxChildrenCanBeTupleType.tsx, 2, 6))
>Component : Symbol(React.Component, Decl(react16.d.ts, 345, 54), Decl(react16.d.ts, 349, 94))
ResizablePanelProps, any> {}
>ResizablePanelProps : Symbol(ResizablePanelProps, Decl(checkJsxChildrenCanBeTupleType.tsx, 2, 25))
const test = <ResizablePanel>
>test : Symbol(test, Decl(checkJsxChildrenCanBeTupleType.tsx, 11, 5))
>ResizablePanel : Symbol(ResizablePanel, Decl(checkJsxChildrenCanBeTupleType.tsx, 6, 1))
<div />
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
<div />
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
</ResizablePanel>
>ResizablePanel : Symbol(ResizablePanel, Decl(checkJsxChildrenCanBeTupleType.tsx, 6, 1))
const testErr = <ResizablePanel>
>testErr : Symbol(testErr, Decl(checkJsxChildrenCanBeTupleType.tsx, 16, 5))
>ResizablePanel : Symbol(ResizablePanel, Decl(checkJsxChildrenCanBeTupleType.tsx, 6, 1))
<div />
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
<div />
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
<div />
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
</ResizablePanel>
>ResizablePanel : Symbol(ResizablePanel, Decl(checkJsxChildrenCanBeTupleType.tsx, 6, 1))
@@ -0,0 +1,57 @@
=== tests/cases/conformance/jsx/checkJsxChildrenCanBeTupleType.tsx ===
/// <reference path="react16.d.ts" />
import React from 'react'
>React : typeof React
interface ResizablePanelProps {
children: [React.ReactNode, React.ReactNode]
>children : [React.ReactNode, React.ReactNode]
>React : any
>React : any
}
class ResizablePanel extends React.Component<
>ResizablePanel : ResizablePanel
>React.Component : React.Component<ResizablePanelProps, any, any>
>React : typeof React
>Component : typeof React.Component
ResizablePanelProps, any> {}
const test = <ResizablePanel>
>test : JSX.Element
><ResizablePanel> <div /> <div /></ResizablePanel> : JSX.Element
>ResizablePanel : typeof ResizablePanel
<div />
><div /> : JSX.Element
>div : any
<div />
><div /> : JSX.Element
>div : any
</ResizablePanel>
>ResizablePanel : typeof ResizablePanel
const testErr = <ResizablePanel>
>testErr : JSX.Element
><ResizablePanel> <div /> <div /> <div /></ResizablePanel> : JSX.Element
>ResizablePanel : typeof ResizablePanel
<div />
><div /> : JSX.Element
>div : any
<div />
><div /> : JSX.Element
>div : any
<div />
><div /> : JSX.Element
>div : any
</ResizablePanel>
>ResizablePanel : typeof ResizablePanel
@@ -0,0 +1,63 @@
//// [checkJsxUnionSFXContextualTypeInferredCorrectly.tsx]
/// <reference path="/.lib/react16.d.ts" />
import React from 'react';
interface PS {
multi: false
value: string | undefined
onChange: (selection: string | undefined) => void
}
interface PM {
multi: true
value: string[]
onChange: (selection: string[]) => void
}
export function ComponentWithUnion(props: PM | PS) {
return <h1></h1>;
}
// Usage with React tsx
export function HereIsTheError() {
return (
<ComponentWithUnion
multi={false}
value={'s'}
onChange={val => console.log(val)} // <- this throws an error
/>
);
}
// Usage with pure TypeScript
ComponentWithUnion({
multi: false,
value: 's',
onChange: val => console.log(val) // <- this works fine
});
//// [checkJsxUnionSFXContextualTypeInferredCorrectly.js]
"use strict";
/// <reference path="react16.d.ts" />
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
exports.__esModule = true;
var react_1 = __importDefault(require("react"));
function ComponentWithUnion(props) {
return react_1["default"].createElement("h1", null);
}
exports.ComponentWithUnion = ComponentWithUnion;
// Usage with React tsx
function HereIsTheError() {
return (react_1["default"].createElement(ComponentWithUnion, { multi: false, value: 's', onChange: function (val) { return console.log(val); } }));
}
exports.HereIsTheError = HereIsTheError;
// Usage with pure TypeScript
ComponentWithUnion({
multi: false,
value: 's',
onChange: function (val) { return console.log(val); } // <- this works fine
});
@@ -0,0 +1,91 @@
=== tests/cases/conformance/jsx/checkJsxUnionSFXContextualTypeInferredCorrectly.tsx ===
/// <reference path="react16.d.ts" />
import React from 'react';
>React : Symbol(React, Decl(checkJsxUnionSFXContextualTypeInferredCorrectly.tsx, 2, 6))
interface PS {
>PS : Symbol(PS, Decl(checkJsxUnionSFXContextualTypeInferredCorrectly.tsx, 2, 26))
multi: false
>multi : Symbol(PS.multi, Decl(checkJsxUnionSFXContextualTypeInferredCorrectly.tsx, 4, 14))
value: string | undefined
>value : Symbol(PS.value, Decl(checkJsxUnionSFXContextualTypeInferredCorrectly.tsx, 5, 16))
onChange: (selection: string | undefined) => void
>onChange : Symbol(PS.onChange, Decl(checkJsxUnionSFXContextualTypeInferredCorrectly.tsx, 6, 29))
>selection : Symbol(selection, Decl(checkJsxUnionSFXContextualTypeInferredCorrectly.tsx, 7, 15))
}
interface PM {
>PM : Symbol(PM, Decl(checkJsxUnionSFXContextualTypeInferredCorrectly.tsx, 8, 1))
multi: true
>multi : Symbol(PM.multi, Decl(checkJsxUnionSFXContextualTypeInferredCorrectly.tsx, 10, 14))
value: string[]
>value : Symbol(PM.value, Decl(checkJsxUnionSFXContextualTypeInferredCorrectly.tsx, 11, 15))
onChange: (selection: string[]) => void
>onChange : Symbol(PM.onChange, Decl(checkJsxUnionSFXContextualTypeInferredCorrectly.tsx, 12, 19))
>selection : Symbol(selection, Decl(checkJsxUnionSFXContextualTypeInferredCorrectly.tsx, 13, 15))
}
export function ComponentWithUnion(props: PM | PS) {
>ComponentWithUnion : Symbol(ComponentWithUnion, Decl(checkJsxUnionSFXContextualTypeInferredCorrectly.tsx, 14, 1))
>props : Symbol(props, Decl(checkJsxUnionSFXContextualTypeInferredCorrectly.tsx, 16, 35))
>PM : Symbol(PM, Decl(checkJsxUnionSFXContextualTypeInferredCorrectly.tsx, 8, 1))
>PS : Symbol(PS, Decl(checkJsxUnionSFXContextualTypeInferredCorrectly.tsx, 2, 26))
return <h1></h1>;
>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react16.d.ts, 2430, 106))
>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react16.d.ts, 2430, 106))
}
// Usage with React tsx
export function HereIsTheError() {
>HereIsTheError : Symbol(HereIsTheError, Decl(checkJsxUnionSFXContextualTypeInferredCorrectly.tsx, 18, 1))
return (
<ComponentWithUnion
>ComponentWithUnion : Symbol(ComponentWithUnion, Decl(checkJsxUnionSFXContextualTypeInferredCorrectly.tsx, 14, 1))
multi={false}
>multi : Symbol(multi, Decl(checkJsxUnionSFXContextualTypeInferredCorrectly.tsx, 23, 27))
value={'s'}
>value : Symbol(value, Decl(checkJsxUnionSFXContextualTypeInferredCorrectly.tsx, 24, 25))
onChange={val => console.log(val)} // <- this throws an error
>onChange : Symbol(onChange, Decl(checkJsxUnionSFXContextualTypeInferredCorrectly.tsx, 25, 23))
>val : Symbol(val, Decl(checkJsxUnionSFXContextualTypeInferredCorrectly.tsx, 26, 22))
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>val : Symbol(val, Decl(checkJsxUnionSFXContextualTypeInferredCorrectly.tsx, 26, 22))
/>
);
}
// Usage with pure TypeScript
ComponentWithUnion({
>ComponentWithUnion : Symbol(ComponentWithUnion, Decl(checkJsxUnionSFXContextualTypeInferredCorrectly.tsx, 14, 1))
multi: false,
>multi : Symbol(multi, Decl(checkJsxUnionSFXContextualTypeInferredCorrectly.tsx, 32, 20))
value: 's',
>value : Symbol(value, Decl(checkJsxUnionSFXContextualTypeInferredCorrectly.tsx, 33, 17))
onChange: val => console.log(val) // <- this works fine
>onChange : Symbol(onChange, Decl(checkJsxUnionSFXContextualTypeInferredCorrectly.tsx, 34, 15))
>val : Symbol(val, Decl(checkJsxUnionSFXContextualTypeInferredCorrectly.tsx, 35, 13))
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>val : Symbol(val, Decl(checkJsxUnionSFXContextualTypeInferredCorrectly.tsx, 35, 13))
});
@@ -0,0 +1,101 @@
=== tests/cases/conformance/jsx/checkJsxUnionSFXContextualTypeInferredCorrectly.tsx ===
/// <reference path="react16.d.ts" />
import React from 'react';
>React : typeof React
interface PS {
multi: false
>multi : false
>false : false
value: string | undefined
>value : string | undefined
onChange: (selection: string | undefined) => void
>onChange : (selection: string | undefined) => void
>selection : string | undefined
}
interface PM {
multi: true
>multi : true
>true : true
value: string[]
>value : string[]
onChange: (selection: string[]) => void
>onChange : (selection: string[]) => void
>selection : string[]
}
export function ComponentWithUnion(props: PM | PS) {
>ComponentWithUnion : (props: PS | PM) => JSX.Element
>props : PS | PM
return <h1></h1>;
><h1></h1> : JSX.Element
>h1 : any
>h1 : any
}
// Usage with React tsx
export function HereIsTheError() {
>HereIsTheError : () => JSX.Element
return (
>( <ComponentWithUnion multi={false} value={'s'} onChange={val => console.log(val)} // <- this throws an error /> ) : JSX.Element
<ComponentWithUnion
><ComponentWithUnion multi={false} value={'s'} onChange={val => console.log(val)} // <- this throws an error /> : JSX.Element
>ComponentWithUnion : (props: PS | PM) => JSX.Element
multi={false}
>multi : false
>false : false
value={'s'}
>value : string
>'s' : "s"
onChange={val => console.log(val)} // <- this throws an error
>onChange : (val: string | undefined) => void
>val => console.log(val) : (val: string | undefined) => void
>val : string | undefined
>console.log(val) : void
>console.log : (message?: any, ...optionalParams: any[]) => void
>console : Console
>log : (message?: any, ...optionalParams: any[]) => void
>val : string | undefined
/>
);
}
// Usage with pure TypeScript
ComponentWithUnion({
>ComponentWithUnion({ multi: false, value: 's', onChange: val => console.log(val) // <- this works fine}) : JSX.Element
>ComponentWithUnion : (props: PS | PM) => JSX.Element
>{ multi: false, value: 's', onChange: val => console.log(val) // <- this works fine} : { multi: false; value: string; onChange: (val: string | undefined) => void; }
multi: false,
>multi : false
>false : false
value: 's',
>value : string
>'s' : "s"
onChange: val => console.log(val) // <- this works fine
>onChange : (val: string | undefined) => void
>val => console.log(val) : (val: string | undefined) => void
>val : string | undefined
>console.log(val) : void
>console.log : (message?: any, ...optionalParams: any[]) => void
>console : Console
>log : (message?: any, ...optionalParams: any[]) => void
>val : string | undefined
});
@@ -0,0 +1,21 @@
=== tests/cases/conformance/salsa/file1.js ===
var SomeClass = function () {
>SomeClass : Symbol(SomeClass, Decl(file1.js, 0, 3), Decl(file2.js, 0, 0), Decl(file2.js, 0, 19))
this.otherProp = 0;
>otherProp : Symbol(SomeClass.otherProp, Decl(file1.js, 0, 29))
};
new SomeClass();
>SomeClass : Symbol(SomeClass, Decl(file1.js, 0, 3), Decl(file2.js, 0, 0), Decl(file2.js, 0, 19))
=== tests/cases/conformance/salsa/file2.js ===
class SomeClass { }
>SomeClass : Symbol(SomeClass, Decl(file1.js, 0, 3), Decl(file2.js, 0, 0), Decl(file2.js, 0, 19))
SomeClass.prop = 0
>SomeClass.prop : Symbol(SomeClass.prop, Decl(file2.js, 0, 19))
>SomeClass : Symbol(SomeClass, Decl(file1.js, 0, 3), Decl(file2.js, 0, 0), Decl(file2.js, 0, 19))
>prop : Symbol(SomeClass.prop, Decl(file2.js, 0, 19))
@@ -0,0 +1,29 @@
=== tests/cases/conformance/salsa/file1.js ===
var SomeClass = function () {
>SomeClass : typeof SomeClass
>function () { this.otherProp = 0;} : typeof SomeClass
this.otherProp = 0;
>this.otherProp = 0 : 0
>this.otherProp : any
>this : any
>otherProp : any
>0 : 0
};
new SomeClass();
>new SomeClass() : SomeClass
>SomeClass : typeof SomeClass
=== tests/cases/conformance/salsa/file2.js ===
class SomeClass { }
>SomeClass : SomeClass
SomeClass.prop = 0
>SomeClass.prop = 0 : 0
>SomeClass.prop : number
>SomeClass : typeof SomeClass
>prop : number
>0 : 0
@@ -0,0 +1,19 @@
=== tests/cases/conformance/jsdoc/bug27025.js ===
export class Alpha { }
>Alpha : Symbol(Alpha, Decl(bug27025.js, 0, 0))
export class Beta {
>Beta : Symbol(Beta, Decl(bug27025.js, 0, 22))
/**
* @constructor
*/
constructor() {
}
}
const arr = [Alpha, Beta];
>arr : Symbol(arr, Decl(bug27025.js, 9, 5))
>Alpha : Symbol(Alpha, Decl(bug27025.js, 0, 0))
>Beta : Symbol(Beta, Decl(bug27025.js, 0, 22))
@@ -0,0 +1,20 @@
=== tests/cases/conformance/jsdoc/bug27025.js ===
export class Alpha { }
>Alpha : Alpha
export class Beta {
>Beta : Beta
/**
* @constructor
*/
constructor() {
}
}
const arr = [Alpha, Beta];
>arr : (typeof Alpha)[]
>[Alpha, Beta] : (typeof Alpha)[]
>Alpha : typeof Alpha
>Beta : typeof Beta
@@ -0,0 +1,21 @@
//// [controlFlowElementAccess.ts]
let x: { o: boolean } = { o: false }
if (x['o'] === false) {
x['o'] = true
}
const y: [number, number] = [0, 0];
if (y[0] === 0) {
y[0] = -1;
}
//// [controlFlowElementAccess.js]
var x = { o: false };
if (x['o'] === false) {
x['o'] = true;
}
var y = [0, 0];
if (y[0] === 0) {
y[0] = -1;
}
@@ -0,0 +1,27 @@
=== tests/cases/conformance/controlFlow/controlFlowElementAccess.ts ===
let x: { o: boolean } = { o: false }
>x : Symbol(x, Decl(controlFlowElementAccess.ts, 0, 3))
>o : Symbol(o, Decl(controlFlowElementAccess.ts, 0, 8))
>o : Symbol(o, Decl(controlFlowElementAccess.ts, 0, 25))
if (x['o'] === false) {
>x : Symbol(x, Decl(controlFlowElementAccess.ts, 0, 3))
>'o' : Symbol(o, Decl(controlFlowElementAccess.ts, 0, 8))
x['o'] = true
>x : Symbol(x, Decl(controlFlowElementAccess.ts, 0, 3))
>'o' : Symbol(o, Decl(controlFlowElementAccess.ts, 0, 8))
}
const y: [number, number] = [0, 0];
>y : Symbol(y, Decl(controlFlowElementAccess.ts, 5, 5))
if (y[0] === 0) {
>y : Symbol(y, Decl(controlFlowElementAccess.ts, 5, 5))
>0 : Symbol(0)
y[0] = -1;
>y : Symbol(y, Decl(controlFlowElementAccess.ts, 5, 5))
>0 : Symbol(0)
}
@@ -0,0 +1,45 @@
=== tests/cases/conformance/controlFlow/controlFlowElementAccess.ts ===
let x: { o: boolean } = { o: false }
>x : { o: boolean; }
>o : boolean
>{ o: false } : { o: false; }
>o : false
>false : false
if (x['o'] === false) {
>x['o'] === false : boolean
>x['o'] : boolean
>x : { o: boolean; }
>'o' : "o"
>false : false
x['o'] = true
>x['o'] = true : true
>x['o'] : boolean
>x : { o: boolean; }
>'o' : "o"
>true : true
}
const y: [number, number] = [0, 0];
>y : [number, number]
>[0, 0] : [number, number]
>0 : 0
>0 : 0
if (y[0] === 0) {
>y[0] === 0 : boolean
>y[0] : number
>y : [number, number]
>0 : 0
>0 : 0
y[0] = -1;
>y[0] = -1 : -1
>y[0] : number
>y : [number, number]
>0 : 0
>-1 : -1
>1 : 1
}
@@ -8,5 +8,5 @@ function /*[#|*/f/*|]*/() {
async function f() {
const s = await fetch('https://typescriptlang.org');
return Promise.resolve(s.statusText.length);
return await Promise.resolve(s.statusText.length);
}
@@ -8,5 +8,5 @@ function /*[#|*/f/*|]*/() {
async function f() {
const s = await fetch('https://typescriptlang.org');
return Promise.resolve(s.statusText.length);
return await Promise.resolve(s.statusText.length);
}
@@ -0,0 +1,19 @@
// ==ORIGINAL==
function /*[#|*/f/*|]*/() {
return Promise.resolve(1)
.then(x => Promise.reject(x))
.catch(err => console.log(err));
}
// ==ASYNC FUNCTION::Convert to async function==
async function f() {
try {
const x = await Promise.resolve(1);
return await Promise.reject(x);
}
catch (err) {
return console.log(err);
}
}
@@ -0,0 +1,19 @@
// ==ORIGINAL==
function /*[#|*/f/*|]*/() {
return Promise.resolve(1)
.then(x => Promise.reject(x))
.catch(err => console.log(err));
}
// ==ASYNC FUNCTION::Convert to async function==
async function f() {
try {
const x = await Promise.resolve(1);
return await Promise.reject(x);
}
catch (err) {
return console.log(err);
}
}
@@ -9,5 +9,5 @@ function /*[#|*/f/*|]*/() {
async function f() {
const x = await fetch('https://typescriptlang.org');
const y = await Promise.resolve(3);
return Promise.resolve(x.statusText.length + y);
return await Promise.resolve(x.statusText.length + y);
}
@@ -9,5 +9,5 @@ function /*[#|*/f/*|]*/() {
async function f() {
const x = await fetch('https://typescriptlang.org');
const y = await Promise.resolve(3);
return Promise.resolve(x.statusText.length + y);
return await Promise.resolve(x.statusText.length + y);
}
@@ -4,7 +4,7 @@ class List<T> { }
>T : Symbol(T, Decl(declFileImportedTypeUseInTypeArgPosition.ts, 0, 11))
declare module 'mod1' {
>'mod1' : Symbol('mod1', Decl(declFileImportedTypeUseInTypeArgPosition.ts, 0, 17))
>'mod1' : Symbol("mod1", Decl(declFileImportedTypeUseInTypeArgPosition.ts, 0, 17))
class Foo {
>Foo : Symbol(Foo, Decl(declFileImportedTypeUseInTypeArgPosition.ts, 1, 23))
@@ -12,7 +12,7 @@ declare module 'mod1' {
}
declare module 'moo' {
>'moo' : Symbol('moo', Decl(declFileImportedTypeUseInTypeArgPosition.ts, 4, 1))
>'moo' : Symbol("moo", Decl(declFileImportedTypeUseInTypeArgPosition.ts, 4, 1))
import x = require('mod1');
>x : Symbol(x, Decl(declFileImportedTypeUseInTypeArgPosition.ts, 6, 22))
@@ -1,6 +1,6 @@
=== tests/cases/compiler/types/component.d.ts ===
declare module '@namespace/component' {
>'@namespace/component' : Symbol('@namespace/component', Decl(component.d.ts, 0, 0))
>'@namespace/component' : Symbol("@namespace/component", Decl(component.d.ts, 0, 0))
export class Foo {}
>Foo : Symbol(Foo, Decl(component.d.ts, 0, 39))
@@ -0,0 +1,29 @@
//// [declarationEmitNoNonRequiredParens.ts]
export enum Test {
A, B, C
}
export type TestType = typeof Test;
export const bar = (null as TestType[Extract<keyof TestType, string>][]);
//// [declarationEmitNoNonRequiredParens.js]
"use strict";
exports.__esModule = true;
var Test;
(function (Test) {
Test[Test["A"] = 0] = "A";
Test[Test["B"] = 1] = "B";
Test[Test["C"] = 2] = "C";
})(Test = exports.Test || (exports.Test = {}));
exports.bar = null;
//// [declarationEmitNoNonRequiredParens.d.ts]
export declare enum Test {
A = 0,
B = 1,
C = 2
}
export declare type TestType = typeof Test;
export declare const bar: Test[];
@@ -0,0 +1,20 @@
=== tests/cases/compiler/declarationEmitNoNonRequiredParens.ts ===
export enum Test {
>Test : Symbol(Test, Decl(declarationEmitNoNonRequiredParens.ts, 0, 0))
A, B, C
>A : Symbol(Test.A, Decl(declarationEmitNoNonRequiredParens.ts, 0, 18))
>B : Symbol(Test.B, Decl(declarationEmitNoNonRequiredParens.ts, 1, 6))
>C : Symbol(Test.C, Decl(declarationEmitNoNonRequiredParens.ts, 1, 9))
}
export type TestType = typeof Test;
>TestType : Symbol(TestType, Decl(declarationEmitNoNonRequiredParens.ts, 2, 1))
>Test : Symbol(Test, Decl(declarationEmitNoNonRequiredParens.ts, 0, 0))
export const bar = (null as TestType[Extract<keyof TestType, string>][]);
>bar : Symbol(bar, Decl(declarationEmitNoNonRequiredParens.ts, 6, 12))
>TestType : Symbol(TestType, Decl(declarationEmitNoNonRequiredParens.ts, 2, 1))
>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --))
>TestType : Symbol(TestType, Decl(declarationEmitNoNonRequiredParens.ts, 2, 1))
@@ -0,0 +1,20 @@
=== tests/cases/compiler/declarationEmitNoNonRequiredParens.ts ===
export enum Test {
>Test : Test
A, B, C
>A : Test.A
>B : Test.B
>C : Test.C
}
export type TestType = typeof Test;
>TestType : typeof Test
>Test : typeof Test
export const bar = (null as TestType[Extract<keyof TestType, string>][]);
>bar : Test[]
>(null as TestType[Extract<keyof TestType, string>][]) : Test[]
>null as TestType[Extract<keyof TestType, string>][] : Test[]
>null : null
@@ -1,6 +1,6 @@
=== tests/cases/compiler/declaredExternalModule.ts ===
declare module 'connect' {
>'connect' : Symbol('connect', Decl(declaredExternalModule.ts, 0, 0))
>'connect' : Symbol("connect", Decl(declaredExternalModule.ts, 0, 0))
interface connectModule {
>connectModule : Symbol(connectModule, Decl(declaredExternalModule.ts, 0, 26))
@@ -1,6 +1,6 @@
=== tests/cases/compiler/declaredExternalModuleWithExportAssignment.ts ===
declare module 'connect' {
>'connect' : Symbol('connect', Decl(declaredExternalModuleWithExportAssignment.ts, 0, 0))
>'connect' : Symbol("connect", Decl(declaredExternalModuleWithExportAssignment.ts, 0, 0))
interface connectModule {
>connectModule : Symbol(connectModule, Decl(declaredExternalModuleWithExportAssignment.ts, 0, 26))
@@ -73,4 +73,37 @@ tests/cases/compiler/discriminantPropertyCheck.ts(65,9): error TS2532: Object is
~~~~~
!!! error TS2532: Object is possibly 'undefined'.
}
}
}
// Repro from #27493
enum Types { Str = 1, Num = 2 }
type Instance = StrType | NumType;
interface StrType {
type: Types.Str;
value: string;
length: number;
}
interface NumType {
type: Types.Num;
value: number;
}
function func2(inst: Instance) {
while (true) {
switch (inst.type) {
case Types.Str: {
inst.value.length;
break;
}
case Types.Num: {
inst.value.toExponential;
break;
}
}
}
}
@@ -65,7 +65,40 @@ function foo6(x: Item) {
if (x.foo !== undefined && x.qux) {
x.foo.length; // Error, intervening discriminant guard
}
}
}
// Repro from #27493
enum Types { Str = 1, Num = 2 }
type Instance = StrType | NumType;
interface StrType {
type: Types.Str;
value: string;
length: number;
}
interface NumType {
type: Types.Num;
value: number;
}
function func2(inst: Instance) {
while (true) {
switch (inst.type) {
case Types.Str: {
inst.value.length;
break;
}
case Types.Num: {
inst.value.toExponential;
break;
}
}
}
}
//// [discriminantPropertyCheck.js]
function goo1(x) {
@@ -108,3 +141,23 @@ function foo6(x) {
x.foo.length; // Error, intervening discriminant guard
}
}
// Repro from #27493
var Types;
(function (Types) {
Types[Types["Str"] = 1] = "Str";
Types[Types["Num"] = 2] = "Num";
})(Types || (Types = {}));
function func2(inst) {
while (true) {
switch (inst.type) {
case Types.Str: {
inst.value.length;
break;
}
case Types.Num: {
inst.value.toExponential;
break;
}
}
}
}
@@ -228,3 +228,86 @@ function foo6(x: Item) {
>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
}
}
// Repro from #27493
enum Types { Str = 1, Num = 2 }
>Types : Symbol(Types, Decl(discriminantPropertyCheck.ts, 66, 1))
>Str : Symbol(Types.Str, Decl(discriminantPropertyCheck.ts, 70, 12))
>Num : Symbol(Types.Num, Decl(discriminantPropertyCheck.ts, 70, 21))
type Instance = StrType | NumType;
>Instance : Symbol(Instance, Decl(discriminantPropertyCheck.ts, 70, 31))
>StrType : Symbol(StrType, Decl(discriminantPropertyCheck.ts, 72, 34))
>NumType : Symbol(NumType, Decl(discriminantPropertyCheck.ts, 78, 1))
interface StrType {
>StrType : Symbol(StrType, Decl(discriminantPropertyCheck.ts, 72, 34))
type: Types.Str;
>type : Symbol(StrType.type, Decl(discriminantPropertyCheck.ts, 74, 19))
>Types : Symbol(Types, Decl(discriminantPropertyCheck.ts, 66, 1))
>Str : Symbol(Types.Str, Decl(discriminantPropertyCheck.ts, 70, 12))
value: string;
>value : Symbol(StrType.value, Decl(discriminantPropertyCheck.ts, 75, 20))
length: number;
>length : Symbol(StrType.length, Decl(discriminantPropertyCheck.ts, 76, 18))
}
interface NumType {
>NumType : Symbol(NumType, Decl(discriminantPropertyCheck.ts, 78, 1))
type: Types.Num;
>type : Symbol(NumType.type, Decl(discriminantPropertyCheck.ts, 80, 19))
>Types : Symbol(Types, Decl(discriminantPropertyCheck.ts, 66, 1))
>Num : Symbol(Types.Num, Decl(discriminantPropertyCheck.ts, 70, 21))
value: number;
>value : Symbol(NumType.value, Decl(discriminantPropertyCheck.ts, 81, 20))
}
function func2(inst: Instance) {
>func2 : Symbol(func2, Decl(discriminantPropertyCheck.ts, 83, 1))
>inst : Symbol(inst, Decl(discriminantPropertyCheck.ts, 85, 15))
>Instance : Symbol(Instance, Decl(discriminantPropertyCheck.ts, 70, 31))
while (true) {
switch (inst.type) {
>inst.type : Symbol(type, Decl(discriminantPropertyCheck.ts, 74, 19), Decl(discriminantPropertyCheck.ts, 80, 19))
>inst : Symbol(inst, Decl(discriminantPropertyCheck.ts, 85, 15))
>type : Symbol(type, Decl(discriminantPropertyCheck.ts, 74, 19), Decl(discriminantPropertyCheck.ts, 80, 19))
case Types.Str: {
>Types.Str : Symbol(Types.Str, Decl(discriminantPropertyCheck.ts, 70, 12))
>Types : Symbol(Types, Decl(discriminantPropertyCheck.ts, 66, 1))
>Str : Symbol(Types.Str, Decl(discriminantPropertyCheck.ts, 70, 12))
inst.value.length;
>inst.value.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
>inst.value : Symbol(StrType.value, Decl(discriminantPropertyCheck.ts, 75, 20))
>inst : Symbol(inst, Decl(discriminantPropertyCheck.ts, 85, 15))
>value : Symbol(StrType.value, Decl(discriminantPropertyCheck.ts, 75, 20))
>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
break;
}
case Types.Num: {
>Types.Num : Symbol(Types.Num, Decl(discriminantPropertyCheck.ts, 70, 21))
>Types : Symbol(Types, Decl(discriminantPropertyCheck.ts, 66, 1))
>Num : Symbol(Types.Num, Decl(discriminantPropertyCheck.ts, 70, 21))
inst.value.toExponential;
>inst.value.toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
>inst.value : Symbol(NumType.value, Decl(discriminantPropertyCheck.ts, 81, 20))
>inst : Symbol(inst, Decl(discriminantPropertyCheck.ts, 85, 15))
>value : Symbol(NumType.value, Decl(discriminantPropertyCheck.ts, 81, 20))
>toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
break;
}
}
}
}
@@ -232,3 +232,81 @@ function foo6(x: Item) {
>length : number
}
}
// Repro from #27493
enum Types { Str = 1, Num = 2 }
>Types : Types
>Str : Types.Str
>1 : 1
>Num : Types.Num
>2 : 2
type Instance = StrType | NumType;
>Instance : Instance
interface StrType {
type: Types.Str;
>type : Types.Str
>Types : any
value: string;
>value : string
length: number;
>length : number
}
interface NumType {
type: Types.Num;
>type : Types.Num
>Types : any
value: number;
>value : number
}
function func2(inst: Instance) {
>func2 : (inst: Instance) => void
>inst : Instance
while (true) {
>true : true
switch (inst.type) {
>inst.type : Types
>inst : Instance
>type : Types
case Types.Str: {
>Types.Str : Types.Str
>Types : typeof Types
>Str : Types.Str
inst.value.length;
>inst.value.length : number
>inst.value : string
>inst : StrType
>value : string
>length : number
break;
}
case Types.Num: {
>Types.Num : Types.Num
>Types : typeof Types
>Num : Types.Num
inst.value.toExponential;
>inst.value.toExponential : (fractionDigits?: number | undefined) => string
>inst.value : number
>inst : NumType
>value : number
>toExponential : (fractionDigits?: number | undefined) => string
break;
}
}
}
}
@@ -263,9 +263,11 @@ class B9 {
}
class C9 extends B9 {
f() {
const _super = name => super[name];
const _super = Object.create(null, {
g: { get: () => super.g }
});
return __asyncGenerator(this, arguments, function* f_1() {
_super("g").call(this);
_super.g.call(this);
});
}
}
@@ -1,9 +1,9 @@
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(3,27): error TS2305: Module '"tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'.
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(5,27): error TS2305: Module '"tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'.
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(7,27): error TS2305: Module '"tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'x'.
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(7,30): error TS2305: Module '"tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'.
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(9,27): error TS2305: Module '"tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'x'.
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(11,27): error TS2305: Module '"tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'm'.
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(3,27): error TS2305: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'.
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(5,27): error TS2305: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'.
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(7,27): error TS2305: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'x'.
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(7,30): error TS2305: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'.
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(9,27): error TS2305: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'x'.
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(11,27): error TS2305: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'm'.
==== tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_0.ts (0 errors) ====
@@ -15,24 +15,24 @@ tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(11,27)
var x1: number = defaultBinding1;
import defaultBinding2, { a } from "es6ImportDefaultBindingFollowedWithNamedImport1_0";
~
!!! error TS2305: Module '"tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'.
!!! error TS2305: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'.
var x1: number = defaultBinding2;
import defaultBinding3, { a as b } from "es6ImportDefaultBindingFollowedWithNamedImport1_0";
~
!!! error TS2305: Module '"tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'.
!!! error TS2305: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'.
var x1: number = defaultBinding3;
import defaultBinding4, { x, a as y } from "es6ImportDefaultBindingFollowedWithNamedImport1_0";
~
!!! error TS2305: Module '"tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'x'.
!!! error TS2305: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'x'.
~
!!! error TS2305: Module '"tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'.
!!! error TS2305: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'.
var x1: number = defaultBinding4;
import defaultBinding5, { x as z, } from "es6ImportDefaultBindingFollowedWithNamedImport1_0";
~
!!! error TS2305: Module '"tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'x'.
!!! error TS2305: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'x'.
var x1: number = defaultBinding5;
import defaultBinding6, { m, } from "es6ImportDefaultBindingFollowedWithNamedImport1_0";
~
!!! error TS2305: Module '"tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'm'.
!!! error TS2305: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'm'.
var x1: number = defaultBinding6;
@@ -1,9 +1,9 @@
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1InEs5_1.ts(3,27): error TS2305: Module '"tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0"' has no exported member 'a'.
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1InEs5_1.ts(5,27): error TS2305: Module '"tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0"' has no exported member 'a'.
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1InEs5_1.ts(7,27): error TS2305: Module '"tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0"' has no exported member 'x'.
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1InEs5_1.ts(7,30): error TS2305: Module '"tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0"' has no exported member 'a'.
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1InEs5_1.ts(9,27): error TS2305: Module '"tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0"' has no exported member 'x'.
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1InEs5_1.ts(11,27): error TS2305: Module '"tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0"' has no exported member 'm'.
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1InEs5_1.ts(3,27): error TS2305: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0"' has no exported member 'a'.
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1InEs5_1.ts(5,27): error TS2305: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0"' has no exported member 'a'.
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1InEs5_1.ts(7,27): error TS2305: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0"' has no exported member 'x'.
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1InEs5_1.ts(7,30): error TS2305: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0"' has no exported member 'a'.
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1InEs5_1.ts(9,27): error TS2305: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0"' has no exported member 'x'.
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1InEs5_1.ts(11,27): error TS2305: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0"' has no exported member 'm'.
==== tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0.ts (0 errors) ====
@@ -15,24 +15,24 @@ tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1InEs5_1.ts(1
var x: number = defaultBinding1;
import defaultBinding2, { a } from "./es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0";
~
!!! error TS2305: Module '"tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0"' has no exported member 'a'.
!!! error TS2305: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0"' has no exported member 'a'.
var x: number = defaultBinding2;
import defaultBinding3, { a as b } from "./es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0";
~
!!! error TS2305: Module '"tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0"' has no exported member 'a'.
!!! error TS2305: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0"' has no exported member 'a'.
var x: number = defaultBinding3;
import defaultBinding4, { x, a as y } from "./es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0";
~
!!! error TS2305: Module '"tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0"' has no exported member 'x'.
!!! error TS2305: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0"' has no exported member 'x'.
~
!!! error TS2305: Module '"tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0"' has no exported member 'a'.
!!! error TS2305: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0"' has no exported member 'a'.
var x: number = defaultBinding4;
import defaultBinding5, { x as z, } from "./es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0";
~
!!! error TS2305: Module '"tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0"' has no exported member 'x'.
!!! error TS2305: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0"' has no exported member 'x'.
var x: number = defaultBinding5;
import defaultBinding6, { m, } from "./es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0";
~
!!! error TS2305: Module '"tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0"' has no exported member 'm'.
!!! error TS2305: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0"' has no exported member 'm'.
var x: number = defaultBinding6;
@@ -1,20 +1,20 @@
tests/cases/compiler/client.ts(1,1): error TS1191: An import declaration cannot have modifiers.
tests/cases/compiler/client.ts(2,12): error TS2323: Cannot redeclare exported variable 'x1'.
tests/cases/compiler/client.ts(3,1): error TS1191: An import declaration cannot have modifiers.
tests/cases/compiler/client.ts(3,34): error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'a'.
tests/cases/compiler/client.ts(3,34): error TS2305: Module '"./server"' has no exported member 'a'.
tests/cases/compiler/client.ts(4,12): error TS2323: Cannot redeclare exported variable 'x1'.
tests/cases/compiler/client.ts(5,1): error TS1191: An import declaration cannot have modifiers.
tests/cases/compiler/client.ts(5,34): error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'a'.
tests/cases/compiler/client.ts(5,34): error TS2305: Module '"./server"' has no exported member 'a'.
tests/cases/compiler/client.ts(6,12): error TS2323: Cannot redeclare exported variable 'x1'.
tests/cases/compiler/client.ts(7,1): error TS1191: An import declaration cannot have modifiers.
tests/cases/compiler/client.ts(7,34): error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'x'.
tests/cases/compiler/client.ts(7,37): error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'a'.
tests/cases/compiler/client.ts(7,34): error TS2305: Module '"./server"' has no exported member 'x'.
tests/cases/compiler/client.ts(7,37): error TS2305: Module '"./server"' has no exported member 'a'.
tests/cases/compiler/client.ts(8,12): error TS2323: Cannot redeclare exported variable 'x1'.
tests/cases/compiler/client.ts(9,1): error TS1191: An import declaration cannot have modifiers.
tests/cases/compiler/client.ts(9,34): error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'x'.
tests/cases/compiler/client.ts(9,34): error TS2305: Module '"./server"' has no exported member 'x'.
tests/cases/compiler/client.ts(10,12): error TS2323: Cannot redeclare exported variable 'x1'.
tests/cases/compiler/client.ts(11,1): error TS1191: An import declaration cannot have modifiers.
tests/cases/compiler/client.ts(11,34): error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'm'.
tests/cases/compiler/client.ts(11,34): error TS2305: Module '"./server"' has no exported member 'm'.
tests/cases/compiler/client.ts(12,12): error TS2323: Cannot redeclare exported variable 'x1'.
@@ -33,7 +33,7 @@ tests/cases/compiler/client.ts(12,12): error TS2323: Cannot redeclare exported v
~~~~~~
!!! error TS1191: An import declaration cannot have modifiers.
~
!!! error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'a'.
!!! error TS2305: Module '"./server"' has no exported member 'a'.
export var x1: number = defaultBinding2;
~~
!!! error TS2323: Cannot redeclare exported variable 'x1'.
@@ -41,7 +41,7 @@ tests/cases/compiler/client.ts(12,12): error TS2323: Cannot redeclare exported v
~~~~~~
!!! error TS1191: An import declaration cannot have modifiers.
~
!!! error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'a'.
!!! error TS2305: Module '"./server"' has no exported member 'a'.
export var x1: number = defaultBinding3;
~~
!!! error TS2323: Cannot redeclare exported variable 'x1'.
@@ -49,9 +49,9 @@ tests/cases/compiler/client.ts(12,12): error TS2323: Cannot redeclare exported v
~~~~~~
!!! error TS1191: An import declaration cannot have modifiers.
~
!!! error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'x'.
!!! error TS2305: Module '"./server"' has no exported member 'x'.
~
!!! error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'a'.
!!! error TS2305: Module '"./server"' has no exported member 'a'.
export var x1: number = defaultBinding4;
~~
!!! error TS2323: Cannot redeclare exported variable 'x1'.
@@ -59,7 +59,7 @@ tests/cases/compiler/client.ts(12,12): error TS2323: Cannot redeclare exported v
~~~~~~
!!! error TS1191: An import declaration cannot have modifiers.
~
!!! error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'x'.
!!! error TS2305: Module '"./server"' has no exported member 'x'.
export var x1: number = defaultBinding5;
~~
!!! error TS2323: Cannot redeclare exported variable 'x1'.
@@ -67,7 +67,7 @@ tests/cases/compiler/client.ts(12,12): error TS2323: Cannot redeclare exported v
~~~~~~
!!! error TS1191: An import declaration cannot have modifiers.
~
!!! error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'm'.
!!! error TS2305: Module '"./server"' has no exported member 'm'.
export var x1: number = defaultBinding6;
~~
!!! error TS2323: Cannot redeclare exported variable 'x1'.
@@ -1,9 +1,9 @@
tests/cases/compiler/client.ts(3,27): error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'a'.
tests/cases/compiler/client.ts(5,27): error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'a'.
tests/cases/compiler/client.ts(7,27): error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'x'.
tests/cases/compiler/client.ts(7,30): error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'a'.
tests/cases/compiler/client.ts(9,27): error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'x'.
tests/cases/compiler/client.ts(11,27): error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'm'.
tests/cases/compiler/client.ts(3,27): error TS2305: Module '"./server"' has no exported member 'a'.
tests/cases/compiler/client.ts(5,27): error TS2305: Module '"./server"' has no exported member 'a'.
tests/cases/compiler/client.ts(7,27): error TS2305: Module '"./server"' has no exported member 'x'.
tests/cases/compiler/client.ts(7,30): error TS2305: Module '"./server"' has no exported member 'a'.
tests/cases/compiler/client.ts(9,27): error TS2305: Module '"./server"' has no exported member 'x'.
tests/cases/compiler/client.ts(11,27): error TS2305: Module '"./server"' has no exported member 'm'.
==== tests/cases/compiler/server.ts (0 errors) ====
@@ -15,23 +15,23 @@ tests/cases/compiler/client.ts(11,27): error TS2305: Module '"tests/cases/compil
export var x1 = new defaultBinding1();
import defaultBinding2, { a } from "./server";
~
!!! error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'a'.
!!! error TS2305: Module '"./server"' has no exported member 'a'.
export var x2 = new defaultBinding2();
import defaultBinding3, { a as b } from "./server";
~
!!! error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'a'.
!!! error TS2305: Module '"./server"' has no exported member 'a'.
export var x3 = new defaultBinding3();
import defaultBinding4, { x, a as y } from "./server";
~
!!! error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'x'.
!!! error TS2305: Module '"./server"' has no exported member 'x'.
~
!!! error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'a'.
!!! error TS2305: Module '"./server"' has no exported member 'a'.
export var x4 = new defaultBinding4();
import defaultBinding5, { x as z, } from "./server";
~
!!! error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'x'.
!!! error TS2305: Module '"./server"' has no exported member 'x'.
export var x5 = new defaultBinding5();
import defaultBinding6, { m, } from "./server";
~
!!! error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'm'.
!!! error TS2305: Module '"./server"' has no exported member 'm'.
export var x6 = new defaultBinding6();
Loaded 100 of 196 files, more files were not shown because too many files have changed in this diff. Show more