diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 562a650a7f0..b6074162fff 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -227,12 +227,13 @@ namespace ts { // Should not be called on a declaration with a computed property name, // unless it is a well known Symbol. function getDeclarationName(node: Declaration): string { - if (node.name) { + const name = getNameOfDeclaration(node); + if (name) { if (isAmbientModule(node)) { - return isGlobalScopeAugmentation(node) ? "__global" : `"${(node.name).text}"`; + return isGlobalScopeAugmentation(node) ? "__global" : `"${(name).text}"`; } - if (node.name.kind === SyntaxKind.ComputedPropertyName) { - const nameExpression = (node.name).expression; + if (name.kind === SyntaxKind.ComputedPropertyName) { + const nameExpression = (name).expression; // treat computed property names where expression is string/numeric literal as just string/numeric literal if (isStringOrNumericLiteral(nameExpression)) { return nameExpression.text; @@ -241,7 +242,7 @@ namespace ts { Debug.assert(isWellKnownSymbolSyntactically(nameExpression)); return getPropertyNameForKnownSymbolName((nameExpression).name.text); } - return (node.name).text; + return (name).text; } switch (node.kind) { case SyntaxKind.Constructor: @@ -303,7 +304,7 @@ namespace ts { } function getDisplayName(node: Declaration): string { - return node.name ? declarationNameToString(node.name) : getDeclarationName(node); + return (node as NamedDeclaration).name ? declarationNameToString((node as NamedDeclaration).name) : getDeclarationName(node); } /** @@ -366,8 +367,8 @@ namespace ts { symbolTable.set(name, symbol = createSymbol(SymbolFlags.None, name)); } else { - if (node.name) { - node.name.parent = node; + if ((node as NamedDeclaration).name) { + (node as NamedDeclaration).name.parent = node; } // Report errors every position with duplicate declaration @@ -396,9 +397,9 @@ namespace ts { } forEach(symbol.declarations, declaration => { - file.bindDiagnostics.push(createDiagnosticForNode(declaration.name || declaration, message, getDisplayName(declaration))); + file.bindDiagnostics.push(createDiagnosticForNode(getNameOfDeclaration(declaration) || declaration, message, getDisplayName(declaration))); }); - file.bindDiagnostics.push(createDiagnosticForNode(node.name || node, message, getDisplayName(node))); + file.bindDiagnostics.push(createDiagnosticForNode(getNameOfDeclaration(node) || node, message, getDisplayName(node))); symbol = createSymbol(SymbolFlags.None, name); } @@ -439,9 +440,9 @@ namespace ts { // and this case is specially handled. Module augmentations should only be merged with original module definition // and should never be merged directly with other augmentation, and the latter case would be possible if automatic merge is allowed. const isJSDocTypedefInJSDocNamespace = node.kind === SyntaxKind.JSDocTypedefTag && - node.name && - node.name.kind === SyntaxKind.Identifier && - (node.name).isInJSDocNamespace; + (node as JSDocTypedefTag).name && + (node as JSDocTypedefTag).name.kind === SyntaxKind.Identifier && + ((node as JSDocTypedefTag).name as Identifier).isInJSDocNamespace; if ((!isAmbientModule(node) && (hasExportModifier || container.flags & NodeFlags.ExportContext)) || isJSDocTypedefInJSDocNamespace) { const exportKind = (symbolFlags & SymbolFlags.Value ? SymbolFlags.ExportValue : 0) | diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f0f0a136439..a96b4809428 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -591,16 +591,16 @@ namespace ts { recordMergedSymbol(target, source); } else if (target.flags & SymbolFlags.NamespaceModule) { - error(source.declarations[0].name, Diagnostics.Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity, symbolToString(target)); + error(getNameOfDeclaration(source.declarations[0]), Diagnostics.Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity, symbolToString(target)); } else { const message = target.flags & SymbolFlags.BlockScopedVariable || source.flags & SymbolFlags.BlockScopedVariable ? Diagnostics.Cannot_redeclare_block_scoped_variable_0 : Diagnostics.Duplicate_identifier_0; forEach(source.declarations, node => { - error(node.name ? node.name : node, message, symbolToString(source)); + error(getNameOfDeclaration(node) || node, message, symbolToString(source)); }); forEach(target.declarations, node => { - error(node.name ? node.name : node, message, symbolToString(source)); + error(getNameOfDeclaration(node) || node, message, symbolToString(source)); }); } } @@ -1283,13 +1283,13 @@ namespace ts { if (!isInAmbientContext(declaration) && !isBlockScopedNameDeclaredBeforeUse(declaration, errorLocation)) { if (result.flags & SymbolFlags.BlockScopedVariable) { - error(errorLocation, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, declarationNameToString(declaration.name)); + error(errorLocation, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, declarationNameToString(getNameOfDeclaration(declaration))); } else if (result.flags & SymbolFlags.Class) { - error(errorLocation, Diagnostics.Class_0_used_before_its_declaration, declarationNameToString(declaration.name)); + error(errorLocation, Diagnostics.Class_0_used_before_its_declaration, declarationNameToString(getNameOfDeclaration(declaration))); } else if (result.flags & SymbolFlags.Enum) { - error(errorLocation, Diagnostics.Enum_0_used_before_its_declaration, declarationNameToString(declaration.name)); + error(errorLocation, Diagnostics.Enum_0_used_before_its_declaration, declarationNameToString(getNameOfDeclaration(declaration))); } } } @@ -1726,10 +1726,9 @@ namespace ts { // references a symbol that is at least declared as a module or a variable. The target of the 'export =' may // combine other declarations with the module or variable (e.g. a class/module, function/module, interface/variable). function resolveESModuleSymbol(moduleSymbol: Symbol, moduleReferenceExpression: Expression, dontResolveAlias: boolean): Symbol { - let symbol = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias); + const symbol = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias); if (!dontResolveAlias && symbol && !(symbol.flags & (SymbolFlags.Module | SymbolFlags.Variable))) { error(moduleReferenceExpression, Diagnostics.Module_0_resolves_to_a_non_module_entity_and_cannot_be_imported_using_this_construct, symbolToString(moduleSymbol)); - symbol = undefined; } return symbol; } @@ -2852,8 +2851,9 @@ namespace ts { function getNameOfSymbol(symbol: Symbol): string { const declaration = firstOrUndefined(symbol.declarations); if (declaration) { - if (declaration.name) { - return declarationNameToString(declaration.name); + const name = getNameOfDeclaration(declaration); + if (name) { + return declarationNameToString(name); } if (declaration.parent && declaration.parent.kind === SyntaxKind.VariableDeclaration) { return declarationNameToString((declaration.parent).name); @@ -2940,8 +2940,9 @@ namespace ts { function getNameOfSymbol(symbol: Symbol): string { if (symbol.declarations && symbol.declarations.length) { const declaration = symbol.declarations[0]; - if (declaration.name) { - return declarationNameToString(declaration.name); + const name = getNameOfDeclaration(declaration); + if (name) { + return declarationNameToString(name); } if (declaration.parent && declaration.parent.kind === SyntaxKind.VariableDeclaration) { return declarationNameToString((declaration.parent).name); @@ -3678,8 +3679,8 @@ namespace ts { case SyntaxKind.BindingElement: return isDeclarationVisible(node.parent.parent); case SyntaxKind.VariableDeclaration: - if (isBindingPattern(node.name) && - !(node.name).elements.length) { + if (isBindingPattern((node as VariableDeclaration).name) && + !((node as VariableDeclaration).name as BindingPattern).elements.length) { // If the binding pattern is empty, this variable declaration is not visible return false; } @@ -6277,8 +6278,8 @@ namespace ts { case SyntaxKind.MethodDeclaration: case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: - return (node).name.kind === SyntaxKind.ComputedPropertyName - && traverse((node).name); + return (node).name.kind === SyntaxKind.ComputedPropertyName + && traverse((node).name); default: return !nodeStartsNewLexicalEnvironment(node) && !isPartOfTypeNode(node) && forEachChild(node, traverse); @@ -6358,8 +6359,9 @@ namespace ts { type = anyType; if (noImplicitAny) { const declaration = signature.declaration; - if (declaration.name) { - error(declaration.name, Diagnostics._0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions, declarationNameToString(declaration.name)); + const name = getNameOfDeclaration(declaration); + if (name) { + error(name, Diagnostics._0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions, declarationNameToString(name)); } else { error(declaration, Diagnostics.Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions); @@ -9942,7 +9944,7 @@ namespace ts { case SyntaxKind.SetAccessor: case SyntaxKind.FunctionExpression: case SyntaxKind.ArrowFunction: - if (!declaration.name) { + if (!(declaration as NamedDeclaration).name) { error(declaration, Diagnostics.Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type, typeAsString); return; } @@ -9951,7 +9953,7 @@ namespace ts { default: diagnostic = Diagnostics.Variable_0_implicitly_has_an_1_type; } - error(declaration, diagnostic, declarationNameToString(declaration.name), typeAsString); + error(declaration, diagnostic, declarationNameToString(getNameOfDeclaration(declaration)), typeAsString); } function reportErrorsFromWidening(declaration: Declaration, type: Type) { @@ -11881,7 +11883,7 @@ namespace ts { if (type === autoType || type === autoArrayType) { if (flowType === autoType || flowType === autoArrayType) { if (noImplicitAny) { - error(declaration.name, Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined, symbolToString(symbol), typeToString(flowType)); + error(getNameOfDeclaration(declaration), Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined, symbolToString(symbol), typeToString(flowType)); error(node, Diagnostics.Variable_0_implicitly_has_an_1_type, symbolToString(symbol), typeToString(flowType)); } return convertAutoToAny(flowType); @@ -15566,7 +15568,7 @@ namespace ts { // only the class declaration node will have the Abstract flag set. const valueDecl = expressionType.symbol && getClassLikeDeclarationOfSymbol(expressionType.symbol); if (valueDecl && getModifierFlags(valueDecl) & ModifierFlags.Abstract) { - error(node, Diagnostics.Cannot_create_an_instance_of_the_abstract_class_0, declarationNameToString(valueDecl.name)); + error(node, Diagnostics.Cannot_create_an_instance_of_the_abstract_class_0, declarationNameToString(getNameOfDeclaration(valueDecl))); return resolveErrorCall(node); } @@ -16030,11 +16032,11 @@ namespace ts { const links = getSymbolLinks(parameter); if (!links.type) { links.type = instantiateType(contextualType, mapper); + const name = getNameOfDeclaration(parameter.valueDeclaration); // if inference didn't come up with anything but {}, fall back to the binding pattern if present. if (links.type === emptyObjectType && - (parameter.valueDeclaration.name.kind === SyntaxKind.ObjectBindingPattern || - parameter.valueDeclaration.name.kind === SyntaxKind.ArrayBindingPattern)) { - links.type = getTypeFromBindingPattern(parameter.valueDeclaration.name); + (name.kind === SyntaxKind.ObjectBindingPattern || name.kind === SyntaxKind.ArrayBindingPattern)) { + links.type = getTypeFromBindingPattern(name); } assignBindingElementTypes(parameter.valueDeclaration); } @@ -17878,7 +17880,7 @@ namespace ts { } if (names.get(memberName)) { - error(member.symbol.valueDeclaration.name, Diagnostics.Duplicate_identifier_0, memberName); + error(getNameOfDeclaration(member.symbol.valueDeclaration), Diagnostics.Duplicate_identifier_0, memberName); error(member.name, Diagnostics.Duplicate_identifier_0, memberName); } else { @@ -17979,7 +17981,8 @@ namespace ts { } function containsSuperCallAsComputedPropertyName(n: Declaration): boolean { - return n.name && containsSuperCall(n.name); + const name = getNameOfDeclaration(n); + return name && containsSuperCall(name); } function containsSuperCall(n: Node): boolean { @@ -18274,16 +18277,16 @@ namespace ts { forEach(overloads, o => { const deviation = getEffectiveDeclarationFlags(o, flagsToCheck) ^ canonicalFlags; if (deviation & ModifierFlags.Export) { - error(o.name, Diagnostics.Overload_signatures_must_all_be_exported_or_non_exported); + error(getNameOfDeclaration(o), Diagnostics.Overload_signatures_must_all_be_exported_or_non_exported); } else if (deviation & ModifierFlags.Ambient) { - error(o.name, Diagnostics.Overload_signatures_must_all_be_ambient_or_non_ambient); + error(getNameOfDeclaration(o), Diagnostics.Overload_signatures_must_all_be_ambient_or_non_ambient); } else if (deviation & (ModifierFlags.Private | ModifierFlags.Protected)) { - error(o.name || o, Diagnostics.Overload_signatures_must_all_be_public_private_or_protected); + error(getNameOfDeclaration(o) || o, Diagnostics.Overload_signatures_must_all_be_public_private_or_protected); } else if (deviation & ModifierFlags.Abstract) { - error(o.name, Diagnostics.Overload_signatures_must_all_be_abstract_or_non_abstract); + error(getNameOfDeclaration(o), Diagnostics.Overload_signatures_must_all_be_abstract_or_non_abstract); } }); } @@ -18295,7 +18298,7 @@ namespace ts { forEach(overloads, o => { const deviation = hasQuestionToken(o) !== canonicalHasQuestionToken; if (deviation) { - error(o.name, Diagnostics.Overload_signatures_must_all_be_optional_or_required); + error(getNameOfDeclaration(o), Diagnostics.Overload_signatures_must_all_be_optional_or_required); } }); } @@ -18431,7 +18434,7 @@ namespace ts { if (duplicateFunctionDeclaration) { forEach(declarations, declaration => { - error(declaration.name, Diagnostics.Duplicate_function_implementation); + error(getNameOfDeclaration(declaration), Diagnostics.Duplicate_function_implementation); }); } @@ -18513,12 +18516,13 @@ namespace ts { for (const d of symbol.declarations) { const declarationSpaces = getDeclarationSpaces(d); + const name = getNameOfDeclaration(d); // Only error on the declarations that contributed to the intersecting spaces. if (declarationSpaces & commonDeclarationSpacesForDefaultAndNonDefault) { - error(d.name, Diagnostics.Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration_instead, declarationNameToString(d.name)); + error(name, Diagnostics.Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration_instead, declarationNameToString(name)); } else if (declarationSpaces & commonDeclarationSpacesForExportsAndLocals) { - error(d.name, Diagnostics.Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local, declarationNameToString(d.name)); + error(name, Diagnostics.Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local, declarationNameToString(name)); } } } @@ -19157,15 +19161,16 @@ namespace ts { if (!local.isReferenced) { if (local.valueDeclaration && getRootDeclaration(local.valueDeclaration).kind === SyntaxKind.Parameter) { const parameter = getRootDeclaration(local.valueDeclaration); + const name = getNameOfDeclaration(local.valueDeclaration); if (compilerOptions.noUnusedParameters && !isParameterPropertyDeclaration(parameter) && !parameterIsThisKeyword(parameter) && - !parameterNameStartsWithUnderscore(local.valueDeclaration.name)) { - error(local.valueDeclaration.name, Diagnostics._0_is_declared_but_never_used, local.name); + !parameterNameStartsWithUnderscore(name)) { + error(name, Diagnostics._0_is_declared_but_never_used, local.name); } } else if (compilerOptions.noUnusedLocals) { - forEach(local.declarations, d => errorUnusedLocal(d.name || d, local.name)); + forEach(local.declarations, d => errorUnusedLocal(getNameOfDeclaration(d) || d, local.name)); } } }); @@ -19249,7 +19254,7 @@ namespace ts { if (!local.isReferenced && !local.exportSymbol) { for (const declaration of local.declarations) { if (!isAmbientModule(declaration)) { - errorUnusedLocal(declaration.name, local.name); + errorUnusedLocal(getNameOfDeclaration(declaration), local.name); } } } @@ -19328,7 +19333,7 @@ namespace ts { if (getNodeCheckFlags(current) & NodeCheckFlags.CaptureThis) { const isDeclaration = node.kind !== SyntaxKind.Identifier; if (isDeclaration) { - error((node).name, Diagnostics.Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference); + error(getNameOfDeclaration(node), Diagnostics.Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference); } else { error(node, Diagnostics.Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference); @@ -19343,7 +19348,7 @@ namespace ts { if (getNodeCheckFlags(current) & NodeCheckFlags.CaptureNewTarget) { const isDeclaration = node.kind !== SyntaxKind.Identifier; if (isDeclaration) { - error((node).name, Diagnostics.Duplicate_identifier_newTarget_Compiler_uses_variable_declaration_newTarget_to_capture_new_target_meta_property_reference); + error(getNameOfDeclaration(node), Diagnostics.Duplicate_identifier_newTarget_Compiler_uses_variable_declaration_newTarget_to_capture_new_target_meta_property_reference); } else { error(node, Diagnostics.Expression_resolves_to_variable_declaration_newTarget_that_compiler_uses_to_capture_new_target_meta_property_reference); @@ -19642,7 +19647,7 @@ namespace ts { checkTypeAssignableTo(checkExpressionCached(node.initializer), declarationType, node, /*headMessage*/ undefined); } if (!areDeclarationFlagsIdentical(node, symbol.valueDeclaration)) { - error(symbol.valueDeclaration.name, Diagnostics.All_declarations_of_0_must_have_identical_modifiers, declarationNameToString(node.name)); + error(getNameOfDeclaration(symbol.valueDeclaration), Diagnostics.All_declarations_of_0_must_have_identical_modifiers, declarationNameToString(node.name)); error(node.name, Diagnostics.All_declarations_of_0_must_have_identical_modifiers, declarationNameToString(node.name)); } } @@ -20473,16 +20478,16 @@ namespace ts { const propDeclaration = prop.valueDeclaration; // index is numeric and property name is not valid numeric literal - if (indexKind === IndexKind.Number && !(propDeclaration ? isNumericName(propDeclaration.name) : isNumericLiteralName(prop.name))) { + if (indexKind === IndexKind.Number && !(propDeclaration ? isNumericName(getNameOfDeclaration(propDeclaration)) : isNumericLiteralName(prop.name))) { return; } // perform property check if property or indexer is declared in 'type' - // this allows to rule out cases when both property and indexer are inherited from the base class + // this allows us to rule out cases when both property and indexer are inherited from the base class let errorNode: Node; if (propDeclaration && (propDeclaration.kind === SyntaxKind.BinaryExpression || - propDeclaration.name.kind === SyntaxKind.ComputedPropertyName || + getNameOfDeclaration(propDeclaration).kind === SyntaxKind.ComputedPropertyName || prop.parent === containingType.symbol)) { errorNode = propDeclaration; } @@ -20841,7 +20846,7 @@ namespace ts { errorMessage = Diagnostics.Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_function; } - error(derived.valueDeclaration.name || derived.valueDeclaration, errorMessage, typeToString(baseType), symbolToString(base), typeToString(type)); + error(getNameOfDeclaration(derived.valueDeclaration) || derived.valueDeclaration, errorMessage, typeToString(baseType), symbolToString(base), typeToString(type)); } } } @@ -21172,7 +21177,7 @@ namespace ts { // check that const is placed\omitted on all enum declarations forEach(enumSymbol.declarations, decl => { if (isConstEnumDeclaration(decl) !== enumIsConst) { - error(decl.name, Diagnostics.Enum_declarations_must_all_be_const_or_non_const); + error(getNameOfDeclaration(decl), Diagnostics.Enum_declarations_must_all_be_const_or_non_const); } }); } @@ -21446,6 +21451,11 @@ namespace ts { Diagnostics.Import_declaration_conflicts_with_local_declaration_of_0; error(node, message, symbolToString(symbol)); } + + // Don't allow to re-export something with no value side when `--isolatedModules` is set. + if (node.kind === SyntaxKind.ExportSpecifier && compilerOptions.isolatedModules && !(target.flags & SymbolFlags.Value)) { + error(node, Diagnostics.Cannot_re_export_a_type_when_the_isolatedModules_flag_is_provided); + } } } @@ -22065,7 +22075,7 @@ namespace ts { function isTypeDeclarationName(name: Node): boolean { return name.kind === SyntaxKind.Identifier && isTypeDeclaration(name.parent) && - (name.parent).name === name; + (name.parent).name === name; } function isTypeDeclaration(node: Node): boolean { @@ -22254,7 +22264,7 @@ namespace ts { return undefined; } - if (isDeclarationName(node)) { + if (isDeclarationNameOrImportPropertyName(node)) { // This is a declaration, call getSymbolOfNode return getSymbolOfNode(node.parent); } @@ -22401,7 +22411,7 @@ namespace ts { return getTypeOfSymbol(symbol); } - if (isDeclarationName(node)) { + if (isDeclarationNameOrImportPropertyName(node)) { const symbol = getSymbolAtLocation(node); return symbol && getTypeOfSymbol(symbol); } @@ -24430,4 +24440,19 @@ namespace ts { return result; } } + + /** Like 'isDeclarationName', but returns true for LHS of `import { x as y }` or `export { x as y }`. */ + function isDeclarationNameOrImportPropertyName(name: Node): boolean { + switch (name.parent.kind) { + case SyntaxKind.ImportSpecifier: + case SyntaxKind.ExportSpecifier: + if ((name.parent as ImportOrExportSpecifier).propertyName) { + return true; + } + // falls through + default: + return isDeclarationName(name); + + } + } } diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index d7ad2c3a78d..7c842de277f 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -67,7 +67,7 @@ namespace ts { let errorNameNode: DeclarationName; const emitJsDocComments = compilerOptions.removeComments ? noop : writeJsDocComments; const emit = compilerOptions.stripInternal ? stripInternal : emitNode; - let noDeclare: boolean; + let needsDeclare = true; let moduleElementDeclarationEmitInfo: ModuleElementDeclarationEmitInfo[] = []; let asynchronousSubModuleDeclarationEmitInfo: ModuleElementDeclarationEmitInfo[]; @@ -110,11 +110,11 @@ namespace ts { resultHasExternalModuleIndicator = false; if (!isBundledEmit || !isExternalModule(sourceFile)) { - noDeclare = false; + needsDeclare = true; emitSourceFile(sourceFile); } else if (isExternalModule(sourceFile)) { - noDeclare = true; + needsDeclare = false; write(`declare module "${getResolvedExternalModuleName(host, sourceFile)}" {`); writeLine(); increaseIndent(); @@ -612,9 +612,9 @@ namespace ts { } } - function emitTempVariableDeclaration(expr: Expression, baseName: string, diagnostic: SymbolAccessibilityDiagnostic): string { + function emitTempVariableDeclaration(expr: Expression, baseName: string, diagnostic: SymbolAccessibilityDiagnostic, needsDeclare: boolean): string { const tempVarName = getExportTempVariableName(baseName); - if (!noDeclare) { + if (needsDeclare) { write("declare "); } write("const "); @@ -636,7 +636,7 @@ namespace ts { const tempVarName = emitTempVariableDeclaration(node.expression, "_default", { diagnosticMessage: Diagnostics.Default_export_of_the_module_has_or_is_using_private_name_0, errorNode: node - }); + }, needsDeclare); write(node.isExportEquals ? "export = " : "export default "); write(tempVarName); } @@ -728,7 +728,7 @@ namespace ts { if (modifiers & ModifierFlags.Default) { write("default "); } - else if (node.kind !== SyntaxKind.InterfaceDeclaration && !noDeclare) { + else if (node.kind !== SyntaxKind.InterfaceDeclaration && needsDeclare) { write("declare "); } } @@ -1127,7 +1127,7 @@ namespace ts { return { diagnosticMessage, errorNode: node, - typeName: (node.parent.parent).name + typeName: getNameOfDeclaration(node.parent.parent) }; } } @@ -1155,7 +1155,7 @@ namespace ts { diagnosticMessage: Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1, errorNode: baseTypeNode, typeName: node.name - }); + }, !findAncestor(node, n => n.kind === SyntaxKind.ModuleDeclaration)); } emitJsDocComments(node); @@ -1266,7 +1266,9 @@ namespace ts { Diagnostics.Exported_variable_0_has_or_is_using_private_name_1; } // This check is to ensure we don't report error on constructor parameter property as that error would be reported during parameter emit - else if (node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature) { + // The only exception here is if the constructor was marked as private. we are not emitting the constructor parameters at all. + else if (node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature || + (node.kind === SyntaxKind.Parameter && hasModifier(node.parent, ModifierFlags.Private))) { // TODO(jfreeman): Deal with computed properties in error reporting. if (hasModifier(node, ModifierFlags.Static)) { return symbolAccessibilityResult.errorModuleName ? @@ -1275,7 +1277,7 @@ namespace ts { Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_private_name_1; } - else if (node.parent.kind === SyntaxKind.ClassDeclaration) { + else if (node.parent.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.Parameter) { return symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : @@ -1501,6 +1503,11 @@ namespace ts { write("["); } else { + if (node.kind === SyntaxKind.Constructor && hasModifier(node, ModifierFlags.Private)) { + write("();"); + writeLine(); + return; + } // Construct signature or constructor type write new Signature if (node.kind === SyntaxKind.ConstructSignature || node.kind === SyntaxKind.ConstructorType) { write("new "); diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 79539dd879e..6d1f6f0dc1d 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -635,6 +635,10 @@ "category": "Error", "code": 1203 }, + "Cannot re-export a type when the '--isolatedModules' flag is provided.": { + "category": "Error", + "code": 1205 + }, "Decorators are not valid here.": { "category": "Error", "code": 1206 diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 93147c4b32f..95c0449959d 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -3086,9 +3086,10 @@ namespace ts { } function getName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: EmitFlags) { - if (node.name && isIdentifier(node.name) && !isGeneratedIdentifier(node.name)) { - const name = getMutableClone(node.name); - emitFlags |= getEmitFlags(node.name); + const nodeName = getNameOfDeclaration(node); + if (nodeName && isIdentifier(nodeName) && !isGeneratedIdentifier(nodeName)) { + const name = getMutableClone(nodeName); + emitFlags |= getEmitFlags(nodeName); if (!allowSourceMaps) emitFlags |= EmitFlags.NoSourceMap; if (!allowComments) emitFlags |= EmitFlags.NoComments; if (emitFlags) setEmitFlags(name, emitFlags); diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index be01d943412..ad9a6b99395 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -3749,7 +3749,7 @@ namespace ts { case SyntaxKind.ClassDeclaration: case SyntaxKind.EnumDeclaration: case SyntaxKind.VariableDeclaration: - return (parent).name === node + return (parent).name === node && resolver.isDeclarationWithCollidingName(parent); } @@ -3782,7 +3782,7 @@ namespace ts { if (enabledSubstitutions & ES2015SubstitutionFlags.BlockScopedBindings && !isInternalName(node)) { const declaration = resolver.getReferencedDeclarationWithCollidingName(node); if (declaration && !(isClassLike(declaration) && isPartOfClassBody(declaration, node))) { - return setTextRange(getGeneratedNameForNode(declaration.name), node); + return setTextRange(getGeneratedNameForNode(getNameOfDeclaration(declaration)), node); } } diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index f831a09ac6f..65978409223 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -2918,7 +2918,7 @@ namespace ts { function visitExportDeclaration(node: ExportDeclaration): VisitResult { if (!node.exportClause) { // Elide a star export if the module it references does not export a value. - return resolver.moduleExportsSomeValue(node.moduleSpecifier) ? node : undefined; + return compilerOptions.isolatedModules || resolver.moduleExportsSomeValue(node.moduleSpecifier) ? node : undefined; } if (!resolver.isValueAliasDeclaration(node)) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 182b851e735..f6310d85a69 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -605,10 +605,13 @@ namespace ts { export interface Declaration extends Node { _declarationBrand: any; + } + + export interface NamedDeclaration extends Declaration { name?: DeclarationName; } - export interface DeclarationStatement extends Declaration, Statement { + export interface DeclarationStatement extends NamedDeclaration, Statement { name?: Identifier | StringLiteral | NumericLiteral; } @@ -622,7 +625,7 @@ namespace ts { expression: LeftHandSideExpression; } - export interface TypeParameterDeclaration extends Declaration { + export interface TypeParameterDeclaration extends NamedDeclaration { kind: SyntaxKind.TypeParameter; parent?: DeclarationWithTypeParameters; name: Identifier; @@ -633,7 +636,7 @@ namespace ts { expression?: Expression; } - export interface SignatureDeclaration extends Declaration { + export interface SignatureDeclaration extends NamedDeclaration { name?: PropertyName; typeParameters?: NodeArray; parameters: NodeArray; @@ -650,7 +653,7 @@ namespace ts { export type BindingName = Identifier | BindingPattern; - export interface VariableDeclaration extends Declaration { + export interface VariableDeclaration extends NamedDeclaration { kind: SyntaxKind.VariableDeclaration; parent?: VariableDeclarationList | CatchClause; name: BindingName; // Declared variable name @@ -664,7 +667,7 @@ namespace ts { declarations: NodeArray; } - export interface ParameterDeclaration extends Declaration { + export interface ParameterDeclaration extends NamedDeclaration { kind: SyntaxKind.Parameter; parent?: SignatureDeclaration; dotDotDotToken?: DotDotDotToken; // Present on rest parameter @@ -674,7 +677,7 @@ namespace ts { initializer?: Expression; // Optional initializer } - export interface BindingElement extends Declaration { + export interface BindingElement extends NamedDeclaration { kind: SyntaxKind.BindingElement; parent?: BindingPattern; propertyName?: PropertyName; // Binding property name (in object binding pattern) @@ -699,7 +702,7 @@ namespace ts { initializer?: Expression; // Optional initializer } - export interface ObjectLiteralElement extends Declaration { + export interface ObjectLiteralElement extends NamedDeclaration { _objectLiteralBrandBrand: any; name?: PropertyName; } @@ -743,7 +746,7 @@ namespace ts { // SyntaxKind.ShorthandPropertyAssignment // SyntaxKind.EnumMember // SyntaxKind.JSDocPropertyTag - export interface VariableLikeDeclaration extends Declaration { + export interface VariableLikeDeclaration extends NamedDeclaration { propertyName?: PropertyName; dotDotDotToken?: DotDotDotToken; name: DeclarationName; @@ -752,7 +755,7 @@ namespace ts { initializer?: Expression; } - export interface PropertyLikeDeclaration extends Declaration { + export interface PropertyLikeDeclaration extends NamedDeclaration { name: PropertyName; } @@ -1216,8 +1219,7 @@ namespace ts { export type BinaryOperatorToken = Token; - // Binary expressions can be declarations if they are 'exports.foo = bar' expressions in JS files - export interface BinaryExpression extends Expression, Declaration { + export interface BinaryExpression extends Expression, Declaration { kind: SyntaxKind.BinaryExpression; left: Expression; operatorToken: BinaryOperatorToken; @@ -1417,7 +1419,7 @@ namespace ts { export type EntityNameExpression = Identifier | PropertyAccessEntityNameExpression | ParenthesizedExpression; export type EntityNameOrEntityNameExpression = EntityName | EntityNameExpression; - export interface PropertyAccessExpression extends MemberExpression, Declaration { + export interface PropertyAccessExpression extends MemberExpression, NamedDeclaration { kind: SyntaxKind.PropertyAccessExpression; expression: LeftHandSideExpression; name: Identifier; @@ -1762,7 +1764,7 @@ namespace ts { export type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration; - export interface ClassLikeDeclaration extends Declaration { + export interface ClassLikeDeclaration extends NamedDeclaration { name?: Identifier; typeParameters?: NodeArray; heritageClauses?: NodeArray; @@ -1778,12 +1780,12 @@ namespace ts { kind: SyntaxKind.ClassExpression; } - export interface ClassElement extends Declaration { + export interface ClassElement extends NamedDeclaration { _classElementBrand: any; name?: PropertyName; } - export interface TypeElement extends Declaration { + export interface TypeElement extends NamedDeclaration { _typeElementBrand: any; name?: PropertyName; questionToken?: QuestionToken; @@ -1811,7 +1813,7 @@ namespace ts { type: TypeNode; } - export interface EnumMember extends Declaration { + export interface EnumMember extends NamedDeclaration { kind: SyntaxKind.EnumMember; parent?: EnumDeclaration; // This does include ComputedPropertyName, but the parser will give an error @@ -1900,14 +1902,14 @@ namespace ts { // import d, * as ns from "mod" => name = d, namedBinding: NamespaceImport = { name: ns } // import { a, b as x } from "mod" => name = undefined, namedBinding: NamedImports = { elements: [{ name: a }, { name: x, propertyName: b}]} // import d, { a, b as x } from "mod" => name = d, namedBinding: NamedImports = { elements: [{ name: a }, { name: x, propertyName: b}]} - export interface ImportClause extends Declaration { + export interface ImportClause extends NamedDeclaration { kind: SyntaxKind.ImportClause; parent?: ImportDeclaration; name?: Identifier; // Default binding namedBindings?: NamedImportBindings; } - export interface NamespaceImport extends Declaration { + export interface NamespaceImport extends NamedDeclaration { kind: SyntaxKind.NamespaceImport; parent?: ImportClause; name: Identifier; @@ -1940,14 +1942,14 @@ namespace ts { export type NamedImportsOrExports = NamedImports | NamedExports; - export interface ImportSpecifier extends Declaration { + export interface ImportSpecifier extends NamedDeclaration { kind: SyntaxKind.ImportSpecifier; parent?: NamedImports; propertyName?: Identifier; // Name preceding "as" keyword (or undefined when "as" is absent) name: Identifier; // Declared name } - export interface ExportSpecifier extends Declaration { + export interface ExportSpecifier extends NamedDeclaration { kind: SyntaxKind.ExportSpecifier; parent?: NamedExports; propertyName?: Identifier; // Name preceding "as" keyword (or undefined when "as" is absent) @@ -2113,7 +2115,7 @@ namespace ts { typeExpression: JSDocTypeExpression; } - export interface JSDocTypedefTag extends JSDocTag, Declaration { + export interface JSDocTypedefTag extends JSDocTag, NamedDeclaration { kind: SyntaxKind.JSDocTypedefTag; fullName?: JSDocNamespaceDeclaration | Identifier; name?: Identifier; @@ -3359,9 +3361,9 @@ namespace ts { } export interface Diagnostic { - file: SourceFile; - start: number; - length: number; + file: SourceFile | undefined; + start: number | undefined; + length: number | undefined; messageText: string | DiagnosticMessageChain; category: DiagnosticCategory; code: number; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 1ec182d9294..24fab4cd9f6 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -566,7 +566,7 @@ namespace ts { case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: case SyntaxKind.TypeAliasDeclaration: - errorNode = (node).name; + errorNode = (node).name; break; case SyntaxKind.ArrowFunction: return getErrorSpanForArrowFunction(sourceFile, node); @@ -1761,22 +1761,44 @@ namespace ts { // True if the given identifier, string literal, or number literal is the name of a declaration node export function isDeclarationName(name: Node): boolean { - if (name.kind !== SyntaxKind.Identifier && name.kind !== SyntaxKind.StringLiteral && name.kind !== SyntaxKind.NumericLiteral) { - return false; + switch (name.kind) { + case SyntaxKind.Identifier: + case SyntaxKind.StringLiteral: + case SyntaxKind.NumericLiteral: + return isDeclaration(name.parent) && name.parent.name === name; + default: + return false; } + } - const parent = name.parent; - if (parent.kind === SyntaxKind.ImportSpecifier || parent.kind === SyntaxKind.ExportSpecifier) { - if ((parent).propertyName) { - return true; + export function getNameOfDeclaration(declaration: Declaration): DeclarationName { + if (!declaration) { + return undefined; + } + if (declaration.kind === SyntaxKind.BinaryExpression) { + const kind = getSpecialPropertyAssignmentKind(declaration as BinaryExpression); + const lhs = (declaration as BinaryExpression).left; + switch (kind) { + case SpecialPropertyAssignmentKind.None: + case SpecialPropertyAssignmentKind.ModuleExports: + return undefined; + case SpecialPropertyAssignmentKind.ExportsProperty: + if (lhs.kind === SyntaxKind.Identifier) { + return (lhs as PropertyAccessExpression).name; + } + else { + return ((lhs as PropertyAccessExpression).expression as PropertyAccessExpression).name; + } + case SpecialPropertyAssignmentKind.ThisProperty: + case SpecialPropertyAssignmentKind.Property: + return (lhs as PropertyAccessExpression).name; + case SpecialPropertyAssignmentKind.PrototypeProperty: + return ((lhs as PropertyAccessExpression).expression as PropertyAccessExpression).name; } } - - if (isDeclaration(parent)) { - return (parent).name === name; + else { + return (declaration as NamedDeclaration).name; } - - return false; } export function isLiteralComputedPropertyDeclarationName(node: Node) { @@ -1799,7 +1821,7 @@ namespace ts { case SyntaxKind.PropertyAssignment: case SyntaxKind.PropertyAccessExpression: // Name in member declaration or property name in property access - return (parent).name === node; + return (parent).name === node; case SyntaxKind.QualifiedName: // Name on right hand side of dot in a type query if ((parent).right === node) { @@ -1997,7 +2019,8 @@ namespace ts { * Symbol. */ export function hasDynamicName(declaration: Declaration): boolean { - return declaration.name && isDynamicName(declaration.name); + const name = getNameOfDeclaration(declaration); + return name && isDynamicName(name); } export function isDynamicName(name: DeclarationName): boolean { @@ -2770,7 +2793,7 @@ namespace ts { forEach(declarations, (member: Declaration) => { if ((member.kind === SyntaxKind.GetAccessor || member.kind === SyntaxKind.SetAccessor) && hasModifier(member, ModifierFlags.Static) === hasModifier(accessor, ModifierFlags.Static)) { - const memberName = getPropertyNameForPropertyNameNode(member.name); + const memberName = getPropertyNameForPropertyNameNode((member as NamedDeclaration).name); const accessorName = getPropertyNameForPropertyNameNode(accessor.name); if (memberName === accessorName) { if (!firstAccessor) { @@ -4103,7 +4126,7 @@ namespace ts { || kind === SyntaxKind.MergeDeclarationMarker; } - export function isDeclaration(node: Node): node is Declaration { + export function isDeclaration(node: Node): node is NamedDeclaration { return isDeclarationKind(node.kind); } diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index a56d21ae345..83d27c951be 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -655,7 +655,7 @@ namespace FourSlash { ts.zipWith(endMarkers, definitions, (endMarker, definition, i) => { const marker = this.getMarkerByName(endMarker); if (marker.fileName !== definition.fileName || marker.position !== definition.textSpan.start) { - this.raiseError(`goToDefinition failed for definition ${i}: expected ${marker.fileName} at ${marker.position}, got ${definition.fileName} at ${definition.textSpan.start}`); + this.raiseError(`goToDefinition failed for definition ${endMarker} (${i}): expected ${marker.fileName} at ${marker.position}, got ${definition.fileName} at ${definition.textSpan.start}`); } }); } diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 9312e66cc48..957112016c4 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -63,7 +63,7 @@ namespace ts.codefix { const declaration = declarations[0] as Declaration; // Clone name to remove leading trivia. - const name = getSynthesizedClone(declaration.name); + const name = getSynthesizedClone(getNameOfDeclaration(declaration)) as PropertyName; const visibilityModifier = createVisibilityModifier(getModifierFlags(declaration)); const modifiers = visibilityModifier ? createNodeArray([visibilityModifier]) : undefined; const type = checker.getWidenedType(checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration)); @@ -231,4 +231,4 @@ namespace ts.codefix { } return undefined; } -} \ No newline at end of file +} diff --git a/src/services/completions.ts b/src/services/completions.ts index 3ec936d282f..318c02683ff 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1214,7 +1214,7 @@ namespace ts.Completions { // TODO(jfreeman): Account for computed property name // NOTE: if one only performs this step when m.name is an identifier, // things like '__proto__' are not filtered out. - existingName = (m.name).text; + existingName = (getNameOfDeclaration(m) as Identifier).text; } existingMemberNames.set(existingName, true); diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 40572b11d34..7be2229877a 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -899,7 +899,7 @@ namespace ts.FindAllReferences.Core { * position of property accessing, the referenceEntry of such position will be handled in the first case. */ if (!(flags & SymbolFlags.Transient) && search.includes(shorthandValueSymbol)) { - addReference(valueDeclaration.name, shorthandValueSymbol, search.location, state); + addReference(getNameOfDeclaration(valueDeclaration), shorthandValueSymbol, search.location, state); } } diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 5c2171cc4ae..d5bd33e33cc 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -487,7 +487,7 @@ namespace ts.formatting { // falls through case SyntaxKind.PropertyDeclaration: case SyntaxKind.Parameter: - return (node).name.kind; + return getNameOfDeclaration(node).kind; } } diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index f2602903be3..09d1f2a248c 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -235,7 +235,7 @@ namespace ts.GoToDefinition { /** Creates a DefinitionInfo from a Declaration, using the declaration's name if possible. */ function createDefinitionInfo(node: Declaration, symbolKind: string, symbolName: string, containerName: string): DefinitionInfo { - return createDefinitionInfoFromName(node.name || node, symbolKind, symbolName, containerName); + return createDefinitionInfoFromName(getNameOfDeclaration(node) || node, symbolKind, symbolName, containerName); } /** Creates a DefinitionInfo directly from the name of a declaration. */ diff --git a/src/services/importTracker.ts b/src/services/importTracker.ts index c94d5cc3143..df50f3ec31c 100644 --- a/src/services/importTracker.ts +++ b/src/services/importTracker.ts @@ -330,7 +330,7 @@ namespace ts.FindAllReferences { /** Calls `action` for each import, re-export, or require() in a file. */ function forEachImport(sourceFile: SourceFile, action: (importStatement: ImporterOrCallExpression, imported: StringLiteral) => void): void { - if (sourceFile.externalModuleIndicator) { + if (sourceFile.externalModuleIndicator || sourceFile.imports !== undefined) { for (const moduleSpecifier of sourceFile.imports) { action(importerFromModuleSpecifier(moduleSpecifier), moduleSpecifier); } @@ -358,27 +358,21 @@ namespace ts.FindAllReferences { } } }); - - if (sourceFile.flags & NodeFlags.JavaScriptFile) { - // Find all 'require()' calls. - sourceFile.forEachChild(function recur(node: Node): void { - if (isRequireCall(node, /*checkArgumentIsStringLiteral*/ true)) { - action(node, node.arguments[0] as StringLiteral); - } else { - node.forEachChild(recur); - } - }); - } } } - function importerFromModuleSpecifier(moduleSpecifier: StringLiteral): Importer { + function importerFromModuleSpecifier(moduleSpecifier: StringLiteral): ImporterOrCallExpression { const decl = moduleSpecifier.parent; - if (decl.kind === SyntaxKind.ImportDeclaration || decl.kind === SyntaxKind.ExportDeclaration) { - return decl as ImportDeclaration | ExportDeclaration; + switch (decl.kind) { + case SyntaxKind.CallExpression: + case SyntaxKind.ImportDeclaration: + case SyntaxKind.ExportDeclaration: + return decl as ImportDeclaration | ExportDeclaration | CallExpression; + case SyntaxKind.ExternalModuleReference: + return (decl as ExternalModuleReference).parent; + default: + Debug.assert(false); } - Debug.assert(decl.kind === SyntaxKind.ExternalModuleReference); - return (decl as ExternalModuleReference).parent; } export interface ImportedSymbol { @@ -537,7 +531,10 @@ namespace ts.FindAllReferences { return symbol.name; } - const name = forEach(symbol.declarations, ({ name }) => name && name.kind === SyntaxKind.Identifier && name.text); + const name = forEach(symbol.declarations, decl => { + const name = getNameOfDeclaration(decl); + return name && name.kind === SyntaxKind.Identifier && name.text; + }); Debug.assert(!!name); return name; } diff --git a/src/services/navigateTo.ts b/src/services/navigateTo.ts index 2c8d43b535b..2fdc567b9bb 100644 --- a/src/services/navigateTo.ts +++ b/src/services/navigateTo.ts @@ -52,7 +52,7 @@ namespace ts.NavigateTo { rawItems = filter(rawItems, item => { const decl = item.declaration; if (decl.kind === SyntaxKind.ImportClause || decl.kind === SyntaxKind.ImportSpecifier || decl.kind === SyntaxKind.ImportEqualsDeclaration) { - const importer = checker.getSymbolAtLocation(decl.name); + const importer = checker.getSymbolAtLocation((decl as NamedDeclaration).name); const imported = checker.getAliasedSymbol(importer); return importer.name !== imported.name; } @@ -97,17 +97,20 @@ namespace ts.NavigateTo { } function tryAddSingleDeclarationName(declaration: Declaration, containers: string[]) { - if (declaration && declaration.name) { - const text = getTextOfIdentifierOrLiteral(declaration.name); - if (text !== undefined) { - containers.unshift(text); - } - else if (declaration.name.kind === SyntaxKind.ComputedPropertyName) { - return tryAddComputedPropertyName((declaration.name).expression, containers, /*includeLastPortion*/ true); - } - else { - // Don't know how to add this. - return false; + if (declaration) { + const name = getNameOfDeclaration(declaration); + if (name) { + const text = getTextOfIdentifierOrLiteral(name); + if (text !== undefined) { + containers.unshift(text); + } + else if (name.kind === SyntaxKind.ComputedPropertyName) { + return tryAddComputedPropertyName((name).expression, containers, /*includeLastPortion*/ true); + } + else { + // Don't know how to add this. + return false; + } } } @@ -143,8 +146,9 @@ namespace ts.NavigateTo { // First, if we started with a computed property name, then add all but the last // portion into the container array. - if (declaration.name.kind === SyntaxKind.ComputedPropertyName) { - if (!tryAddComputedPropertyName((declaration.name).expression, containers, /*includeLastPortion*/ false)) { + const name = getNameOfDeclaration(declaration); + if (name.kind === SyntaxKind.ComputedPropertyName) { + if (!tryAddComputedPropertyName((name).expression, containers, /*includeLastPortion*/ false)) { return undefined; } } @@ -190,6 +194,7 @@ namespace ts.NavigateTo { function createNavigateToItem(rawItem: RawNavigateToItem): NavigateToItem { const declaration = rawItem.declaration; const container = getContainerNode(declaration); + const containerName = container && getNameOfDeclaration(container); return { name: rawItem.name, kind: getNodeKind(declaration), @@ -199,9 +204,9 @@ namespace ts.NavigateTo { fileName: rawItem.fileName, textSpan: createTextSpanFromNode(declaration), // TODO(jfreeman): What should be the containerName when the container has a computed name? - containerName: container && container.name ? (container.name).text : "", - containerKind: container && container.name ? getNodeKind(container) : "" + containerName: containerName ? (containerName).text : "", + containerKind: containerName ? getNodeKind(container) : "" }; } } -} \ No newline at end of file +} diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 7a2508fcfd6..819202ff6f4 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -279,8 +279,8 @@ namespace ts.NavigationBar { function mergeChildren(children: NavigationBarNode[]): void { const nameToItems = createMap(); filterMutate(children, child => { - const decl = child.node; - const name = decl.name && nodeText(decl.name); + const declName = getNameOfDeclaration(child.node); + const name = declName && nodeText(declName); if (!name) { // Anonymous items are never merged. return true; @@ -378,9 +378,9 @@ namespace ts.NavigationBar { return getModuleName(node); } - const decl = node; - if (decl.name) { - return getPropertyNameForPropertyNameNode(decl.name); + const declName = getNameOfDeclaration(node); + if (declName) { + return getPropertyNameForPropertyNameNode(declName); } switch (node.kind) { case SyntaxKind.FunctionExpression: @@ -399,7 +399,7 @@ namespace ts.NavigationBar { return getModuleName(node); } - const name = (node).name; + const name = getNameOfDeclaration(node); if (name) { const text = nodeText(name); if (text.length > 0) { diff --git a/src/services/services.ts b/src/services/services.ts index a99774f7958..6eccfd42ddd 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -578,14 +578,15 @@ namespace ts { } function getDeclarationName(declaration: Declaration) { - if (declaration.name) { - const result = getTextOfIdentifierOrLiteral(declaration.name); + const name = getNameOfDeclaration(declaration); + if (name) { + const result = getTextOfIdentifierOrLiteral(name); if (result !== undefined) { return result; } - if (declaration.name.kind === SyntaxKind.ComputedPropertyName) { - const expr = (declaration.name).expression; + if (name.kind === SyntaxKind.ComputedPropertyName) { + const expr = (name).expression; if (expr.kind === SyntaxKind.PropertyAccessExpression) { return (expr).name.text; } diff --git a/src/services/shims.ts b/src/services/shims.ts index e8513074361..32db56fa0d9 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -1038,7 +1038,11 @@ namespace ts { return this.forwardJSONCall(`resolveModuleName('${fileName}')`, () => { const compilerOptions = JSON.parse(compilerOptionsJson); const result = resolveModuleName(moduleName, normalizeSlashes(fileName), compilerOptions, this.host); - const resolvedFileName = result.resolvedModule ? result.resolvedModule.resolvedFileName : undefined; + let resolvedFileName = result.resolvedModule ? result.resolvedModule.resolvedFileName : undefined; + if (result.resolvedModule && result.resolvedModule.extension !== Extension.Ts && result.resolvedModule.extension !== Extension.Tsx && result.resolvedModule.extension !== Extension.Dts) { + resolvedFileName = undefined; + } + return { resolvedFileName, failedLookupLocations: result.failedLookupLocations diff --git a/src/services/utilities.ts b/src/services/utilities.ts index c604fd13df3..ba593fd1caa 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -21,7 +21,6 @@ namespace ts { case SyntaxKind.PropertySignature: case SyntaxKind.PropertyAssignment: case SyntaxKind.ShorthandPropertyAssignment: - case SyntaxKind.EnumMember: case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: case SyntaxKind.Constructor: @@ -40,10 +39,13 @@ namespace ts { case SyntaxKind.TypeLiteral: return SemanticMeaning.Type; + case SyntaxKind.EnumMember: case SyntaxKind.ClassDeclaration: - case SyntaxKind.EnumDeclaration: return SemanticMeaning.Value | SemanticMeaning.Type; + case SyntaxKind.EnumDeclaration: + return SemanticMeaning.All; + case SyntaxKind.ModuleDeclaration: if (isAmbientModule(node)) { return SemanticMeaning.Namespace | SemanticMeaning.Value; @@ -61,7 +63,7 @@ namespace ts { case SyntaxKind.ImportDeclaration: case SyntaxKind.ExportAssignment: case SyntaxKind.ExportDeclaration: - return SemanticMeaning.Value | SemanticMeaning.Type | SemanticMeaning.Namespace; + return SemanticMeaning.All; // An external module can be a Value case SyntaxKind.SourceFile: @@ -238,7 +240,7 @@ namespace ts { case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: case SyntaxKind.ModuleDeclaration: - return (node.parent).name === node; + return getNameOfDeclaration(node.parent) === node; case SyntaxKind.ElementAccessExpression: return (node.parent).argumentExpression === node; case SyntaxKind.ComputedPropertyName: diff --git a/tests/baselines/reference/APISample_compile.js b/tests/baselines/reference/APISample_compile.js index c2617b2a6c6..35d49350457 100644 --- a/tests/baselines/reference/APISample_compile.js +++ b/tests/baselines/reference/APISample_compile.js @@ -1,6 +1,6 @@ //// [APISample_compile.ts] /* - * Note: This test is a public API sample. The sample sources can be found + * Note: This test is a public API sample. The sample sources can be found at: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#a-minimal-compiler * Please log a "breaking change" issue for any API breaking change affecting this issue */ @@ -18,8 +18,12 @@ export function compile(fileNames: string[], options: ts.CompilerOptions): void var allDiagnostics = ts.getPreEmitDiagnostics(program); allDiagnostics.forEach(diagnostic => { - var { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start); var message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'); + if (!diagnostic.file) { + console.log(message); + return; + } + var { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!); console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`); }); @@ -31,7 +35,8 @@ export function compile(fileNames: string[], options: ts.CompilerOptions): void compile(process.argv.slice(2), { noEmitOnError: true, noImplicitAny: true, target: ts.ScriptTarget.ES5, module: ts.ModuleKind.CommonJS -}); +}); + //// [APISample_compile.js] "use strict"; @@ -47,8 +52,12 @@ function compile(fileNames, options) { var emitResult = program.emit(); var allDiagnostics = ts.getPreEmitDiagnostics(program); allDiagnostics.forEach(function (diagnostic) { - var _a = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start), line = _a.line, character = _a.character; var message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'); + if (!diagnostic.file) { + console.log(message); + return; + } + var _a = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start), line = _a.line, character = _a.character; console.log(diagnostic.file.fileName + " (" + (line + 1) + "," + (character + 1) + "): " + message); }); var exitCode = emitResult.emitSkipped ? 1 : 0; diff --git a/tests/baselines/reference/APISample_watcher.js b/tests/baselines/reference/APISample_watcher.js index f06f9ced73f..b813a44f53e 100644 --- a/tests/baselines/reference/APISample_watcher.js +++ b/tests/baselines/reference/APISample_watcher.js @@ -1,6 +1,6 @@ //// [APISample_watcher.ts] /* - * Note: This test is a public API sample. The sample sources can be found + * Note: This test is a public API sample. The sample sources can be found at: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#incremental-build-support-using-the-language-services * Please log a "breaking change" issue for any API breaking change affecting this issue */ @@ -91,7 +91,7 @@ function watch(rootFileNames: string[], options: ts.CompilerOptions) { allDiagnostics.forEach(diagnostic => { let message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n"); if (diagnostic.file) { - let { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start); + let { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!); console.log(` Error ${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`); } else { @@ -106,7 +106,8 @@ const currentDirectoryFiles = fs.readdirSync(process.cwd()). filter(fileName=> fileName.length >= 3 && fileName.substr(fileName.length - 3, 3) === ".ts"); // Start the watcher -watch(currentDirectoryFiles, { module: ts.ModuleKind.CommonJS }); +watch(currentDirectoryFiles, { module: ts.ModuleKind.CommonJS }); + //// [APISample_watcher.js] "use strict"; diff --git a/tests/baselines/reference/checkJsFiles_noErrorLocation.errors.txt b/tests/baselines/reference/checkJsFiles_noErrorLocation.errors.txt index 758b295a49d..d9104608284 100644 --- a/tests/baselines/reference/checkJsFiles_noErrorLocation.errors.txt +++ b/tests/baselines/reference/checkJsFiles_noErrorLocation.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/a.js(14,5): error TS2424: Class 'A' defines instance member function 'foo', but extended class 'B' defines it as instance member property. +tests/cases/compiler/a.js(14,10): error TS2424: Class 'A' defines instance member function 'foo', but extended class 'B' defines it as instance member property. ==== tests/cases/compiler/a.js (1 errors) ==== @@ -16,7 +16,7 @@ tests/cases/compiler/a.js(14,5): error TS2424: Class 'A' defines instance member constructor() { super(); this.foo = () => 3; - ~~~~~~~~~~~~~~~~~~ + ~~~ !!! error TS2424: Class 'A' defines instance member function 'foo', but extended class 'B' defines it as instance member property. } } diff --git a/tests/baselines/reference/classConstructorAccessibility.js b/tests/baselines/reference/classConstructorAccessibility.js index 46a548d0b54..4d120a3980f 100644 --- a/tests/baselines/reference/classConstructorAccessibility.js +++ b/tests/baselines/reference/classConstructorAccessibility.js @@ -89,7 +89,7 @@ declare class C { } declare class D { x: number; - private constructor(x); + private constructor(); } declare class E { x: number; diff --git a/tests/baselines/reference/classConstructorAccessibility2.js b/tests/baselines/reference/classConstructorAccessibility2.js index 7297af11a4e..76c8ea19110 100644 --- a/tests/baselines/reference/classConstructorAccessibility2.js +++ b/tests/baselines/reference/classConstructorAccessibility2.js @@ -135,7 +135,7 @@ declare class BaseB { } declare class BaseC { x: number; - private constructor(x); + private constructor(); createInstance(): void; static staticInstance(): void; } diff --git a/tests/baselines/reference/classConstructorAccessibility3.js b/tests/baselines/reference/classConstructorAccessibility3.js index 3e024970bcf..d1bd8f38c40 100644 --- a/tests/baselines/reference/classConstructorAccessibility3.js +++ b/tests/baselines/reference/classConstructorAccessibility3.js @@ -90,7 +90,7 @@ declare class Baz { } declare class Qux { x: number; - private constructor(x); + private constructor(); } declare let a: typeof Foo; declare let b: typeof Baz; diff --git a/tests/baselines/reference/classConstructorOverloadsAccessibility.js b/tests/baselines/reference/classConstructorOverloadsAccessibility.js index 7fef7443c62..2a173966d5d 100644 --- a/tests/baselines/reference/classConstructorOverloadsAccessibility.js +++ b/tests/baselines/reference/classConstructorOverloadsAccessibility.js @@ -59,7 +59,7 @@ var D = (function () { declare class A { constructor(a: boolean); protected constructor(a: number); - private constructor(a); + private constructor(); } declare class B { protected constructor(a: number); diff --git a/tests/baselines/reference/declarationEmitClassPrivateConstructor.js b/tests/baselines/reference/declarationEmitClassPrivateConstructor.js new file mode 100644 index 00000000000..6cc65964987 --- /dev/null +++ b/tests/baselines/reference/declarationEmitClassPrivateConstructor.js @@ -0,0 +1,72 @@ +//// [declarationEmitClassPrivateConstructor.ts] +interface PrivateInterface { +} + +export class ExportedClass1 { + private constructor(data: PrivateInterface) { } +} + +export class ExportedClass2 { + private constructor(private data: PrivateInterface) { } +} + +export class ExportedClass3 { + private constructor(private data: PrivateInterface, private n: number) { } +} + +export class ExportedClass4 { + private constructor(private data: PrivateInterface, public n:number) { } +} + +//// [declarationEmitClassPrivateConstructor.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var ExportedClass1 = (function () { + function ExportedClass1(data) { + } + return ExportedClass1; +}()); +exports.ExportedClass1 = ExportedClass1; +var ExportedClass2 = (function () { + function ExportedClass2(data) { + this.data = data; + } + return ExportedClass2; +}()); +exports.ExportedClass2 = ExportedClass2; +var ExportedClass3 = (function () { + function ExportedClass3(data, n) { + this.data = data; + this.n = n; + } + return ExportedClass3; +}()); +exports.ExportedClass3 = ExportedClass3; +var ExportedClass4 = (function () { + function ExportedClass4(data, n) { + this.data = data; + this.n = n; + } + return ExportedClass4; +}()); +exports.ExportedClass4 = ExportedClass4; + + +//// [declarationEmitClassPrivateConstructor.d.ts] +export declare class ExportedClass1 { + private constructor(); +} +export declare class ExportedClass2 { + private data; + private constructor(); +} +export declare class ExportedClass3 { + private data; + private n; + private constructor(); +} +export declare class ExportedClass4 { + private data; + n: number; + private constructor(); +} diff --git a/tests/baselines/reference/declarationEmitClassPrivateConstructor.symbols b/tests/baselines/reference/declarationEmitClassPrivateConstructor.symbols new file mode 100644 index 00000000000..285d9fb3f39 --- /dev/null +++ b/tests/baselines/reference/declarationEmitClassPrivateConstructor.symbols @@ -0,0 +1,38 @@ +=== tests/cases/compiler/declarationEmitClassPrivateConstructor.ts === +interface PrivateInterface { +>PrivateInterface : Symbol(PrivateInterface, Decl(declarationEmitClassPrivateConstructor.ts, 0, 0)) +} + +export class ExportedClass1 { +>ExportedClass1 : Symbol(ExportedClass1, Decl(declarationEmitClassPrivateConstructor.ts, 1, 1)) + + private constructor(data: PrivateInterface) { } +>data : Symbol(data, Decl(declarationEmitClassPrivateConstructor.ts, 4, 24)) +>PrivateInterface : Symbol(PrivateInterface, Decl(declarationEmitClassPrivateConstructor.ts, 0, 0)) +} + +export class ExportedClass2 { +>ExportedClass2 : Symbol(ExportedClass2, Decl(declarationEmitClassPrivateConstructor.ts, 5, 1)) + + private constructor(private data: PrivateInterface) { } +>data : Symbol(ExportedClass2.data, Decl(declarationEmitClassPrivateConstructor.ts, 8, 24)) +>PrivateInterface : Symbol(PrivateInterface, Decl(declarationEmitClassPrivateConstructor.ts, 0, 0)) +} + +export class ExportedClass3 { +>ExportedClass3 : Symbol(ExportedClass3, Decl(declarationEmitClassPrivateConstructor.ts, 9, 1)) + + private constructor(private data: PrivateInterface, private n: number) { } +>data : Symbol(ExportedClass3.data, Decl(declarationEmitClassPrivateConstructor.ts, 12, 24)) +>PrivateInterface : Symbol(PrivateInterface, Decl(declarationEmitClassPrivateConstructor.ts, 0, 0)) +>n : Symbol(ExportedClass3.n, Decl(declarationEmitClassPrivateConstructor.ts, 12, 55)) +} + +export class ExportedClass4 { +>ExportedClass4 : Symbol(ExportedClass4, Decl(declarationEmitClassPrivateConstructor.ts, 13, 1)) + + private constructor(private data: PrivateInterface, public n:number) { } +>data : Symbol(ExportedClass4.data, Decl(declarationEmitClassPrivateConstructor.ts, 16, 24)) +>PrivateInterface : Symbol(PrivateInterface, Decl(declarationEmitClassPrivateConstructor.ts, 0, 0)) +>n : Symbol(ExportedClass4.n, Decl(declarationEmitClassPrivateConstructor.ts, 16, 55)) +} diff --git a/tests/baselines/reference/declarationEmitClassPrivateConstructor.types b/tests/baselines/reference/declarationEmitClassPrivateConstructor.types new file mode 100644 index 00000000000..ed8d5494ba6 --- /dev/null +++ b/tests/baselines/reference/declarationEmitClassPrivateConstructor.types @@ -0,0 +1,38 @@ +=== tests/cases/compiler/declarationEmitClassPrivateConstructor.ts === +interface PrivateInterface { +>PrivateInterface : PrivateInterface +} + +export class ExportedClass1 { +>ExportedClass1 : ExportedClass1 + + private constructor(data: PrivateInterface) { } +>data : PrivateInterface +>PrivateInterface : PrivateInterface +} + +export class ExportedClass2 { +>ExportedClass2 : ExportedClass2 + + private constructor(private data: PrivateInterface) { } +>data : PrivateInterface +>PrivateInterface : PrivateInterface +} + +export class ExportedClass3 { +>ExportedClass3 : ExportedClass3 + + private constructor(private data: PrivateInterface, private n: number) { } +>data : PrivateInterface +>PrivateInterface : PrivateInterface +>n : number +} + +export class ExportedClass4 { +>ExportedClass4 : ExportedClass4 + + private constructor(private data: PrivateInterface, public n:number) { } +>data : PrivateInterface +>PrivateInterface : PrivateInterface +>n : number +} diff --git a/tests/baselines/reference/declarationEmitClassPrivateConstructor2.errors.txt b/tests/baselines/reference/declarationEmitClassPrivateConstructor2.errors.txt new file mode 100644 index 00000000000..a31454a4760 --- /dev/null +++ b/tests/baselines/reference/declarationEmitClassPrivateConstructor2.errors.txt @@ -0,0 +1,20 @@ +tests/cases/compiler/declarationEmitClassPrivateConstructor2.ts(5,38): error TS4031: Public property 'data' of exported class has or is using private name 'PrivateInterface'. +tests/cases/compiler/declarationEmitClassPrivateConstructor2.ts(10,33): error TS4063: Parameter 'data' of constructor from exported class has or is using private name 'PrivateInterface'. + + +==== tests/cases/compiler/declarationEmitClassPrivateConstructor2.ts (2 errors) ==== + interface PrivateInterface { + } + + export class ExportedClass1 { + private constructor(public data: PrivateInterface) { } + ~~~~~~~~~~~~~~~~ +!!! error TS4031: Public property 'data' of exported class has or is using private name 'PrivateInterface'. + } + + + export class ExportedClass2 { + protected constructor(data: PrivateInterface) { } + ~~~~~~~~~~~~~~~~ +!!! error TS4063: Parameter 'data' of constructor from exported class has or is using private name 'PrivateInterface'. + } \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmitClassPrivateConstructor2.js b/tests/baselines/reference/declarationEmitClassPrivateConstructor2.js new file mode 100644 index 00000000000..8b7ad25a6bf --- /dev/null +++ b/tests/baselines/reference/declarationEmitClassPrivateConstructor2.js @@ -0,0 +1,29 @@ +//// [declarationEmitClassPrivateConstructor2.ts] +interface PrivateInterface { +} + +export class ExportedClass1 { + private constructor(public data: PrivateInterface) { } +} + + +export class ExportedClass2 { + protected constructor(data: PrivateInterface) { } +} + +//// [declarationEmitClassPrivateConstructor2.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var ExportedClass1 = (function () { + function ExportedClass1(data) { + this.data = data; + } + return ExportedClass1; +}()); +exports.ExportedClass1 = ExportedClass1; +var ExportedClass2 = (function () { + function ExportedClass2(data) { + } + return ExportedClass2; +}()); +exports.ExportedClass2 = ExportedClass2; diff --git a/tests/baselines/reference/declarationEmitExpressionInExtends5.js b/tests/baselines/reference/declarationEmitExpressionInExtends5.js new file mode 100644 index 00000000000..77f8fc0e12c --- /dev/null +++ b/tests/baselines/reference/declarationEmitExpressionInExtends5.js @@ -0,0 +1,67 @@ +//// [declarationEmitExpressionInExtends5.ts] +namespace Test +{ + export interface IFace + { + } + + export class SomeClass implements IFace + { + } + + export class Derived extends getClass() + { + } + + export function getClass() : new() => T + { + return SomeClass as (new() => T); + } +} + + +//// [declarationEmitExpressionInExtends5.js] +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var Test; +(function (Test) { + var SomeClass = (function () { + function SomeClass() { + } + return SomeClass; + }()); + Test.SomeClass = SomeClass; + var Derived = (function (_super) { + __extends(Derived, _super); + function Derived() { + return _super !== null && _super.apply(this, arguments) || this; + } + return Derived; + }(getClass())); + Test.Derived = Derived; + function getClass() { + return SomeClass; + } + Test.getClass = getClass; +})(Test || (Test = {})); + + +//// [declarationEmitExpressionInExtends5.d.ts] +declare namespace Test { + interface IFace { + } + class SomeClass implements IFace { + } + const Derived_base: new () => IFace; + class Derived extends Derived_base { + } + function getClass(): new () => T; +} diff --git a/tests/baselines/reference/declarationEmitExpressionInExtends5.symbols b/tests/baselines/reference/declarationEmitExpressionInExtends5.symbols new file mode 100644 index 00000000000..42bf5892211 --- /dev/null +++ b/tests/baselines/reference/declarationEmitExpressionInExtends5.symbols @@ -0,0 +1,33 @@ +=== tests/cases/compiler/declarationEmitExpressionInExtends5.ts === +namespace Test +>Test : Symbol(Test, Decl(declarationEmitExpressionInExtends5.ts, 0, 0)) +{ + export interface IFace +>IFace : Symbol(IFace, Decl(declarationEmitExpressionInExtends5.ts, 1, 1)) + { + } + + export class SomeClass implements IFace +>SomeClass : Symbol(SomeClass, Decl(declarationEmitExpressionInExtends5.ts, 4, 2)) +>IFace : Symbol(IFace, Decl(declarationEmitExpressionInExtends5.ts, 1, 1)) + { + } + + export class Derived extends getClass() +>Derived : Symbol(Derived, Decl(declarationEmitExpressionInExtends5.ts, 8, 2)) +>getClass : Symbol(getClass, Decl(declarationEmitExpressionInExtends5.ts, 12, 2)) +>IFace : Symbol(IFace, Decl(declarationEmitExpressionInExtends5.ts, 1, 1)) + { + } + + export function getClass() : new() => T +>getClass : Symbol(getClass, Decl(declarationEmitExpressionInExtends5.ts, 12, 2)) +>T : Symbol(T, Decl(declarationEmitExpressionInExtends5.ts, 14, 26)) +>T : Symbol(T, Decl(declarationEmitExpressionInExtends5.ts, 14, 26)) + { + return SomeClass as (new() => T); +>SomeClass : Symbol(SomeClass, Decl(declarationEmitExpressionInExtends5.ts, 4, 2)) +>T : Symbol(T, Decl(declarationEmitExpressionInExtends5.ts, 14, 26)) + } +} + diff --git a/tests/baselines/reference/declarationEmitExpressionInExtends5.types b/tests/baselines/reference/declarationEmitExpressionInExtends5.types new file mode 100644 index 00000000000..22aafb85e58 --- /dev/null +++ b/tests/baselines/reference/declarationEmitExpressionInExtends5.types @@ -0,0 +1,35 @@ +=== tests/cases/compiler/declarationEmitExpressionInExtends5.ts === +namespace Test +>Test : typeof Test +{ + export interface IFace +>IFace : IFace + { + } + + export class SomeClass implements IFace +>SomeClass : SomeClass +>IFace : IFace + { + } + + export class Derived extends getClass() +>Derived : Derived +>getClass() : IFace +>getClass : () => new () => T +>IFace : IFace + { + } + + export function getClass() : new() => T +>getClass : () => new () => T +>T : T +>T : T + { + return SomeClass as (new() => T); +>SomeClass as (new() => T) : new () => T +>SomeClass : typeof SomeClass +>T : T + } +} + diff --git a/tests/baselines/reference/es6ExportEqualsInterop.errors.txt b/tests/baselines/reference/es6ExportEqualsInterop.errors.txt index 4a9f7dcb506..4675136d081 100644 --- a/tests/baselines/reference/es6ExportEqualsInterop.errors.txt +++ b/tests/baselines/reference/es6ExportEqualsInterop.errors.txt @@ -14,11 +14,20 @@ tests/cases/compiler/main.ts(36,8): error TS1192: Module '"class-module"' has no tests/cases/compiler/main.ts(39,21): error TS2497: Module '"interface"' resolves to a non-module entity and cannot be imported using this construct. tests/cases/compiler/main.ts(45,21): error TS2497: Module '"function"' resolves to a non-module entity and cannot be imported using this construct. tests/cases/compiler/main.ts(47,21): error TS2497: Module '"class"' resolves to a non-module entity and cannot be imported using this construct. +tests/cases/compiler/main.ts(50,1): error TS2693: 'y1' only refers to a type, but is being used as a value here. +tests/cases/compiler/main.ts(56,4): error TS2339: Property 'a' does not exist on type '() => any'. +tests/cases/compiler/main.ts(58,4): error TS2339: Property 'a' does not exist on type 'typeof Foo'. +tests/cases/compiler/main.ts(62,10): error TS2305: Module '"interface"' has no exported member 'a'. tests/cases/compiler/main.ts(62,25): error TS2497: Module '"interface"' resolves to a non-module entity and cannot be imported using this construct. +tests/cases/compiler/main.ts(68,10): error TS2305: Module '"function"' has no exported member 'a'. tests/cases/compiler/main.ts(68,25): error TS2497: Module '"function"' resolves to a non-module entity and cannot be imported using this construct. +tests/cases/compiler/main.ts(70,10): error TS2305: Module '"class"' has no exported member 'a'. tests/cases/compiler/main.ts(70,25): error TS2497: Module '"class"' resolves to a non-module entity and cannot be imported using this construct. +tests/cases/compiler/main.ts(85,10): error TS2305: Module '"interface"' has no exported member 'a'. tests/cases/compiler/main.ts(85,25): error TS2497: Module '"interface"' resolves to a non-module entity and cannot be imported using this construct. +tests/cases/compiler/main.ts(91,10): error TS2305: Module '"function"' has no exported member 'a'. tests/cases/compiler/main.ts(91,25): error TS2497: Module '"function"' resolves to a non-module entity and cannot be imported using this construct. +tests/cases/compiler/main.ts(93,10): error TS2305: Module '"class"' has no exported member 'a'. tests/cases/compiler/main.ts(93,25): error TS2497: Module '"class"' resolves to a non-module entity and cannot be imported using this construct. tests/cases/compiler/main.ts(97,15): error TS2498: Module '"interface"' uses 'export =' and cannot be used with 'export *'. tests/cases/compiler/main.ts(98,15): error TS2498: Module '"variable"' uses 'export =' and cannot be used with 'export *'. @@ -32,7 +41,7 @@ tests/cases/compiler/main.ts(105,15): error TS2498: Module '"class"' uses 'expor tests/cases/compiler/main.ts(106,15): error TS2498: Module '"class-module"' uses 'export =' and cannot be used with 'export *'. -==== tests/cases/compiler/main.ts (32 errors) ==== +==== tests/cases/compiler/main.ts (41 errors) ==== /// // import-equals @@ -115,18 +124,26 @@ tests/cases/compiler/main.ts(106,15): error TS2498: Module '"class-module"' uses import * as y0 from "class-module"; y1.a; + ~~ +!!! error TS2693: 'y1' only refers to a type, but is being used as a value here. y2.a; y3.a; y4.a; y5.a; y6.a; y7.a; + ~ +!!! error TS2339: Property 'a' does not exist on type '() => any'. y8.a; y9.a; + ~ +!!! error TS2339: Property 'a' does not exist on type 'typeof Foo'. y0.a; // named import import { a as a1 } from "interface"; + ~ +!!! error TS2305: Module '"interface"' has no exported member 'a'. ~~~~~~~~~~~ !!! error TS2497: Module '"interface"' resolves to a non-module entity and cannot be imported using this construct. import { a as a2 } from "variable"; @@ -135,10 +152,14 @@ tests/cases/compiler/main.ts(106,15): error TS2498: Module '"class-module"' uses import { a as a5 } from "interface-module"; import { a as a6 } from "variable-module"; import { a as a7 } from "function"; + ~ +!!! error TS2305: Module '"function"' has no exported member 'a'. ~~~~~~~~~~ !!! error TS2497: Module '"function"' resolves to a non-module entity and cannot be imported using this construct. import { a as a8 } from "function-module"; import { a as a9 } from "class"; + ~ +!!! error TS2305: Module '"class"' has no exported member 'a'. ~~~~~~~ !!! error TS2497: Module '"class"' resolves to a non-module entity and cannot be imported using this construct. import { a as a0 } from "class-module"; @@ -156,6 +177,8 @@ tests/cases/compiler/main.ts(106,15): error TS2498: Module '"class-module"' uses // named export export { a as a1 } from "interface"; + ~ +!!! error TS2305: Module '"interface"' has no exported member 'a'. ~~~~~~~~~~~ !!! error TS2497: Module '"interface"' resolves to a non-module entity and cannot be imported using this construct. export { a as a2 } from "variable"; @@ -164,10 +187,14 @@ tests/cases/compiler/main.ts(106,15): error TS2498: Module '"class-module"' uses export { a as a5 } from "interface-module"; export { a as a6 } from "variable-module"; export { a as a7 } from "function"; + ~ +!!! error TS2305: Module '"function"' has no exported member 'a'. ~~~~~~~~~~ !!! error TS2497: Module '"function"' resolves to a non-module entity and cannot be imported using this construct. export { a as a8 } from "function-module"; export { a as a9 } from "class"; + ~ +!!! error TS2305: Module '"class"' has no exported member 'a'. ~~~~~~~ !!! error TS2497: Module '"class"' resolves to a non-module entity and cannot be imported using this construct. export { a as a0 } from "class-module"; diff --git a/tests/baselines/reference/es6ExportEqualsInterop.js b/tests/baselines/reference/es6ExportEqualsInterop.js index 5e04221df8b..13908a29e2d 100644 --- a/tests/baselines/reference/es6ExportEqualsInterop.js +++ b/tests/baselines/reference/es6ExportEqualsInterop.js @@ -232,8 +232,6 @@ z7.a; z8.a; z9.a; z0.a; -// namespace import -var y1 = require("interface"); var y2 = require("variable"); var y3 = require("interface-variable"); var y4 = require("module"); diff --git a/tests/baselines/reference/isolatedModulesDontElideReExportStar.js b/tests/baselines/reference/isolatedModulesDontElideReExportStar.js new file mode 100644 index 00000000000..4d546135f74 --- /dev/null +++ b/tests/baselines/reference/isolatedModulesDontElideReExportStar.js @@ -0,0 +1,12 @@ +//// [tests/cases/compiler/isolatedModulesDontElideReExportStar.ts] //// + +//// [a.ts] +export type T = number; + +//// [b.ts] +export * from "./a"; + + +//// [a.js] +//// [b.js] +export * from "./a"; diff --git a/tests/baselines/reference/isolatedModulesDontElideReExportStar.symbols b/tests/baselines/reference/isolatedModulesDontElideReExportStar.symbols new file mode 100644 index 00000000000..38ab78bf498 --- /dev/null +++ b/tests/baselines/reference/isolatedModulesDontElideReExportStar.symbols @@ -0,0 +1,8 @@ +=== /a.ts === +export type T = number; +>T : Symbol(T, Decl(a.ts, 0, 0)) + +=== /b.ts === +export * from "./a"; +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/isolatedModulesDontElideReExportStar.types b/tests/baselines/reference/isolatedModulesDontElideReExportStar.types new file mode 100644 index 00000000000..4f68c5ded89 --- /dev/null +++ b/tests/baselines/reference/isolatedModulesDontElideReExportStar.types @@ -0,0 +1,8 @@ +=== /a.ts === +export type T = number; +>T : number + +=== /b.ts === +export * from "./a"; +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/isolatedModulesReExportType.errors.txt b/tests/baselines/reference/isolatedModulesReExportType.errors.txt new file mode 100644 index 00000000000..10c07cde084 --- /dev/null +++ b/tests/baselines/reference/isolatedModulesReExportType.errors.txt @@ -0,0 +1,38 @@ +/user.ts(2,10): error TS1205: Cannot re-export a type when the '--isolatedModules' flag is provided. +/user.ts(17,10): error TS1205: Cannot re-export a type when the '--isolatedModules' flag is provided. + + +==== /user.ts (2 errors) ==== + // Error, can't re-export something that's only a type. + export { T } from "./exportT"; + ~ +!!! error TS1205: Cannot re-export a type when the '--isolatedModules' flag is provided. + export import T2 = require("./exportEqualsT"); + + // OK, has a value side + export { C } from "./exportValue"; + + // OK, even though the namespace it exports is only types. + import * as NS from "./exportT"; + export { NS }; + + // OK, syntactically clear that a type is being re-exported. + export type T3 = T; + + // Error, not clear (to an isolated module) whether `T4` is a type. + import { T } from "./exportT"; + export { T as T4 }; + ~~~~~~~ +!!! error TS1205: Cannot re-export a type when the '--isolatedModules' flag is provided. + +==== /exportT.ts (0 errors) ==== + export type T = number; + +==== /exportValue.ts (0 errors) ==== + export class C {} + +==== /exportEqualsT.ts (0 errors) ==== + declare type T = number; + export = T; + + \ No newline at end of file diff --git a/tests/baselines/reference/isolatedModulesReExportType.js b/tests/baselines/reference/isolatedModulesReExportType.js new file mode 100644 index 00000000000..545e5a81a8a --- /dev/null +++ b/tests/baselines/reference/isolatedModulesReExportType.js @@ -0,0 +1,57 @@ +//// [tests/cases/compiler/isolatedModulesReExportType.ts] //// + +//// [exportT.ts] +export type T = number; + +//// [exportValue.ts] +export class C {} + +//// [exportEqualsT.ts] +declare type T = number; +export = T; + + +//// [user.ts] +// Error, can't re-export something that's only a type. +export { T } from "./exportT"; +export import T2 = require("./exportEqualsT"); + +// OK, has a value side +export { C } from "./exportValue"; + +// OK, even though the namespace it exports is only types. +import * as NS from "./exportT"; +export { NS }; + +// OK, syntactically clear that a type is being re-exported. +export type T3 = T; + +// Error, not clear (to an isolated module) whether `T4` is a type. +import { T } from "./exportT"; +export { T as T4 }; + + +//// [exportT.js] +"use strict"; +exports.__esModule = true; +//// [exportEqualsT.js] +"use strict"; +exports.__esModule = true; +//// [exportValue.js] +"use strict"; +exports.__esModule = true; +var C = (function () { + function C() { + } + return C; +}()); +exports.C = C; +//// [user.js] +"use strict"; +exports.__esModule = true; +// OK, has a value side +var exportValue_1 = require("./exportValue"); +exports.C = exportValue_1.C; +// OK, even though the namespace it exports is only types. +var NS = require("./exportT"); +exports.NS = NS; diff --git a/tests/baselines/reference/typesWithPrivateConstructor.js b/tests/baselines/reference/typesWithPrivateConstructor.js index be58c77339d..e5c59b99e93 100644 --- a/tests/baselines/reference/typesWithPrivateConstructor.js +++ b/tests/baselines/reference/typesWithPrivateConstructor.js @@ -38,7 +38,7 @@ declare class C { declare var c: any; declare var r: () => void; declare class C2 { - private constructor(x); + private constructor(); } declare var c2: any; declare var r2: (x: number) => void; diff --git a/tests/cases/compiler/APISample_compile.ts b/tests/cases/compiler/APISample_compile.ts index b60c53685aa..c49d2a7b122 100644 --- a/tests/cases/compiler/APISample_compile.ts +++ b/tests/cases/compiler/APISample_compile.ts @@ -4,7 +4,7 @@ // @strictNullChecks:true /* - * Note: This test is a public API sample. The sample sources can be found + * Note: This test is a public API sample. The sample sources can be found at: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#a-minimal-compiler * Please log a "breaking change" issue for any API breaking change affecting this issue */ @@ -22,8 +22,12 @@ export function compile(fileNames: string[], options: ts.CompilerOptions): void var allDiagnostics = ts.getPreEmitDiagnostics(program); allDiagnostics.forEach(diagnostic => { - var { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start); var message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'); + if (!diagnostic.file) { + console.log(message); + return; + } + var { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!); console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`); }); @@ -35,4 +39,4 @@ export function compile(fileNames: string[], options: ts.CompilerOptions): void compile(process.argv.slice(2), { noEmitOnError: true, noImplicitAny: true, target: ts.ScriptTarget.ES5, module: ts.ModuleKind.CommonJS -}); \ No newline at end of file +}); diff --git a/tests/cases/compiler/APISample_watcher.ts b/tests/cases/compiler/APISample_watcher.ts index 07922bd35c7..3e8ce3d8d63 100644 --- a/tests/cases/compiler/APISample_watcher.ts +++ b/tests/cases/compiler/APISample_watcher.ts @@ -4,7 +4,7 @@ // @strictNullChecks:true /* - * Note: This test is a public API sample. The sample sources can be found + * Note: This test is a public API sample. The sample sources can be found at: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#incremental-build-support-using-the-language-services * Please log a "breaking change" issue for any API breaking change affecting this issue */ @@ -95,7 +95,7 @@ function watch(rootFileNames: string[], options: ts.CompilerOptions) { allDiagnostics.forEach(diagnostic => { let message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n"); if (diagnostic.file) { - let { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start); + let { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!); console.log(` Error ${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`); } else { @@ -110,4 +110,4 @@ const currentDirectoryFiles = fs.readdirSync(process.cwd()). filter(fileName=> fileName.length >= 3 && fileName.substr(fileName.length - 3, 3) === ".ts"); // Start the watcher -watch(currentDirectoryFiles, { module: ts.ModuleKind.CommonJS }); \ No newline at end of file +watch(currentDirectoryFiles, { module: ts.ModuleKind.CommonJS }); diff --git a/tests/cases/compiler/declarationEmitClassPrivateConstructor.ts b/tests/cases/compiler/declarationEmitClassPrivateConstructor.ts new file mode 100644 index 00000000000..d77360496c9 --- /dev/null +++ b/tests/cases/compiler/declarationEmitClassPrivateConstructor.ts @@ -0,0 +1,22 @@ +// @target: es5 +// @module: commonjs +// @declaration: true + +interface PrivateInterface { +} + +export class ExportedClass1 { + private constructor(data: PrivateInterface) { } +} + +export class ExportedClass2 { + private constructor(private data: PrivateInterface) { } +} + +export class ExportedClass3 { + private constructor(private data: PrivateInterface, private n: number) { } +} + +export class ExportedClass4 { + private constructor(private data: PrivateInterface, public n:number) { } +} \ No newline at end of file diff --git a/tests/cases/compiler/declarationEmitClassPrivateConstructor2.ts b/tests/cases/compiler/declarationEmitClassPrivateConstructor2.ts new file mode 100644 index 00000000000..900ece84f8e --- /dev/null +++ b/tests/cases/compiler/declarationEmitClassPrivateConstructor2.ts @@ -0,0 +1,15 @@ +// @target: es5 +// @module: commonjs +// @declaration: true + +interface PrivateInterface { +} + +export class ExportedClass1 { + private constructor(public data: PrivateInterface) { } +} + + +export class ExportedClass2 { + protected constructor(data: PrivateInterface) { } +} \ No newline at end of file diff --git a/tests/cases/compiler/declarationEmitExpressionInExtends5.ts b/tests/cases/compiler/declarationEmitExpressionInExtends5.ts new file mode 100644 index 00000000000..5057ade7570 --- /dev/null +++ b/tests/cases/compiler/declarationEmitExpressionInExtends5.ts @@ -0,0 +1,20 @@ +// @declaration: true +namespace Test +{ + export interface IFace + { + } + + export class SomeClass implements IFace + { + } + + export class Derived extends getClass() + { + } + + export function getClass() : new() => T + { + return SomeClass as (new() => T); + } +} diff --git a/tests/cases/compiler/isolatedModulesDontElideReExportStar.ts b/tests/cases/compiler/isolatedModulesDontElideReExportStar.ts new file mode 100644 index 00000000000..37a851a6292 --- /dev/null +++ b/tests/cases/compiler/isolatedModulesDontElideReExportStar.ts @@ -0,0 +1,8 @@ +// @isolatedModules: true +// @target: es6 + +// @filename: /a.ts +export type T = number; + +// @filename: /b.ts +export * from "./a"; diff --git a/tests/cases/compiler/isolatedModulesReExportType.ts b/tests/cases/compiler/isolatedModulesReExportType.ts new file mode 100644 index 00000000000..d1e05af6c83 --- /dev/null +++ b/tests/cases/compiler/isolatedModulesReExportType.ts @@ -0,0 +1,31 @@ +// @isolatedModules: true + +// @Filename: /exportT.ts +export type T = number; + +// @Filename: /exportValue.ts +export class C {} + +// @Filename: /exportEqualsT.ts +declare type T = number; +export = T; + + +// @Filename: /user.ts +// Error, can't re-export something that's only a type. +export { T } from "./exportT"; +export import T2 = require("./exportEqualsT"); + +// OK, has a value side +export { C } from "./exportValue"; + +// OK, even though the namespace it exports is only types. +import * as NS from "./exportT"; +export { NS }; + +// OK, syntactically clear that a type is being re-exported. +export type T3 = T; + +// Error, not clear (to an isolated module) whether `T4` is a type. +import { T } from "./exportT"; +export { T as T4 }; diff --git a/tests/cases/fourslash/findAllRefsEnumAsNamespace.ts b/tests/cases/fourslash/findAllRefsEnumAsNamespace.ts new file mode 100644 index 00000000000..a065f355d10 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsEnumAsNamespace.ts @@ -0,0 +1,6 @@ +/// + +////enum [|{| "isWriteAccess": true, "isDefinition": true |}E|] { A } +////let e: [|E|].A; + +verify.singleReferenceGroup("enum E"); diff --git a/tests/cases/fourslash/findAllRefsEnumMember.ts b/tests/cases/fourslash/findAllRefsEnumMember.ts new file mode 100644 index 00000000000..584b8befd29 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsEnumMember.ts @@ -0,0 +1,6 @@ +/// + +////enum E { [|{| "isWriteAccess": true, "isDefinition": true |}A|], B } +////const e: E.[|A|] = E.[|A|]; + +verify.singleReferenceGroup("(enum member) E.A = 0"); diff --git a/tests/cases/fourslash/findAllRefsOnImportAliases2.ts b/tests/cases/fourslash/findAllRefsOnImportAliases2.ts index 63fb12f5270..64f44018d07 100644 --- a/tests/cases/fourslash/findAllRefsOnImportAliases2.ts +++ b/tests/cases/fourslash/findAllRefsOnImportAliases2.ts @@ -1,16 +1,14 @@ /// //@Filename: a.ts -////export class [|{| "isWriteAccess": true, "isDefinition": true |}Class|] { -////} +////export class [|{| "isWriteAccess": true, "isDefinition": true |}Class|] {} //@Filename: b.ts -////import { [|{| "isWriteAccess": true, "isDefinition": true |}Class|] as [|{| "isWriteAccess": true, "isDefinition": true |}C2|] } from "./a"; -//// +////import { [|Class|] as [|{| "isWriteAccess": true, "isDefinition": true |}C2|] } from "./a"; ////var c = new [|C2|](); //@Filename: c.ts -////export { [|{| "isWriteAccess": true, "isDefinition": true |}Class|] as [|{| "isWriteAccess": true, "isDefinition": true |}C3|] } from "./a"; +////export { [|Class|] as [|{| "isWriteAccess": true, "isDefinition": true |}C3|] } from "./a"; const ranges = test.rangesByText(); const classRanges = ranges.get("Class"); diff --git a/tests/cases/fourslash/findAllRefsReExportLocal.ts b/tests/cases/fourslash/findAllRefsReExportLocal.ts index 25e8accbbc0..3e5890e6317 100644 --- a/tests/cases/fourslash/findAllRefsReExportLocal.ts +++ b/tests/cases/fourslash/findAllRefsReExportLocal.ts @@ -5,7 +5,7 @@ // @Filename: /a.ts ////var [|{| "isWriteAccess": true, "isDefinition": true |}x|]; ////export { [|{| "isWriteAccess": true, "isDefinition": true |}x|] }; -////export { [|{| "isWriteAccess": true, "isDefinition": true |}x|] as [|{| "isWriteAccess": true, "isDefinition": true |}y|] }; +////export { [|x|] as [|{| "isWriteAccess": true, "isDefinition": true |}y|] }; // @Filename: /b.ts ////import { [|{| "isWriteAccess": true, "isDefinition": true |}x|], [|{| "isWriteAccess": true, "isDefinition": true |}y|] } from "./a"; diff --git a/tests/cases/fourslash/findAllRefsReExports.ts b/tests/cases/fourslash/findAllRefsReExports.ts index 593db568c8a..a4cced049b9 100644 --- a/tests/cases/fourslash/findAllRefsReExports.ts +++ b/tests/cases/fourslash/findAllRefsReExports.ts @@ -4,10 +4,10 @@ ////export function [|{| "isWriteAccess": true, "isDefinition": true |}foo|](): void {} // @Filename: /b.ts -////export { [|{| "isWriteAccess": true, "isDefinition": true |}foo|] as [|{| "isWriteAccess": true, "isDefinition": true |}bar|] } from "./a"; +////export { [|foo|] as [|{| "isWriteAccess": true, "isDefinition": true |}bar|] } from "./a"; // @Filename: /c.ts -////export { [|{| "isWriteAccess": true, "isDefinition": true |}foo|] as [|{| "isWriteAccess": true, "isDefinition": true |}default|] } from "./a"; +////export { [|foo|] as [|{| "isWriteAccess": true, "isDefinition": true |}default|] } from "./a"; // @Filename: /d.ts ////export { [|{| "isWriteAccess": true, "isDefinition": true |}default|] } from "./c"; @@ -15,7 +15,7 @@ // @Filename: /e.ts ////import { [|{| "isWriteAccess": true, "isDefinition": true |}bar|] } from "./b"; ////import [|{| "isWriteAccess": true, "isDefinition": true |}baz|] from "./c"; -////import { [|{| "isWriteAccess": true, "isDefinition": true |}default|] as [|{| "isWriteAccess": true, "isDefinition": true |}bang|] } from "./c"; +////import { [|default|] as [|{| "isWriteAccess": true, "isDefinition": true |}bang|] } from "./c"; ////import [|{| "isWriteAccess": true, "isDefinition": true |}boom|] from "./d"; ////[|bar|](); [|baz|](); [|bang|](); [|boom|](); diff --git a/tests/cases/fourslash/findAllRefsReExports2.ts b/tests/cases/fourslash/findAllRefsReExports2.ts new file mode 100644 index 00000000000..5dfdc8aebbf --- /dev/null +++ b/tests/cases/fourslash/findAllRefsReExports2.ts @@ -0,0 +1,14 @@ +/// + +// @Filename: /a.ts +////export function [|{| "isWriteAccess": true, "isDefinition": true |}foo|](): void {} + +// @Filename: /b.ts +////import { [|foo|] as [|{| "isWriteAccess": true, "isDefinition": true |}oof|] } from "./a"; + +verify.noErrors(); +const [r0, r1, r2] = test.ranges(); +verify.referenceGroups(r0, [ + { definition: "function foo(): void", ranges: [r0, r1] }, + { definition: "import oof", ranges: [r2] } +]); diff --git a/tests/cases/fourslash/findAllRefsRenameImportWithSameName.ts b/tests/cases/fourslash/findAllRefsRenameImportWithSameName.ts index c1a49b3b5b0..5a5db1496a7 100644 --- a/tests/cases/fourslash/findAllRefsRenameImportWithSameName.ts +++ b/tests/cases/fourslash/findAllRefsRenameImportWithSameName.ts @@ -4,7 +4,7 @@ ////export const [|{| "isWriteAccess": true, "isDefinition": true |}x|] = 0; //@Filename: /b.ts -////import { [|{| "isWriteAccess": true, "isDefinition": true |}x|] as [|{| "isWriteAccess": true, "isDefinition": true |}x|] } from "./a"; +////import { [|x|] as [|{| "isWriteAccess": true, "isDefinition": true |}x|] } from "./a"; ////[|x|]; verify.noErrors(); diff --git a/tests/cases/fourslash/javaScriptClass3.ts b/tests/cases/fourslash/javaScriptClass3.ts index 41ce79b35eb..fd67f6f53a5 100644 --- a/tests/cases/fourslash/javaScriptClass3.ts +++ b/tests/cases/fourslash/javaScriptClass3.ts @@ -1,13 +1,13 @@ /// -// In an inferred class, we can to-to-def successfully +// In an inferred class, we can go-to-def successfully // @allowNonTsExtensions: true // @Filename: Foo.js //// class Foo { //// constructor() { -//// /*dst1*/this.alpha = 10; -//// /*dst2*/this.beta = 'gamma'; +//// this./*dst1*/alpha = 10; +//// this./*dst2*/beta = 'gamma'; //// } //// method() { return this.alpha; } //// } diff --git a/tests/cases/fourslash/renameImportOfExportEquals2.ts b/tests/cases/fourslash/renameImportOfExportEquals2.ts index f57a10c5777..8ac00b8c012 100644 --- a/tests/cases/fourslash/renameImportOfExportEquals2.ts +++ b/tests/cases/fourslash/renameImportOfExportEquals2.ts @@ -8,10 +8,10 @@ ////} ////declare module "a" { //// import * as [|{| "isWriteAccess": true, "isDefinition": true |}O|] from "mod"; -//// export { [|{| "isWriteAccess": true, "isDefinition": true |}O|] as [|{| "isWriteAccess": true, "isDefinition": true |}P|] }; // Renaming N here would rename +//// export { [|O|] as [|{| "isWriteAccess": true, "isDefinition": true |}P|] }; // Renaming N here would rename ////} ////declare module "b" { -//// import { [|{| "isWriteAccess": true, "isDefinition": true |}P|] as [|{| "isWriteAccess": true, "isDefinition": true |}Q|] } from "a"; +//// import { [|P|] as [|{| "isWriteAccess": true, "isDefinition": true |}Q|] } from "a"; //// export const y: typeof [|Q|].x; ////} diff --git a/tests/cases/fourslash/renameImportOfReExport2.ts b/tests/cases/fourslash/renameImportOfReExport2.ts index 56cc3966112..ac61200b2f0 100644 --- a/tests/cases/fourslash/renameImportOfReExport2.ts +++ b/tests/cases/fourslash/renameImportOfReExport2.ts @@ -4,7 +4,7 @@ //// export class [|{| "isWriteAccess": true, "isDefinition": true |}C|] {} ////} ////declare module "b" { -//// export { [|{| "isWriteAccess": true, "isDefinition": true |}C|] as [|{| "isWriteAccess": true, "isDefinition": true |}D|] } from "a"; +//// export { [|C|] as [|{| "isWriteAccess": true, "isDefinition": true |}D|] } from "a"; ////} ////declare module "c" { //// import { [|{| "isWriteAccess": true, "isDefinition": true |}D|] } from "b"; diff --git a/tests/cases/fourslash/signatureHelpImportStarFromExportEquals.ts b/tests/cases/fourslash/signatureHelpImportStarFromExportEquals.ts new file mode 100644 index 00000000000..cdf4b0a5c64 --- /dev/null +++ b/tests/cases/fourslash/signatureHelpImportStarFromExportEquals.ts @@ -0,0 +1,15 @@ +/// + +// @allowJs: true + +// @Filename: /node_modules/@types/abs/index.d.ts +////declare function abs(str: string): string; +////export = abs; + +// @Filename: /a.js +////import * as abs from "abs"; +////abs/**/; + +goTo.marker(); +edit.insert('('); +verify.currentSignatureHelpIs('abs(str: string): string'); diff --git a/tests/cases/fourslash/transitiveExportImports3.ts b/tests/cases/fourslash/transitiveExportImports3.ts index 6b3bb10572d..638fa85df83 100644 --- a/tests/cases/fourslash/transitiveExportImports3.ts +++ b/tests/cases/fourslash/transitiveExportImports3.ts @@ -4,7 +4,7 @@ ////export function [|{| "isWriteAccess": true, "isDefinition": true |}f|]() {} // @Filename: b.ts -////export { [|{| "isWriteAccess": true, "isDefinition": true |}f|] as [|{| "isWriteAccess": true, "isDefinition": true |}g|] } from "./a"; +////export { [|f|] as [|{| "isWriteAccess": true, "isDefinition": true |}g|] } from "./a"; ////import { [|{| "isWriteAccess": true, "isDefinition": true |}f|] } from "./a"; ////import { [|{| "isWriteAccess": true, "isDefinition": true |}g|] } from "./b";