Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 2627e6f

Browse filesBrowse files
authored
[Transforms] Merge master on 08/05 (microsoft#10182)
* Fix microsoft#10083 - allowSyntheticDefaultImports alters getExternalModuleMember (microsoft#10096) * Add a helper function `getOrUpdateProperty` to prevent unprotected access to Maps. * Limit type guards as assertions to incomplete types in loops * Accept new baselines * Fix linting error * [Release-2.0] Fix 9662: Visual Studio 2015 with TS2.0 gives incorrect @types path resolution errors (microsoft#9867) * Change the shape of the shim layer to support getAutomaticTypeDirectives * Change the key for looking up automatic type-directives * Update baselines from change look-up name of type-directives * Add @CurrentDirectory into the test * Update baselines * Fix linting error * Address PR: fix spelling mistake * Instead of return path of the type directive names just return type directive names * Remove unused reference files: these tests produce erros so they will not produce these files (microsoft#9233) * Don't allow properties inherited from Object to be automatically included in TSX attributes * Port PR microsoft#10016 to Master (microsoft#10100) * Treat namespaceExportDeclaration as declaration * Update baselines * wip - add tests * Add tests * Show "export namespace" for quick-info * Update baselines from merging
1 parent c725ee4 commit 2627e6f
Copy full SHA for 2627e6f

83 files changed

+535-966Lines changed: 535 additions & 966 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Dismiss banner
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎src/compiler/checker.ts‎

Copy file name to clipboardExpand all lines: src/compiler/checker.ts
+54-32Lines changed: 54 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ namespace ts {
216216
const flowLoopKeys: string[] = [];
217217
const flowLoopTypes: Type[][] = [];
218218
const visitedFlowNodes: FlowNode[] = [];
219-
const visitedFlowTypes: Type[] = [];
219+
const visitedFlowTypes: FlowType[] = [];
220220
const potentialThisCollisions: Node[] = [];
221221
const awaitedTypeStack: number[] = [];
222222

@@ -1136,6 +1136,10 @@ namespace ts {
11361136
else {
11371137
symbolFromVariable = getPropertyOfVariable(targetSymbol, name.text);
11381138
}
1139+
// If the export member we're looking for is default, and there is no real default but allowSyntheticDefaultImports is on, return the entire module as the default
1140+
if (!symbolFromVariable && allowSyntheticDefaultImports && name.text === "default") {
1141+
symbolFromVariable = resolveExternalModuleSymbol(moduleSymbol) || resolveSymbol(moduleSymbol);
1142+
}
11391143
// if symbolFromVariable is export - get its final target
11401144
symbolFromVariable = resolveSymbol(symbolFromVariable);
11411145
const symbolFromModule = getExportOfModule(targetSymbol, name.text);
@@ -8094,21 +8098,33 @@ namespace ts {
80948098
f(type) ? type : neverType;
80958099
}
80968100

8101+
function isIncomplete(flowType: FlowType) {
8102+
return flowType.flags === 0;
8103+
}
8104+
8105+
function getTypeFromFlowType(flowType: FlowType) {
8106+
return flowType.flags === 0 ? (<IncompleteType>flowType).type : <Type>flowType;
8107+
}
8108+
8109+
function createFlowType(type: Type, incomplete: boolean): FlowType {
8110+
return incomplete ? { flags: 0, type } : type;
8111+
}
8112+
80978113
function getFlowTypeOfReference(reference: Node, declaredType: Type, assumeInitialized: boolean, includeOuterFunctions: boolean) {
80988114
let key: string;
80998115
if (!reference.flowNode || assumeInitialized && !(declaredType.flags & TypeFlags.Narrowable)) {
81008116
return declaredType;
81018117
}
81028118
const initialType = assumeInitialized ? declaredType : includeFalsyTypes(declaredType, TypeFlags.Undefined);
81038119
const visitedFlowStart = visitedFlowCount;
8104-
const result = getTypeAtFlowNode(reference.flowNode);
8120+
const result = getTypeFromFlowType(getTypeAtFlowNode(reference.flowNode));
81058121
visitedFlowCount = visitedFlowStart;
81068122
if (reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(result, TypeFacts.NEUndefinedOrNull) === neverType) {
81078123
return declaredType;
81088124
}
81098125
return result;
81108126

8111-
function getTypeAtFlowNode(flow: FlowNode): Type {
8127+
function getTypeAtFlowNode(flow: FlowNode): FlowType {
81128128
while (true) {
81138129
if (flow.flags & FlowFlags.Shared) {
81148130
// We cache results of flow type resolution for shared nodes that were previously visited in
@@ -8120,7 +8136,7 @@ namespace ts {
81208136
}
81218137
}
81228138
}
8123-
let type: Type;
8139+
let type: FlowType;
81248140
if (flow.flags & FlowFlags.Assignment) {
81258141
type = getTypeAtFlowAssignment(<FlowAssignment>flow);
81268142
if (!type) {
@@ -8188,41 +8204,44 @@ namespace ts {
81888204
return undefined;
81898205
}
81908206

8191-
function getTypeAtFlowCondition(flow: FlowCondition) {
8192-
let type = getTypeAtFlowNode(flow.antecedent);
8207+
function getTypeAtFlowCondition(flow: FlowCondition): FlowType {
8208+
const flowType = getTypeAtFlowNode(flow.antecedent);
8209+
let type = getTypeFromFlowType(flowType);
81938210
if (type !== neverType) {
81948211
// If we have an antecedent type (meaning we're reachable in some way), we first
8195-
// attempt to narrow the antecedent type. If that produces the nothing type, then
8196-
// we take the type guard as an indication that control could reach here in a
8197-
// manner not understood by the control flow analyzer (e.g. a function argument
8198-
// has an invalid type, or a nested function has possibly made an assignment to a
8199-
// captured variable). We proceed by reverting to the declared type and then
8212+
// attempt to narrow the antecedent type. If that produces the never type, and if
8213+
// the antecedent type is incomplete (i.e. a transient type in a loop), then we
8214+
// take the type guard as an indication that control *could* reach here once we
8215+
// have the complete type. We proceed by reverting to the declared type and then
82008216
// narrow that.
82018217
const assumeTrue = (flow.flags & FlowFlags.TrueCondition) !== 0;
82028218
type = narrowType(type, flow.expression, assumeTrue);
8203-
if (type === neverType) {
8219+
if (type === neverType && isIncomplete(flowType)) {
82048220
type = narrowType(declaredType, flow.expression, assumeTrue);
82058221
}
82068222
}
8207-
return type;
8223+
return createFlowType(type, isIncomplete(flowType));
82088224
}
82098225

8210-
function getTypeAtSwitchClause(flow: FlowSwitchClause) {
8211-
const type = getTypeAtFlowNode(flow.antecedent);
8226+
function getTypeAtSwitchClause(flow: FlowSwitchClause): FlowType {
8227+
const flowType = getTypeAtFlowNode(flow.antecedent);
8228+
let type = getTypeFromFlowType(flowType);
82128229
const expr = flow.switchStatement.expression;
82138230
if (isMatchingReference(reference, expr)) {
8214-
return narrowTypeBySwitchOnDiscriminant(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd);
8231+
type = narrowTypeBySwitchOnDiscriminant(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd);
82158232
}
8216-
if (isMatchingPropertyAccess(expr)) {
8217-
return narrowTypeByDiscriminant(type, <PropertyAccessExpression>expr, t => narrowTypeBySwitchOnDiscriminant(t, flow.switchStatement, flow.clauseStart, flow.clauseEnd));
8233+
else if (isMatchingPropertyAccess(expr)) {
8234+
type = narrowTypeByDiscriminant(type, <PropertyAccessExpression>expr, t => narrowTypeBySwitchOnDiscriminant(t, flow.switchStatement, flow.clauseStart, flow.clauseEnd));
82188235
}
8219-
return type;
8236+
return createFlowType(type, isIncomplete(flowType));
82208237
}
82218238

8222-
function getTypeAtFlowBranchLabel(flow: FlowLabel) {
8239+
function getTypeAtFlowBranchLabel(flow: FlowLabel): FlowType {
82238240
const antecedentTypes: Type[] = [];
8241+
let seenIncomplete = false;
82248242
for (const antecedent of flow.antecedents) {
8225-
const type = getTypeAtFlowNode(antecedent);
8243+
const flowType = getTypeAtFlowNode(antecedent);
8244+
const type = getTypeFromFlowType(flowType);
82268245
// If the type at a particular antecedent path is the declared type and the
82278246
// reference is known to always be assigned (i.e. when declared and initial types
82288247
// are the same), there is no reason to process more antecedents since the only
@@ -8233,11 +8252,14 @@ namespace ts {
82338252
if (!contains(antecedentTypes, type)) {
82348253
antecedentTypes.push(type);
82358254
}
8255+
if (isIncomplete(flowType)) {
8256+
seenIncomplete = true;
8257+
}
82368258
}
8237-
return getUnionType(antecedentTypes);
8259+
return createFlowType(getUnionType(antecedentTypes), seenIncomplete);
82388260
}
82398261

8240-
function getTypeAtFlowLoopLabel(flow: FlowLabel) {
8262+
function getTypeAtFlowLoopLabel(flow: FlowLabel): FlowType {
82418263
// If we have previously computed the control flow type for the reference at
82428264
// this flow loop junction, return the cached type.
82438265
const id = getFlowNodeId(flow);
@@ -8249,12 +8271,12 @@ namespace ts {
82498271
return cache[key];
82508272
}
82518273
// If this flow loop junction and reference are already being processed, return
8252-
// the union of the types computed for each branch so far. We should never see
8253-
// an empty array here because the first antecedent of a loop junction is always
8254-
// the non-looping control flow path that leads to the top.
8274+
// the union of the types computed for each branch so far, marked as incomplete.
8275+
// We should never see an empty array here because the first antecedent of a loop
8276+
// junction is always the non-looping control flow path that leads to the top.
82558277
for (let i = flowLoopStart; i < flowLoopCount; i++) {
82568278
if (flowLoopNodes[i] === flow && flowLoopKeys[i] === key) {
8257-
return getUnionType(flowLoopTypes[i]);
8279+
return createFlowType(getUnionType(flowLoopTypes[i]), /*incomplete*/ true);
82588280
}
82598281
}
82608282
// Add the flow loop junction and reference to the in-process stack and analyze
@@ -8265,7 +8287,7 @@ namespace ts {
82658287
flowLoopTypes[flowLoopCount] = antecedentTypes;
82668288
for (const antecedent of flow.antecedents) {
82678289
flowLoopCount++;
8268-
const type = getTypeAtFlowNode(antecedent);
8290+
const type = getTypeFromFlowType(getTypeAtFlowNode(antecedent));
82698291
flowLoopCount--;
82708292
// If we see a value appear in the cache it is a sign that control flow analysis
82718293
// was restarted and completed by checkExpressionCached. We can simply pick up
@@ -10068,7 +10090,7 @@ namespace ts {
1006810090
for (const prop of props) {
1006910091
// Is there a corresponding property in the element attributes type? Skip checking of properties
1007010092
// that have already been assigned to, as these are not actually pushed into the resulting type
10071-
if (!nameTable[prop.name]) {
10093+
if (!hasProperty(nameTable, prop.name)) {
1007210094
const targetPropSym = getPropertyOfType(elementAttributesType, prop.name);
1007310095
if (targetPropSym) {
1007410096
const msg = chainDiagnosticMessages(undefined, Diagnostics.Property_0_of_JSX_spread_attribute_is_not_assignable_to_target_property, prop.name);
@@ -10414,7 +10436,7 @@ namespace ts {
1041410436
const targetProperties = getPropertiesOfType(targetAttributesType);
1041510437
for (let i = 0; i < targetProperties.length; i++) {
1041610438
if (!(targetProperties[i].flags & SymbolFlags.Optional) &&
10417-
nameTable[targetProperties[i].name] === undefined) {
10439+
!hasProperty(nameTable, targetProperties[i].name)) {
1041810440

1041910441
error(node, Diagnostics.Property_0_is_missing_in_type_1, targetProperties[i].name, typeToString(targetAttributesType));
1042010442
}
@@ -19845,7 +19867,7 @@ namespace ts {
1984519867
}
1984619868

1984719869
function checkGrammarTopLevelElementForRequiredDeclareModifier(node: Node): boolean {
19848-
// A declare modifier is required for any top level .d.ts declaration except export=, export default,
19870+
// A declare modifier is required for any top level .d.ts declaration except export=, export default, export as namespace
1984919871
// interfaces and imports categories:
1985019872
//
1985119873
// DeclarationElement:
@@ -19863,8 +19885,8 @@ namespace ts {
1986319885
node.kind === SyntaxKind.ImportEqualsDeclaration ||
1986419886
node.kind === SyntaxKind.ExportDeclaration ||
1986519887
node.kind === SyntaxKind.ExportAssignment ||
19888+
node.kind === SyntaxKind.NamespaceExportDeclaration ||
1986619889
getModifierFlags(node) & (ModifierFlags.Ambient | ModifierFlags.Export | ModifierFlags.Default)) {
19867-
1986819890
return false;
1986919891
}
1987019892

Collapse file

‎src/compiler/core.ts‎

Copy file name to clipboardExpand all lines: src/compiler/core.ts
+6-2Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -499,8 +499,12 @@ namespace ts {
499499
return keys;
500500
}
501501

502-
export function getProperty<T>(map: Map<T>, key: string): T {
503-
return hasOwnProperty.call(map, key) ? map[key] : undefined;
502+
export function getProperty<T>(map: Map<T>, key: string): T | undefined {
503+
return hasProperty(map, key) ? map[key] : undefined;
504+
}
505+
506+
export function getOrUpdateProperty<T>(map: Map<T>, key: string, makeValue: () => T): T {
507+
return hasProperty(map, key) ? map[key] : map[key] = makeValue();
504508
}
505509

506510
export function isEmpty<T>(map: Map<T>) {
Collapse file

‎src/compiler/program.ts‎

Copy file name to clipboardExpand all lines: src/compiler/program.ts
+9-10Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,19 +1056,15 @@ namespace ts {
10561056
return resolutions;
10571057
}
10581058

1059-
function getInferredTypesRoot(options: CompilerOptions, rootFiles: string[], host: CompilerHost) {
1060-
return computeCommonSourceDirectoryOfFilenames(rootFiles, host.getCurrentDirectory(), f => host.getCanonicalFileName(f));
1061-
}
1062-
10631059
/**
1064-
* Given a set of options and a set of root files, returns the set of type directive names
1060+
* Given a set of options, returns the set of type directive names
10651061
* that should be included for this program automatically.
10661062
* This list could either come from the config file,
10671063
* or from enumerating the types root + initial secondary types lookup location.
10681064
* More type directives might appear in the program later as a result of loading actual source files;
10691065
* this list is only the set of defaults that are implicitly included.
10701066
*/
1071-
export function getAutomaticTypeDirectiveNames(options: CompilerOptions, rootFiles: string[], host: CompilerHost): string[] {
1067+
export function getAutomaticTypeDirectiveNames(options: CompilerOptions, host: ModuleResolutionHost): string[] {
10721068
// Use explicit type list from tsconfig.json
10731069
if (options.types) {
10741070
return options.types;
@@ -1081,7 +1077,10 @@ namespace ts {
10811077
if (typeRoots) {
10821078
for (const root of typeRoots) {
10831079
if (host.directoryExists(root)) {
1084-
result = result.concat(host.getDirectories(root));
1080+
for (const typeDirectivePath of host.getDirectories(root)) {
1081+
// Return just the type directive names
1082+
result = result.concat(getBaseFileName(normalizePath(typeDirectivePath)));
1083+
}
10851084
}
10861085
}
10871086
}
@@ -1156,11 +1155,11 @@ namespace ts {
11561155
forEach(rootNames, name => processRootFile(name, /*isDefaultLib*/ false));
11571156

11581157
// load type declarations specified via 'types' argument or implicitly from types/ and node_modules/@types folders
1159-
const typeReferences: string[] = getAutomaticTypeDirectiveNames(options, rootNames, host);
1158+
const typeReferences: string[] = getAutomaticTypeDirectiveNames(options, host);
11601159

11611160
if (typeReferences) {
1162-
const inferredRoot = getInferredTypesRoot(options, rootNames, host);
1163-
const containingFilename = combinePaths(inferredRoot, "__inferred type names__.ts");
1161+
// This containingFilename needs to match with the one used in managed-side
1162+
const containingFilename = combinePaths(host.getCurrentDirectory(), "__inferred type names__.ts");
11641163
const resolutions = resolveTypeReferenceDirectiveNamesWorker(typeReferences, containingFilename);
11651164
for (let i = 0; i < typeReferences.length; i++) {
11661165
processTypeReferenceDirective(typeReferences[i], resolutions[i]);
Collapse file

‎src/compiler/types.ts‎

Copy file name to clipboardExpand all lines: src/compiler/types.ts
+11Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1680,6 +1680,16 @@ namespace ts {
16801680
antecedent: FlowNode;
16811681
}
16821682

1683+
export type FlowType = Type | IncompleteType;
1684+
1685+
// Incomplete types occur during control flow analysis of loops. An IncompleteType
1686+
// is distinguished from a regular type by a flags value of zero. Incomplete type
1687+
// objects are internal to the getFlowTypeOfRefecence function and never escape it.
1688+
export interface IncompleteType {
1689+
flags: TypeFlags; // No flags set
1690+
type: Type; // The type marked incomplete
1691+
}
1692+
16831693
export interface AmdDependency {
16841694
path: string;
16851695
name: string;
@@ -2978,6 +2988,7 @@ namespace ts {
29782988
directoryExists?(directoryName: string): boolean;
29792989
realpath?(path: string): string;
29802990
getCurrentDirectory?(): string;
2991+
getDirectories?(path: string): string[];
29812992
}
29822993

29832994
export interface ResolvedModule {
Collapse file

‎src/compiler/utilities.ts‎

Copy file name to clipboardExpand all lines: src/compiler/utilities.ts
+2-6Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3521,12 +3521,7 @@ namespace ts {
35213521
// export { x, y }
35223522
for (const specifier of (<ExportDeclaration>node).exportClause.elements) {
35233523
const name = (specifier.propertyName || specifier.name).text;
3524-
if (!exportSpecifiers[name]) {
3525-
exportSpecifiers[name] = [specifier];
3526-
}
3527-
else {
3528-
exportSpecifiers[name].push(specifier);
3529-
}
3524+
getOrUpdateProperty(exportSpecifiers, name, () => []).push(specifier);
35303525
}
35313526
}
35323527
break;
@@ -3965,6 +3960,7 @@ namespace ts {
39653960
|| kind === SyntaxKind.MethodDeclaration
39663961
|| kind === SyntaxKind.MethodSignature
39673962
|| kind === SyntaxKind.ModuleDeclaration
3963+
|| kind === SyntaxKind.NamespaceExportDeclaration
39683964
|| kind === SyntaxKind.NamespaceImport
39693965
|| kind === SyntaxKind.Parameter
39703966
|| kind === SyntaxKind.PropertyAssignment
Collapse file

‎src/services/services.ts‎

Copy file name to clipboardExpand all lines: src/services/services.ts
+9-2Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1891,7 +1891,7 @@ namespace ts {
18911891
};
18921892
}
18931893

1894-
// Cache host information about scrip Should be refreshed
1894+
// Cache host information about script should be refreshed
18951895
// at each language service public entry point, since we don't know when
18961896
// set of scripts handled by the host changes.
18971897
class HostCache {
@@ -4835,7 +4835,14 @@ namespace ts {
48354835
}
48364836
if (symbolFlags & SymbolFlags.Alias) {
48374837
addNewLineIfDisplayPartsExist();
4838-
displayParts.push(keywordPart(SyntaxKind.ImportKeyword));
4838+
if (symbol.declarations[0].kind === SyntaxKind.NamespaceExportDeclaration) {
4839+
displayParts.push(keywordPart(SyntaxKind.ExportKeyword));
4840+
displayParts.push(spacePart());
4841+
displayParts.push(keywordPart(SyntaxKind.NamespaceKeyword));
4842+
}
4843+
else {
4844+
displayParts.push(keywordPart(SyntaxKind.ImportKeyword));
4845+
}
48394846
displayParts.push(spacePart());
48404847
addFullSymbolName(symbol);
48414848
ts.forEach(symbol.declarations, declaration => {

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.