Merge branch 'master' of https://github.com/Microsoft/TypeScript into feature/eslint

This commit is contained in:
Alexander T
2019-08-22 09:46:22 +03:00
29 changed files with 308 additions and 125 deletions
+16 -11
View File
@@ -22875,24 +22875,29 @@ namespace ts {
// If the symbol of the node has members, treat it like a constructor.
const symbol = getSymbolOfNode(func);
return !!symbol && symbol.members !== undefined;
return !!symbol && hasEntries(symbol.members);
}
return false;
}
function mergeJSSymbols(target: Symbol, source: Symbol | undefined) {
if (source && (hasEntries(source.exports) || hasEntries(source.members))) {
target = cloneSymbol(target);
if (hasEntries(source.exports)) {
target.exports = target.exports || createSymbolTable();
mergeSymbolTable(target.exports, source.exports);
const links = getSymbolLinks(source);
if (!links.inferredClassSymbol || !links.inferredClassSymbol.has("" + getSymbolId(target))) {
const inferred = isTransientSymbol(target) ? target : cloneSymbol(target) as TransientSymbol;
inferred.exports = inferred.exports || createSymbolTable();
inferred.members = inferred.members || createSymbolTable();
inferred.flags |= source.flags & SymbolFlags.Class;
if (hasEntries(source.exports)) {
mergeSymbolTable(inferred.exports, source.exports);
}
if (hasEntries(source.members)) {
mergeSymbolTable(inferred.members, source.members);
}
(links.inferredClassSymbol || (links.inferredClassSymbol = createMap<TransientSymbol>())).set("" + getSymbolId(inferred), inferred);
return inferred;
}
if (hasEntries(source.members)) {
target.members = target.members || createSymbolTable();
mergeSymbolTable(target.members, source.members);
}
target.flags |= source.flags & SymbolFlags.Class;
return target as TransientSymbol;
return links.inferredClassSymbol.get("" + getSymbolId(target));
}
}
+24 -23
View File
@@ -3792,30 +3792,31 @@ namespace ts {
/* @internal */
export interface SymbolLinks {
immediateTarget?: Symbol; // Immediate target of an alias. May be another alias. Do not access directly, use `checker.getImmediateAliasedSymbol` instead.
target?: Symbol; // Resolved (non-alias) target of an alias
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
instantiations?: Map<Type>; // Instantiations of generic type alias (undefined if non-generic)
mapper?: TypeMapper; // Type mapper for instantiation alias
referenced?: boolean; // True if alias symbol has been referenced as a value
containingType?: UnionOrIntersectionType; // Containing union or intersection type for synthetic property
leftSpread?: Symbol; // Left source for synthetic spread property
rightSpread?: Symbol; // Right source for synthetic spread property
syntheticOrigin?: Symbol; // For a property on a mapped or spread type, points back to the original property
isDiscriminantProperty?: boolean; // True if discriminant synthetic property
resolvedExports?: SymbolTable; // Resolved exports of module or combined early- and late-bound static members of a class.
resolvedMembers?: SymbolTable; // Combined early- and late-bound members of a symbol
exportsChecked?: boolean; // True if exports of external module have been checked
typeParametersChecked?: boolean; // True if type parameters of merged class and interface declarations have been checked.
immediateTarget?: Symbol; // Immediate target of an alias. May be another alias. Do not access directly, use `checker.getImmediateAliasedSymbol` instead.
target?: Symbol; // Resolved (non-alias) target of an alias
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
instantiations?: Map<Type>; // Instantiations of generic type alias (undefined if non-generic)
inferredClassSymbol?: Map<TransientSymbol>; // Symbol of an inferred ES5 constructor function
mapper?: TypeMapper; // Type mapper for instantiation alias
referenced?: boolean; // True if alias symbol has been referenced as a value
containingType?: UnionOrIntersectionType; // Containing union or intersection type for synthetic property
leftSpread?: Symbol; // Left source for synthetic spread property
rightSpread?: Symbol; // Right source for synthetic spread property
syntheticOrigin?: Symbol; // For a property on a mapped or spread type, points back to the original property
isDiscriminantProperty?: boolean; // True if discriminant synthetic property
resolvedExports?: SymbolTable; // Resolved exports of module or combined early- and late-bound static members of a class.
resolvedMembers?: SymbolTable; // Combined early- and late-bound members of a symbol
exportsChecked?: boolean; // True if exports of external module have been checked
typeParametersChecked?: boolean; // True if type parameters of merged class and interface declarations have been checked.
isDeclarationWithCollidingName?: boolean; // True if symbol is block scoped redeclaration
bindingElement?: BindingElement; // Binding element associated with property symbol
exportsSomeValue?: boolean; // True if module exports some value (not just types)
enumKind?: EnumKind; // Enum declaration classification
bindingElement?: BindingElement; // Binding element associated with property symbol
exportsSomeValue?: boolean; // True if module exports some value (not just types)
enumKind?: EnumKind; // Enum declaration classification
originatingImport?: ImportDeclaration | ImportCall; // Import declaration which produced the symbol, present if the symbol is marked as uncallable but had call signatures in `resolveESModuleSymbol`
lateSymbol?: Symbol; // Late-bound symbol for a computed property
specifierCache?: Map<string>; // For symbols corresponding to external modules, a cache of incoming path -> module specifier name mappings
@@ -2577,7 +2577,7 @@
<Str Cat="Text">
<Val><![CDATA[Conflicting definitions for '{0}' found at '{1}' and '{2}'. Consider installing a specific version of this library to resolve the conflict.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Znaleziono sprzeczne definicje dla „{0}” w „{1}” i „{2}”. Rozważ zainstalowanie konkretnej wersji tej biblioteki, aby rozwiązać problem.]]></Val>
<Val><![CDATA[Znaleziono definicje będące w konflikcie dla „{0}” w „{1}” i „{2}”. Rozważ zainstalowanie konkretnej wersji tej biblioteki, aby rozwiązać problem.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@@ -14,7 +14,7 @@ namespace ts.codefix {
function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number) {
const token = getTokenAtPosition(sourceFile, pos);
const assertion = Debug.assertDefined(findAncestor(token, (n): n is AsExpression | TypeAssertion => isAsExpression(n) || isTypeAssertion(n)));
const assertion = Debug.assertDefined(findAncestor(token, (n): n is AsExpression | TypeAssertion => isAsExpression(n) || isTypeAssertion(n)), "Expected to find an assertion expression");
const replacement = isAsExpression(assertion)
? createAsExpression(assertion.expression, createKeywordTypeNode(SyntaxKind.UnknownKeyword))
: createTypeAssertion(createKeywordTypeNode(SyntaxKind.UnknownKeyword), assertion.expression);
@@ -60,8 +60,8 @@ namespace ts.codefix {
}
}
else {
const jsdocType = Debug.assertDefined(getJSDocType(decl)); // If not defined, shouldn't have been an error to fix
Debug.assert(!decl.type); // If defined, shouldn't have been an error to fix.
const jsdocType = Debug.assertDefined(getJSDocType(decl), "A JSDocType for this declaration should exist"); // If not defined, shouldn't have been an error to fix
Debug.assert(!decl.type, "The JSDocType decl should have a type"); // If defined, shouldn't have been an error to fix.
changes.tryInsertTypeAnnotation(sourceFile, decl, transformJSDocType(jsdocType));
}
}
+4 -4
View File
@@ -178,7 +178,7 @@ namespace ts.codefix {
// `const a = require("b").c` --> `import { c as a } from "./b";
return [makeSingleImport(name.text, propertyName, moduleSpecifier, quotePreference)];
default:
return Debug.assertNever(name);
return Debug.assertNever(name, `Convert to ES6 module got invalid syntax form ${(name as BindingName).kind}`);
}
}
@@ -239,7 +239,7 @@ namespace ts.codefix {
case SyntaxKind.MethodDeclaration:
return !isIdentifier(prop.name) ? undefined : functionExpressionToDeclaration(prop.name.text, [createToken(SyntaxKind.ExportKeyword)], prop);
default:
Debug.assertNever(prop);
Debug.assertNever(prop, `Convert to ES6 got invalid prop kind ${(prop as ObjectLiteralElementLike).kind}`);
}
});
return statements && [statements, false];
@@ -377,7 +377,7 @@ namespace ts.codefix {
case SyntaxKind.Identifier:
return convertSingleIdentifierImport(file, name, moduleSpecifier, changes, checker, identifiers, quotePreference);
default:
return Debug.assertNever(name);
return Debug.assertNever(name, `Convert to ES6 module got invalid name kind ${(name as BindingName).kind}`);
}
}
@@ -401,7 +401,7 @@ namespace ts.codefix {
const { parent } = use;
if (isPropertyAccessExpression(parent)) {
const { expression, name: { text: propertyName } } = parent;
Debug.assert(expression === use); // Else shouldn't have been in `collectIdentifiers`
Debug.assert(expression === use, "Didn't expect expression === use"); // Else shouldn't have been in `collectIdentifiers`
let idName = namedBindingsNames.get(propertyName);
if (idName === undefined) {
idName = makeUniqueName(propertyName, identifiers);
@@ -19,8 +19,8 @@ namespace ts.codefix {
function getImportTypeNode(sourceFile: SourceFile, pos: number): ImportTypeNode {
const token = getTokenAtPosition(sourceFile, pos);
Debug.assert(token.kind === SyntaxKind.ImportKeyword);
Debug.assert(token.parent.kind === SyntaxKind.ImportType);
Debug.assert(token.kind === SyntaxKind.ImportKeyword, "This token should be an ImportKeyword");
Debug.assert(token.parent.kind === SyntaxKind.ImportType, "Token parent should be an ImportType");
return <ImportTypeNode>token.parent;
}
@@ -30,7 +30,7 @@ namespace ts.codefix {
});
function getClass(sourceFile: SourceFile, pos: number): ClassLikeDeclaration {
return Debug.assertDefined(getContainingClass(getTokenAtPosition(sourceFile, pos)));
return Debug.assertDefined(getContainingClass(getTokenAtPosition(sourceFile, pos)), "There should be a containing class");
}
function symbolPointsToNonPrivateMember (symbol: Symbol) {
@@ -17,7 +17,7 @@ namespace ts.codefix {
function getNode(sourceFile: SourceFile, pos: number): ConstructorDeclaration {
const token = getTokenAtPosition(sourceFile, pos);
Debug.assert(token.kind === SyntaxKind.ConstructorKeyword);
Debug.assert(token.kind === SyntaxKind.ConstructorKeyword, "token should be at the constructor keyword");
return token.parent as ConstructorDeclaration;
}
+2 -2
View File
@@ -36,12 +36,12 @@ namespace ts.codefix {
let suggestion: string | undefined;
if (isPropertyAccessExpression(node.parent) && node.parent.name === node) {
Debug.assert(node.kind === SyntaxKind.Identifier);
Debug.assert(node.kind === SyntaxKind.Identifier, "Expected an identifier for spelling (property access)");
const containingType = checker.getTypeAtLocation(node.parent.expression);
suggestion = checker.getSuggestionForNonexistentProperty(node as Identifier, containingType);
}
else if (isImportSpecifier(node.parent) && node.parent.name === node) {
Debug.assert(node.kind === SyntaxKind.Identifier);
Debug.assert(node.kind === SyntaxKind.Identifier, "Expected an identifier for spelling (import)");
const importDeclaration = findAncestor(node, isImportDeclaration)!;
const resolvedSourceFile = getResolvedSourceFileFromImportDeclaration(sourceFile, context, importDeclaration);
if (resolvedSourceFile && resolvedSourceFile.symbol) {
+2 -2
View File
@@ -15,7 +15,7 @@ namespace ts.codefix {
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, start: number, length: number): void {
const token = getTokenAtPosition(sourceFile, start);
const statement = findAncestor(token, isStatement)!;
Debug.assert(statement.getStart(sourceFile) === token.getStart(sourceFile));
Debug.assert(statement.getStart(sourceFile) === token.getStart(sourceFile), "token and statement should start at the same point");
const container = (isBlock(statement.parent) ? statement.parent : statement).parent;
if (!isBlock(statement.parent) || statement === first(statement.parent.statements)) {
@@ -40,7 +40,7 @@ namespace ts.codefix {
if (isBlock(statement.parent)) {
const end = start + length;
const lastStatement = Debug.assertDefined(lastWhere(sliceAfter(statement.parent.statements, statement), s => s.pos < end));
const lastStatement = Debug.assertDefined(lastWhere(sliceAfter(statement.parent.statements, statement), s => s.pos < end), "Some statement should be last");
changes.deleteNodeRange(sourceFile, statement, lastStatement);
}
else {
@@ -117,7 +117,7 @@ namespace ts.codefix {
}
function deleteTypeParameters(changes: textChanges.ChangeTracker, sourceFile: SourceFile, token: Node): void {
changes.delete(sourceFile, Debug.assertDefined(cast(token.parent, isDeclarationWithTypeParameterChildren).typeParameters));
changes.delete(sourceFile, Debug.assertDefined(cast(token.parent, isDeclarationWithTypeParameterChildren).typeParameters, "The type parameter to delete should exist"));
}
// Sometimes the diagnostic span is an entire ImportDeclaration, so we should remove the whole thing.
@@ -231,7 +231,7 @@ namespace ts.codefix {
// Can't remove a non-last parameter in a callback. Can remove a parameter in code-fix-all if future parameters are also unused.
const { parameters } = parent;
const index = parameters.indexOf(p);
Debug.assert(index !== -1);
Debug.assert(index !== -1, "The parameter should already be in the list");
return isFixAll
? parameters.slice(index + 1).every(p => p.name.kind === SyntaxKind.Identifier && !p.symbol.isReferenced)
: index === parameters.length - 1;
+3 -3
View File
@@ -87,7 +87,7 @@ namespace ts.codefix {
ambient ? undefined : createStubbedMethodBody(preferences)));
}
else {
Debug.assertNode(accessor, isSetAccessorDeclaration);
Debug.assertNode(accessor, isSetAccessorDeclaration, "The counterpart to a getter should be a setter");
const parameter = getSetAccessorValueParameter(accessor);
const parameterName = parameter && isIdentifier(parameter.name) ? idText(parameter.name) : undefined;
out(createSetAccessor(
@@ -115,7 +115,7 @@ namespace ts.codefix {
}
if (declarations.length === 1) {
Debug.assert(signatures.length === 1);
Debug.assert(signatures.length === 1, "One declaration implies one signature");
const signature = signatures[0];
outputMethod(signature, modifiers, name, ambient ? undefined : createStubbedMethodBody(preferences));
break;
@@ -132,7 +132,7 @@ namespace ts.codefix {
outputMethod(signature, modifiers, name, createStubbedMethodBody(preferences));
}
else {
Debug.assert(declarations.length === signatures.length);
Debug.assert(declarations.length === signatures.length, "Declarations and signatures should match count");
out(createMethodImplementingSignatures(signatures, name, optional, modifiers, preferences));
}
}
+13 -13
View File
@@ -57,7 +57,7 @@ namespace ts.codefix {
pushIfUnique(entry.namedImports, symbolName);
}
else {
Debug.assert(entry.defaultImport === undefined || entry.defaultImport === symbolName);
Debug.assert(entry.defaultImport === undefined || entry.defaultImport === symbolName, "(Add to Existing) Default import should be missing or match symbolName");
entry.defaultImport = symbolName;
}
break;
@@ -70,7 +70,7 @@ namespace ts.codefix {
}
switch (importKind) {
case ImportKind.Default:
Debug.assert(entry.defaultImport === undefined || entry.defaultImport === symbolName);
Debug.assert(entry.defaultImport === undefined || entry.defaultImport === symbolName, "(Add new) Default import should be missing or match symbolName");
entry.defaultImport = symbolName;
break;
case ImportKind.Named:
@@ -78,14 +78,14 @@ namespace ts.codefix {
break;
case ImportKind.Equals:
case ImportKind.Namespace:
Debug.assert(entry.namespaceLikeImport === undefined || entry.namespaceLikeImport.name === symbolName);
Debug.assert(entry.namespaceLikeImport === undefined || entry.namespaceLikeImport.name === symbolName, "Namespacelike import shoudl be missing or match symbolName");
entry.namespaceLikeImport = { importKind, name: symbolName };
break;
}
break;
}
default:
Debug.assertNever(fix);
Debug.assertNever(fix, `fix wasn't never - got kind ${(fix as ImportFix).kind}`);
}
});
@@ -165,7 +165,7 @@ namespace ts.codefix {
preferences: UserPreferences,
): { readonly moduleSpecifier: string, readonly codeAction: CodeAction } {
const exportInfos = getAllReExportingModules(sourceFile, exportedSymbol, moduleSymbol, symbolName, sourceFile, program.getCompilerOptions(), program.getTypeChecker(), program.getSourceFiles());
Debug.assert(exportInfos.some(info => info.moduleSymbol === moduleSymbol));
Debug.assert(exportInfos.some(info => info.moduleSymbol === moduleSymbol), "Some exportInfo should match the specified moduleSymbol");
// We sort the best codefixes first, so taking `first` is best for completions.
const moduleSpecifier = first(getNewImportInfos(program, sourceFile, position, exportInfos, host, preferences)).moduleSpecifier;
const fix = first(getFixForImport(exportInfos, symbolName, position, program, sourceFile, host, preferences));
@@ -288,7 +288,7 @@ namespace ts.codefix {
moduleSpecifiers.getModuleSpecifiers(moduleSymbol, program.getCompilerOptions(), sourceFile, host, program.getSourceFiles(), preferences, program.redirectTargetsMap)
.map((moduleSpecifier): FixAddNewImport | FixUseImportType =>
// `position` should only be undefined at a missing jsx namespace, in which case we shouldn't be looking for pure types.
exportedSymbolIsTypeOnly && isJs ? { kind: ImportFixKind.ImportType, moduleSpecifier, position: Debug.assertDefined(position) } : { kind: ImportFixKind.AddNew, moduleSpecifier, importKind }));
exportedSymbolIsTypeOnly && isJs ? { kind: ImportFixKind.ImportType, moduleSpecifier, position: Debug.assertDefined(position, "position should be defined") } : { kind: ImportFixKind.AddNew, moduleSpecifier, importKind }));
// Sort to keep the shortest paths first
return sort(choicesForEachExportingModule, (a, b) => a.moduleSpecifier.length - b.moduleSpecifier.length);
}
@@ -369,7 +369,7 @@ namespace ts.codefix {
// Fall back to the `import * as ns` style import.
return ImportKind.Namespace;
default:
return Debug.assertNever(moduleKind);
return Debug.assertNever(moduleKind, `Unexpected moduleKind ${moduleKind}`);
}
}
@@ -382,7 +382,7 @@ namespace ts.codefix {
? checker.getJsxNamespace(sourceFile)
: symbolToken.text;
// "default" is a keyword and not a legal identifier for the import, so we don't expect it here
Debug.assert(symbolName !== InternalSymbolName.Default);
Debug.assert(symbolName !== InternalSymbolName.Default, "'default' isn't a legal identifier and couldn't occur here");
const fixes = arrayFrom(flatMapIterator(getExportInfos(symbolName, getMeaningFromLocation(symbolToken), cancellationToken, sourceFile, checker, program).entries(), ([_, exportInfos]) =>
getFixForImport(exportInfos, symbolName, symbolToken.getStart(sourceFile), program, sourceFile, host, preferences)));
@@ -468,7 +468,7 @@ namespace ts.codefix {
if (defaultExport.flags & SymbolFlags.Alias) {
const aliased = checker.getImmediateAliasedSymbol(defaultExport);
return aliased && getDefaultExportInfoWorker(aliased, Debug.assertDefined(aliased.parent), checker, compilerOptions);
return aliased && getDefaultExportInfoWorker(aliased, Debug.assertDefined(aliased.parent, "Alias targets of default exports must have a parent"), checker, compilerOptions);
}
if (defaultExport.escapedName !== InternalSymbolName.Default &&
@@ -486,7 +486,7 @@ namespace ts.codefix {
}
}
else if (isExportSpecifier(declaration)) {
Debug.assert(declaration.name.text === InternalSymbolName.Default);
Debug.assert(declaration.name.text === InternalSymbolName.Default, "Expected the specifier to be a default export");
return declaration.propertyName && declaration.propertyName.text;
}
});
@@ -521,13 +521,13 @@ namespace ts.codefix {
return [importKind === ImportKind.Default ? Diagnostics.Import_default_0_from_module_1 : Diagnostics.Import_0_from_module_1, symbolName, moduleSpecifier];
}
default:
return Debug.assertNever(fix);
return Debug.assertNever(fix, `Unexpected fix kind ${(fix as ImportFix).kind}`);
}
}
function doAddExistingFix(changes: textChanges.ChangeTracker, sourceFile: SourceFile, clause: ImportClause, defaultImport: string | undefined, namedImports: readonly string[]): void {
if (defaultImport) {
Debug.assert(!clause.name);
Debug.assert(!clause.name, "Default imports can't have names");
changes.insertNodeAt(sourceFile, clause.getStart(sourceFile), createIdentifier(defaultImport), { suffix: ", " });
}
@@ -545,7 +545,7 @@ namespace ts.codefix {
changes.replaceNode(sourceFile, clause.namedBindings, namedImports);
}
else {
changes.insertNodeAfter(sourceFile, Debug.assertDefined(clause.name), namedImports);
changes.insertNodeAfter(sourceFile, Debug.assertDefined(clause.name, "Named import specifiers must have names"), namedImports);
}
}
}
+2 -2
View File
@@ -211,7 +211,7 @@ namespace ts.codefix {
declaration: p,
type: isIdentifier(p.name) ? inferTypeForVariableFromUsage(p.name, program, cancellationToken) : program.getTypeChecker().getAnyType()
}));
Debug.assert(containingFunction.parameters.length === parameterInferences.length);
Debug.assert(containingFunction.parameters.length === parameterInferences.length, "Parameter count and inference count should match");
if (isInJSFile(containingFunction)) {
annotateJSDocParameters(changes, sourceFile, parameterInferences, program, host);
@@ -747,7 +747,7 @@ namespace ts.codefix {
for (const i of inferences) {
for (const { high, low } of priorities) {
if (high(i)) {
Debug.assert(!low(i));
Debug.assert(!low(i), "Priority can't have both low and high");
toRemove.push(low);
}
}
+10 -10
View File
@@ -12,8 +12,8 @@ namespace ts.refactor {
return [{ name: refactorName, description, actions: [{ name: actionName, description }] }];
},
getEditsForAction(context, actionName): RefactorEditInfo {
Debug.assert(actionName === actionNameDefaultToNamed || actionName === actionNameNamedToDefault);
const edits = textChanges.ChangeTracker.with(context, t => doChange(context.file, context.program, Debug.assertDefined(getInfo(context)), t, context.cancellationToken));
Debug.assert(actionName === actionNameDefaultToNamed || actionName === actionNameNamedToDefault, "Unexpected action name");
const edits = textChanges.ChangeTracker.with(context, t => doChange(context.file, context.program, Debug.assertDefined(getInfo(context), "context must have info"), t, context.cancellationToken));
return { edits, renameFilename: undefined, renameLocation: undefined };
},
});
@@ -63,7 +63,7 @@ namespace ts.refactor {
}
const decl = first(vs.declarationList.declarations);
if (!decl.initializer) return undefined;
Debug.assert(!wasDefault);
Debug.assert(!wasDefault, "Can't have a default flag here");
return isIdentifier(decl.name) ? { exportNode: vs, exportName: decl.name, wasDefault, exportingModuleSymbol } : undefined;
}
default:
@@ -78,10 +78,10 @@ namespace ts.refactor {
function changeExport(exportingSourceFile: SourceFile, { wasDefault, exportNode, exportName }: Info, changes: textChanges.ChangeTracker, checker: TypeChecker): void {
if (wasDefault) {
changes.delete(exportingSourceFile, Debug.assertDefined(findModifier(exportNode, SyntaxKind.DefaultKeyword)));
changes.delete(exportingSourceFile, Debug.assertDefined(findModifier(exportNode, SyntaxKind.DefaultKeyword), "Should find a default keyword in modifier list"));
}
else {
const exportKeyword = Debug.assertDefined(findModifier(exportNode, SyntaxKind.ExportKeyword));
const exportKeyword = Debug.assertDefined(findModifier(exportNode, SyntaxKind.ExportKeyword), "Should find an export keyword in modifier list");
switch (exportNode.kind) {
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.ClassDeclaration:
@@ -92,7 +92,7 @@ namespace ts.refactor {
// If 'x' isn't used in this file, `export const x = 0;` --> `export default 0;`
if (!FindAllReferences.Core.isSymbolReferencedInFile(exportName, checker, exportingSourceFile)) {
// We checked in `getInfo` that an initializer exists.
changes.replaceNode(exportingSourceFile, exportNode, createExportDefault(Debug.assertDefined(first(exportNode.declarationList.declarations).initializer)));
changes.replaceNode(exportingSourceFile, exportNode, createExportDefault(Debug.assertDefined(first(exportNode.declarationList.declarations).initializer, "Initializer was previously known to be present")));
break;
}
// falls through
@@ -104,14 +104,14 @@ namespace ts.refactor {
changes.insertNodeAfter(exportingSourceFile, exportNode, createExportDefault(createIdentifier(exportName.text)));
break;
default:
Debug.assertNever(exportNode);
Debug.assertNever(exportNode, `Unexpected exportNode kind ${(exportNode as ExportToConvert).kind}`);
}
}
}
function changeImports(program: Program, { wasDefault, exportName, exportingModuleSymbol }: Info, changes: textChanges.ChangeTracker, cancellationToken: CancellationToken | undefined): void {
const checker = program.getTypeChecker();
const exportSymbol = Debug.assertDefined(checker.getSymbolAtLocation(exportName));
const exportSymbol = Debug.assertDefined(checker.getSymbolAtLocation(exportName), "Export name should resolve to a symbol");
FindAllReferences.Core.eachExportReference(program.getSourceFiles(), checker, cancellationToken, exportSymbol, exportingModuleSymbol, exportName.text, wasDefault, ref => {
const importingSourceFile = ref.getSourceFile();
if (wasDefault) {
@@ -139,7 +139,7 @@ namespace ts.refactor {
}
case SyntaxKind.ImportClause: {
const clause = parent as ImportClause;
Debug.assert(clause.name === ref);
Debug.assert(clause.name === ref, "Import clause name should match provided ref");
const spec = makeImportSpecifier(exportName, ref.text);
const { namedBindings } = clause;
if (!namedBindings) {
@@ -194,7 +194,7 @@ namespace ts.refactor {
break;
}
default:
Debug.assertNever(parent);
Debug.assertNever(parent, `Unexpected parent kind ${(parent as Node).kind}`);
}
}
+3 -3
View File
@@ -12,8 +12,8 @@ namespace ts.refactor {
return [{ name: refactorName, description, actions: [{ name: actionName, description }] }];
},
getEditsForAction(context, actionName): RefactorEditInfo {
Debug.assert(actionName === actionNameNamespaceToNamed || actionName === actionNameNamedToNamespace);
const edits = textChanges.ChangeTracker.with(context, t => doChange(context.file, context.program, t, Debug.assertDefined(getImportToConvert(context))));
Debug.assert(actionName === actionNameNamespaceToNamed || actionName === actionNameNamedToNamespace, "Unexpected action name");
const edits = textChanges.ChangeTracker.with(context, t => doChange(context.file, context.program, t, Debug.assertDefined(getImportToConvert(context), "Context must provide an import to convert")));
return { edits, renameFilename: undefined, renameLocation: undefined };
}
});
@@ -55,7 +55,7 @@ namespace ts.refactor {
if (checker.resolveName(exportName, id, SymbolFlags.All, /*excludeGlobals*/ true)) {
conflictingNames.set(exportName, true);
}
Debug.assert(parent.expression === id);
Debug.assert(parent.expression === id, "Parent expression should match id");
nodesToReplace.push(parent);
}
});
@@ -24,7 +24,7 @@ namespace ts.refactor.convertParamsToDestructuredObject {
}
function getEditsForAction(context: RefactorContext, actionName: string): RefactorEditInfo | undefined {
Debug.assert(actionName === refactorName);
Debug.assert(actionName === refactorName, "Unexpected action name");
const { file, startPosition, program, cancellationToken, host } = context;
const functionDeclaration = getFunctionDeclarationAtPosition(file, startPosition, program.getTypeChecker());
if (!functionDeclaration || !cancellationToken) return undefined;
@@ -563,7 +563,7 @@ namespace ts.refactor.convertParamsToDestructuredObject {
if (functionDeclaration.name) return [functionDeclaration.name, functionDeclaration.parent.name];
return [functionDeclaration.parent.name];
default:
return Debug.assertNever(functionDeclaration);
return Debug.assertNever(functionDeclaration, `Unexpected function declaration kind ${(functionDeclaration as ValidFunctionDeclaration).kind}`);
}
}
+12 -12
View File
@@ -335,10 +335,10 @@ namespace ts.refactor.extractSymbol {
}
// We believe it's true because the node is from the (unmodified) tree.
Debug.assert(nodeToCheck.pos <= nodeToCheck.end, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809");
Debug.assert(nodeToCheck.pos <= nodeToCheck.end, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809 (1)");
// For understanding how skipTrivia functioned:
Debug.assert(!positionIsSynthesized(nodeToCheck.pos), "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809");
Debug.assert(!positionIsSynthesized(nodeToCheck.pos), "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809 (2)");
if (!isStatement(nodeToCheck) && !(isExpressionNode(nodeToCheck) && isExtractableExpression(nodeToCheck))) {
return [createDiagnosticForNode(nodeToCheck, Messages.statementOrExpressionExpected)];
@@ -681,7 +681,7 @@ namespace ts.refactor.extractSymbol {
case SyntaxKind.SetAccessor:
return `'set ${scope.name.getText()}'`;
default:
throw Debug.assertNever(scope);
throw Debug.assertNever(scope, `Unexpected scope kind ${(scope as FunctionLikeDeclaration).kind}`);
}
}
function getDescriptionForClassLikeDeclaration(scope: ClassLikeDeclaration): string {
@@ -837,8 +837,8 @@ namespace ts.refactor.extractSymbol {
// No need to mix declarations and writes.
// How could any variables be exposed if there's a return statement?
Debug.assert(!returnValueProperty);
Debug.assert(!(range.facts & RangeFacts.HasReturn));
Debug.assert(!returnValueProperty, "Expected no returnValueProperty");
Debug.assert(!(range.facts & RangeFacts.HasReturn), "Expected RangeFacts.HasReturn flag to be unset");
if (exposedVariableDeclarations.length === 1) {
// Declaring exactly one variable: let x = newFunction();
@@ -928,7 +928,7 @@ namespace ts.refactor.extractSymbol {
if (assignments.length === 1) {
// We would only have introduced a return value property if there had been
// other assignments to make.
Debug.assert(!returnValueProperty);
Debug.assert(!returnValueProperty, "Shouldn't have returnValueProperty here");
newNodes.push(createStatement(createAssignment(assignments[0].name, call)));
@@ -1016,7 +1016,7 @@ namespace ts.refactor.extractSymbol {
const changeTracker = textChanges.ChangeTracker.fromContext(context);
if (isClassLike(scope)) {
Debug.assert(!isJS); // See CannotExtractToJSClass
Debug.assert(!isJS, "Cannot extract to a JS class"); // See CannotExtractToJSClass
const modifiers: Modifier[] = [];
modifiers.push(createToken(SyntaxKind.PrivateKeyword));
if (rangeFacts & RangeFacts.InStaticRegion) {
@@ -1255,7 +1255,7 @@ namespace ts.refactor.extractSymbol {
function getNodeToInsertPropertyBefore(maxPos: number, scope: ClassLikeDeclaration): ClassElement {
const members = scope.members;
Debug.assert(members.length > 0); // There must be at least one child, since we extracted from one.
Debug.assert(members.length > 0, "Found no members"); // There must be at least one child, since we extracted from one.
let prevMember: ClassElement | undefined;
let allProperties = true;
@@ -1301,12 +1301,12 @@ namespace ts.refactor.extractSymbol {
if (!prevStatement && isCaseClause(curr)) {
// We must have been in the expression of the case clause.
Debug.assert(isSwitchStatement(curr.parent.parent));
Debug.assert(isSwitchStatement(curr.parent.parent), "Grandparent isn't a switch statement");
return curr.parent.parent;
}
// There must be at least one statement since we started in one.
return Debug.assertDefined(prevStatement);
return Debug.assertDefined(prevStatement, "prevStatement failed to get set");
}
Debug.assert(curr !== scope, "Didn't encounter a block-like before encountering scope");
@@ -1476,7 +1476,7 @@ namespace ts.refactor.extractSymbol {
// If we didn't get through all the scopes, then there were some that weren't in our
// parent chain (impossible at time of writing). A conservative solution would be to
// copy allTypeParameterUsages into all remaining scopes.
Debug.assert(i === scopes.length);
Debug.assert(i === scopes.length, "Should have iterated all scopes");
}
// If there are any declarations in the extracted block that are used in the same enclosing
@@ -1512,7 +1512,7 @@ namespace ts.refactor.extractSymbol {
});
// If an expression was extracted, then there shouldn't have been any variable declarations.
Debug.assert(isReadonlyArray(targetRange.range) || exposedVariableDeclarations.length === 0);
Debug.assert(isReadonlyArray(targetRange.range) || exposedVariableDeclarations.length === 0, "No variable declarations expected if something was extracted");
if (hasWrite && !isReadonlyArray(targetRange.range)) {
const diag = createDiagnosticForNode(targetRange.range, Messages.cannotWriteInExpression);
+4 -4
View File
@@ -19,10 +19,10 @@ namespace ts.refactor {
}];
},
getEditsForAction(context, actionName): RefactorEditInfo {
Debug.assert(actionName === extractToTypeAlias || actionName === extractToTypeDef);
Debug.assert(actionName === extractToTypeAlias || actionName === extractToTypeDef, "Unexpected action name");
const { file } = context;
const info = Debug.assertDefined(getRangeToExtract(context));
Debug.assert(actionName === extractToTypeAlias && !info.isJS || actionName === extractToTypeDef && info.isJS);
const info = Debug.assertDefined(getRangeToExtract(context), "Expected to find a range to extract");
Debug.assert(actionName === extractToTypeAlias && !info.isJS || actionName === extractToTypeDef && info.isJS, "Invalid actionName/JS combo");
const name = getUniqueName("NewType", file);
const edits = textChanges.ChangeTracker.with(context, changes => info.isJS ?
@@ -47,7 +47,7 @@ namespace ts.refactor {
if (!selection || !isTypeNode(selection)) return undefined;
const checker = context.program.getTypeChecker();
const firstStatement = Debug.assertDefined(isJS ? findAncestor(selection, isStatementAndHasJSDoc) : findAncestor(selection, isStatement));
const firstStatement = Debug.assertDefined(isJS ? findAncestor(selection, isStatementAndHasJSDoc) : findAncestor(selection, isStatement), "Should find a statement");
const typeParameters = collectTypeParameters(checker, selection, firstStatement, file);
if (!typeParameters) return undefined;
+12 -12
View File
@@ -8,7 +8,7 @@ namespace ts.refactor {
return [{ name: refactorName, description, actions: [{ name: refactorName, description }] }];
},
getEditsForAction(context, actionName): RefactorEditInfo {
Debug.assert(actionName === refactorName);
Debug.assert(actionName === refactorName, "Wrong refactor invoked");
const statements = Debug.assertDefined(getStatementsToMove(context));
const edits = textChanges.ChangeTracker.with(context, t => doChange(context.file, context.program, statements, t, context.host, context.preferences));
return { edits, renameFilename: undefined, renameLocation: undefined };
@@ -184,7 +184,7 @@ namespace ts.refactor {
case SyntaxKind.VariableDeclaration:
return tryCast(node.name, isIdentifier);
default:
return Debug.assertNever(node);
return Debug.assertNever(node, `Unexpected node kind ${(node as SupportedImport).kind}`);
}
}
@@ -232,7 +232,7 @@ namespace ts.refactor {
case SyntaxKind.VariableDeclaration:
return createVariableDeclaration(newNamespaceId, /*type*/ undefined, createRequireCall(newModuleString));
default:
return Debug.assertNever(node);
return Debug.assertNever(node, `Unexpected node kind ${(node as SupportedImport).kind}`);
}
}
@@ -290,7 +290,7 @@ namespace ts.refactor {
return makeImportIfNecessary(defaultImport, specifiers, path, quotePreference);
}
else {
Debug.assert(!defaultImport); // If there's a default export, it should have been an es6 module.
Debug.assert(!defaultImport, "No default import should exist"); // If there's a default export, it should have been an es6 module.
const bindingElements = imports.map(i => createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, i));
return bindingElements.length
? makeVariableStatement(createObjectBindingPattern(bindingElements), /*type*/ undefined, createRequireCall(createLiteral(path)))
@@ -332,7 +332,7 @@ namespace ts.refactor {
deleteUnusedImportsInVariableDeclaration(sourceFile, importDecl, changes, isUnused);
break;
default:
Debug.assertNever(importDecl);
Debug.assertNever(importDecl, `Unexpected import decl kind ${(importDecl as SupportedImport).kind}`);
}
}
function deleteUnusedImportsInDeclaration(sourceFile: SourceFile, importDecl: ImportDeclaration, changes: textChanges.ChangeTracker, isUnused: (name: Identifier) => boolean): void {
@@ -472,7 +472,7 @@ namespace ts.refactor {
for (const statement of toMove) {
forEachTopLevelDeclaration(statement, decl => {
movedSymbols.add(Debug.assertDefined(isExpressionStatement(decl) ? checker.getSymbolAtLocation(decl.expression.left) : decl.symbol));
movedSymbols.add(Debug.assertDefined(isExpressionStatement(decl) ? checker.getSymbolAtLocation(decl.expression.left) : decl.symbol, "Need a symbol here"));
});
}
for (const statement of toMove) {
@@ -565,7 +565,7 @@ namespace ts.refactor {
return name ? makeVariableStatement(name, i.type, createRequireCall(moduleSpecifier), i.parent.flags) : undefined;
}
default:
return Debug.assertNever(i);
return Debug.assertNever(i, `Unexpected import kind ${(i as SupportedImport).kind}`);
}
}
function filterNamedBindings(namedBindings: NamedImportBindings, keep: (name: Identifier) => boolean): NamedImportBindings | undefined {
@@ -654,7 +654,7 @@ namespace ts.refactor {
}
function isTopLevelDeclarationStatement(node: Node): node is TopLevelDeclarationStatement {
Debug.assert(isSourceFile(node.parent));
Debug.assert(isSourceFile(node.parent), "Node parent should be a SourceFile");
return isNonVariableTopLevelDeclaration(node) || isVariableStatement(node);
}
@@ -703,7 +703,7 @@ namespace ts.refactor {
case SyntaxKind.ObjectBindingPattern:
return firstDefined(name.elements, em => isOmittedExpression(em) ? undefined : forEachTopLevelDeclarationInBindingName(em.name, cb));
default:
return Debug.assertNever(name);
return Debug.assertNever(name, `Unexpected name kind ${(name as BindingName).kind}`);
}
}
@@ -768,7 +768,7 @@ namespace ts.refactor {
case SyntaxKind.ExpressionStatement:
return Debug.fail(); // Shouldn't try to add 'export' keyword to `exports.x = ...`
default:
return Debug.assertNever(d);
return Debug.assertNever(d, `Unexpected declaration kind ${(d as DeclarationStatement).kind}`);
}
}
function addCommonjsExport(decl: TopLevelDeclarationStatement): readonly Statement[] | undefined {
@@ -788,9 +788,9 @@ namespace ts.refactor {
case SyntaxKind.ImportEqualsDeclaration:
return emptyArray;
case SyntaxKind.ExpressionStatement:
return Debug.fail(); // Shouldn't try to add 'export' keyword to `exports.x = ...`
return Debug.fail("Can't export an ExpressionStatement"); // Shouldn't try to add 'export' keyword to `exports.x = ...`
default:
return Debug.assertNever(decl);
return Debug.assertNever(decl, `Unexpected decl kind ${(decl as TopLevelDeclarationStatement).kind}`);
}
}
@@ -19,10 +19,10 @@ tests/cases/conformance/salsa/use.js(6,5): error TS2345: Argument of type '"not
declare var exports: any;
==== tests/cases/conformance/salsa/mod.js (0 errors) ====
/// <reference path='./types.d.ts'/>
var A = function() {
var A = function A() {
this.a = 1
}
var B = function() {
var B = function B() {
this.b = 2
}
exports.A = A
@@ -37,17 +37,19 @@ declare var exports: any;
=== tests/cases/conformance/salsa/mod.js ===
/// <reference path='./types.d.ts'/>
var A = function() {
var A = function A() {
>A : Symbol(A, Decl(mod.js, 1, 3), Decl(mod.js, 8, 13))
>A : Symbol(A, Decl(mod.js, 1, 7))
this.a = 1
>a : Symbol(A.a, Decl(mod.js, 1, 20))
>a : Symbol(A.a, Decl(mod.js, 1, 22))
}
var B = function() {
var B = function B() {
>B : Symbol(B, Decl(mod.js, 4, 3), Decl(mod.js, 9, 13))
>B : Symbol(B, Decl(mod.js, 4, 7))
this.b = 2
>b : Symbol(B.b, Decl(mod.js, 4, 20))
>b : Symbol(B.b, Decl(mod.js, 4, 22))
}
exports.A = A
>exports.A : Symbol(A, Decl(mod.js, 6, 1))
@@ -44,9 +44,10 @@ declare var exports: any;
=== tests/cases/conformance/salsa/mod.js ===
/// <reference path='./types.d.ts'/>
var A = function() {
var A = function A() {
>A : typeof A
>function A() { this.a = 1} : typeof A
>A : typeof A
>function() { this.a = 1} : typeof A
this.a = 1
>this.a = 1 : 1
@@ -55,9 +56,10 @@ var A = function() {
>a : any
>1 : 1
}
var B = function() {
var B = function B() {
>B : typeof B
>function B() { this.b = 2} : typeof B
>B : typeof B
>function() { this.b = 2} : typeof B
this.b = 2
>this.b = 2 : 2
@@ -0,0 +1,31 @@
tests/cases/conformance/salsa/other.js(5,5): error TS2339: Property 'wat' does not exist on type 'One'.
tests/cases/conformance/salsa/other.js(10,5): error TS2339: Property 'wat' does not exist on type 'Two'.
==== tests/cases/conformance/salsa/prototypePropertyAssignmentMergeAcrossFiles2.js (0 errors) ====
var Ns = {}
Ns.One = function() {};
Ns.Two = function() {};
Ns.One.prototype = {
ok() {},
};
Ns.Two.prototype = {
}
==== tests/cases/conformance/salsa/other.js (2 errors) ====
/**
* @type {Ns.One}
*/
var one;
one.wat;
~~~
!!! error TS2339: Property 'wat' does not exist on type 'One'.
/**
* @type {Ns.Two}
*/
var two;
two.wat;
~~~
!!! error TS2339: Property 'wat' does not exist on type 'Two'.
@@ -0,0 +1,52 @@
=== tests/cases/conformance/salsa/prototypePropertyAssignmentMergeAcrossFiles2.js ===
var Ns = {}
>Ns : Symbol(Ns, Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 0, 3), Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 0, 11), Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 1, 23), Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 2, 23), Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 6, 2))
Ns.One = function() {};
>Ns.One : Symbol(Ns.One, Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 0, 11), Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 4, 3))
>Ns : Symbol(Ns, Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 0, 3), Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 0, 11), Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 1, 23), Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 2, 23), Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 6, 2))
>One : Symbol(Ns.One, Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 0, 11), Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 4, 3))
Ns.Two = function() {};
>Ns.Two : Symbol(Ns.Two, Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 1, 23), Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 7, 3))
>Ns : Symbol(Ns, Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 0, 3), Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 0, 11), Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 1, 23), Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 2, 23), Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 6, 2))
>Two : Symbol(Ns.Two, Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 1, 23), Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 7, 3))
Ns.One.prototype = {
>Ns.One.prototype : Symbol(Ns.One.prototype, Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 2, 23))
>Ns.One : Symbol(Ns.One, Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 0, 11), Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 4, 3))
>Ns : Symbol(Ns, Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 0, 3), Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 0, 11), Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 1, 23), Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 2, 23), Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 6, 2))
>One : Symbol(Ns.One, Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 0, 11), Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 4, 3))
>prototype : Symbol(Ns.One.prototype, Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 2, 23))
ok() {},
>ok : Symbol(ok, Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 4, 20))
};
Ns.Two.prototype = {
>Ns.Two.prototype : Symbol(Ns.Two.prototype, Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 6, 2))
>Ns.Two : Symbol(Ns.Two, Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 1, 23), Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 7, 3))
>Ns : Symbol(Ns, Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 0, 3), Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 0, 11), Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 1, 23), Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 2, 23), Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 6, 2))
>Two : Symbol(Ns.Two, Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 1, 23), Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 7, 3))
>prototype : Symbol(Ns.Two.prototype, Decl(prototypePropertyAssignmentMergeAcrossFiles2.js, 6, 2))
}
=== tests/cases/conformance/salsa/other.js ===
/**
* @type {Ns.One}
*/
var one;
>one : Symbol(one, Decl(other.js, 3, 3))
one.wat;
>one : Symbol(one, Decl(other.js, 3, 3))
/**
* @type {Ns.Two}
*/
var two;
>two : Symbol(two, Decl(other.js, 8, 3))
two.wat;
>two : Symbol(two, Decl(other.js, 8, 3))
@@ -0,0 +1,65 @@
=== tests/cases/conformance/salsa/prototypePropertyAssignmentMergeAcrossFiles2.js ===
var Ns = {}
>Ns : typeof Ns
>{} : {}
Ns.One = function() {};
>Ns.One = function() {} : typeof One
>Ns.One : typeof One
>Ns : typeof Ns
>One : typeof One
>function() {} : typeof One
Ns.Two = function() {};
>Ns.Two = function() {} : typeof Two
>Ns.Two : typeof Two
>Ns : typeof Ns
>Two : typeof Two
>function() {} : typeof Two
Ns.One.prototype = {
>Ns.One.prototype = { ok() {},} : { ok(): void; }
>Ns.One.prototype : { ok(): void; }
>Ns.One : typeof One
>Ns : typeof Ns
>One : typeof One
>prototype : { ok(): void; }
>{ ok() {},} : { ok(): void; }
ok() {},
>ok : () => void
};
Ns.Two.prototype = {
>Ns.Two.prototype = {} : {}
>Ns.Two.prototype : {}
>Ns.Two : typeof Two
>Ns : typeof Ns
>Two : typeof Two
>prototype : {}
>{} : {}
}
=== tests/cases/conformance/salsa/other.js ===
/**
* @type {Ns.One}
*/
var one;
>one : One
one.wat;
>one.wat : any
>one : One
>wat : any
/**
* @type {Ns.Two}
*/
var two;
>two : Two
two.wat;
>two.wat : any
>two : Two
>wat : any
@@ -7,10 +7,10 @@ declare function require(name: string): any;
declare var exports: any;
// @Filename: mod.js
/// <reference path='./types.d.ts'/>
var A = function() {
var A = function A() {
this.a = 1
}
var B = function() {
var B = function B() {
this.b = 2
}
exports.A = A
@@ -0,0 +1,25 @@
// @Filename: prototypePropertyAssignmentMergeAcrossFiles2.js
// @allowJs: true
// @checkJs: true
// @noEmit: true
var Ns = {}
Ns.One = function() {};
Ns.Two = function() {};
Ns.One.prototype = {
ok() {},
};
Ns.Two.prototype = {
}
// @Filename: other.js
/**
* @type {Ns.One}
*/
var one;
one.wat;
/**
* @type {Ns.Two}
*/
var two;
two.wat;