Skip to content

Commit

Permalink
Merge branch 'master' into add-unmeasurable-variance-kind
Browse files Browse the repository at this point in the history
  • Loading branch information
weswigham committed Apr 29, 2019
2 parents dc40484 + 47d9081 commit 093cc72
Show file tree
Hide file tree
Showing 98 changed files with 1,779 additions and 182 deletions.
5 changes: 2 additions & 3 deletions .github/pull_request_template.md
@@ -1,8 +1,8 @@
<!--
Thank you for submitting a pull request!
Here's a checklist you might find useful.
* [ ] There is an associated issue that is labeled 'Bug' or 'help wanted'
Please verify that:
* [ ] There is an associated issue in the `Backlog` milestone (**required**)
* [ ] Code is up-to-date with the `master` branch
* [ ] You've successfully run `gulp runtests` locally
* [ ] There are new or updated unit tests validating the change
Expand All @@ -12,4 +12,3 @@ Refer to CONTRIBUTING.MD for more details.
-->

Fixes #

11 changes: 2 additions & 9 deletions src/compiler/binder.ts
Expand Up @@ -1625,15 +1625,8 @@ namespace ts {
}

function hasExportDeclarations(node: ModuleDeclaration | SourceFile): boolean {
const body = node.kind === SyntaxKind.SourceFile ? node : node.body;
if (body && (body.kind === SyntaxKind.SourceFile || body.kind === SyntaxKind.ModuleBlock)) {
for (const stat of (<BlockLike>body).statements) {
if (stat.kind === SyntaxKind.ExportDeclaration || stat.kind === SyntaxKind.ExportAssignment) {
return true;
}
}
}
return false;
const body = isSourceFile(node) ? node : tryCast(node.body, isModuleBlock);
return !!body && body.statements.some(s => isExportDeclaration(s) || isExportAssignment(s));
}

function setExportContextFlag(node: ModuleDeclaration | SourceFile) {
Expand Down
85 changes: 67 additions & 18 deletions src/compiler/checker.ts
Expand Up @@ -1410,15 +1410,14 @@ namespace ts {
}
break;
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.PropertySignature:
// TypeScript 1.0 spec (April 2014): 8.4.1
// Initializer expressions for instance member variables are evaluated in the scope
// of the class constructor body but are not permitted to reference parameters or
// local variables of the constructor. This effectively means that entities from outer scopes
// by the same name as a constructor parameter or local variable are inaccessible
// in initializer expressions for instance member variables.
if (isClassLike(location.parent) && !hasModifier(location, ModifierFlags.Static)) {
const ctor = findConstructorDeclaration(location.parent);
if (!hasModifier(location, ModifierFlags.Static)) {
const ctor = findConstructorDeclaration(location.parent as ClassLikeDeclaration);
if (ctor && ctor.locals) {
if (lookup(ctor.locals, name, meaning & SymbolFlags.Value)) {
// Remember the property node, it will be used later to report appropriate error
Expand Down Expand Up @@ -9944,13 +9943,13 @@ namespace ts {
return type.flags & TypeFlags.Union ? getIntersectionType(map((<IntersectionType>type).types, t => getIndexType(t, stringsOnly, noIndexSignatures))) :
type.flags & TypeFlags.Intersection ? getUnionType(map((<IntersectionType>type).types, t => getIndexType(t, stringsOnly, noIndexSignatures))) :
maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive) ? getIndexTypeForGenericType(<InstantiableType | UnionOrIntersectionType>type, stringsOnly) :
getObjectFlags(type) & ObjectFlags.Mapped ? filterType(getConstraintTypeFromMappedType(<MappedType>type), t => !(noIndexSignatures && t.flags & (TypeFlags.Any | TypeFlags.String | TypeFlags.Number))) :
getObjectFlags(type) & ObjectFlags.Mapped ? filterType(getConstraintTypeFromMappedType(<MappedType>type), t => !(noIndexSignatures && t.flags & (TypeFlags.Any | TypeFlags.String))) :
type === wildcardType ? wildcardType :
type.flags & TypeFlags.Unknown ? neverType :
type.flags & (TypeFlags.Any | TypeFlags.Never) ? keyofConstraintType :
stringsOnly ? !noIndexSignatures && getIndexInfoOfType(type, IndexKind.String) ? stringType : getLiteralTypeFromProperties(type, TypeFlags.StringLiteral) :
!noIndexSignatures && getIndexInfoOfType(type, IndexKind.String) ? getUnionType([stringType, numberType, getLiteralTypeFromProperties(type, TypeFlags.UniqueESSymbol)]) :
!noIndexSignatures && getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromProperties(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol)]) :
getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromProperties(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol)]) :
getLiteralTypeFromProperties(type, TypeFlags.StringOrNumberLiteralOrUnique);
}

Expand Down Expand Up @@ -10068,10 +10067,10 @@ namespace ts {
if (objectType.flags & (TypeFlags.Any | TypeFlags.Never)) {
return objectType;
}
const indexInfo = isTypeAssignableToKind(indexType, TypeFlags.NumberLike) && getIndexInfoOfType(objectType, IndexKind.Number) ||
getIndexInfoOfType(objectType, IndexKind.String);
const stringIndexInfo = getIndexInfoOfType(objectType, IndexKind.String);
const indexInfo = isTypeAssignableToKind(indexType, TypeFlags.NumberLike) && getIndexInfoOfType(objectType, IndexKind.Number) || stringIndexInfo;
if (indexInfo) {
if (accessFlags & AccessFlags.NoIndexSignatures) {
if (accessFlags & AccessFlags.NoIndexSignatures && indexInfo === stringIndexInfo) {
if (accessExpression) {
error(accessExpression, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(originalObjectType));
}
Expand Down Expand Up @@ -14270,6 +14269,32 @@ namespace ts {
return strictNullChecks ? getGlobalNonNullableTypeInstantiation(type) : type;
}


/**
* Is source potentially coercible to target type under `==`.
* Assumes that `source` is a constituent of a union, hence
* the boolean literal flag on the LHS, but not on the RHS.
*
* This does not fully replicate the semantics of `==`. The
* intention is to catch cases that are clearly not right.
*
* Comparing (string | number) to number should not remove the
* string element.
*
* Comparing (string | number) to 1 will remove the string
* element, though this is not sound. This is a pragmatic
* choice.
*
* @see narrowTypeByEquality
*
* @param source
* @param target
*/
function isCoercibleUnderDoubleEquals(source: Type, target: Type): boolean {
return ((source.flags & (TypeFlags.Number | TypeFlags.String | TypeFlags.BooleanLiteral)) !== 0)
&& ((target.flags & (TypeFlags.Number | TypeFlags.String | TypeFlags.Boolean)) !== 0);
}

/**
* Return true if type was inferred from an object literal, written as an object type literal, or is the shape of a module
* with no call or construct signatures.
Expand Down Expand Up @@ -16613,7 +16638,10 @@ namespace ts {
return type;
}
if (assumeTrue) {
const narrowedType = filterType(type, t => areTypesComparable(t, valueType));
const filterFn: (t: Type) => boolean = operator === SyntaxKind.EqualsEqualsToken ?
(t => areTypesComparable(t, valueType) || isCoercibleUnderDoubleEquals(t, valueType)) :
t => areTypesComparable(t, valueType);
const narrowedType = filterType(type, filterFn);
return narrowedType.flags & TypeFlags.Never ? type : replacePrimitivesWithLiterals(narrowedType, valueType);
}
if (isUnitType(valueType)) {
Expand Down Expand Up @@ -25678,7 +25706,7 @@ namespace ts {
}

if (!compilerOptions.experimentalDecorators) {
error(node, Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_to_remove_this_warning);
error(node, Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_in_your_tsconfig_or_jsconfig_to_remove_this_warning);
}

const firstDecorator = node.decorators[0];
Expand Down Expand Up @@ -26476,14 +26504,28 @@ namespace ts {
}
// For a binding pattern, validate the initializer and exit
if (isBindingPattern(node.name)) {
// Don't validate for-in initializer as it is already an error
if (node.initializer && node.parent.parent.kind !== SyntaxKind.ForInStatement) {
const initializerType = checkExpressionCached(node.initializer);
if (strictNullChecks && node.name.elements.length === 0) {
checkNonNullNonVoidType(initializerType, node);
const needCheckInitializer = node.initializer && node.parent.parent.kind !== SyntaxKind.ForInStatement;
const needCheckWidenedType = node.name.elements.length === 0;
if (needCheckInitializer || needCheckWidenedType) {
// Don't validate for-in initializer as it is already an error
const widenedType = getWidenedTypeForVariableLikeDeclaration(node);
if (needCheckInitializer) {
const initializerType = checkExpressionCached(node.initializer!);
if (strictNullChecks && needCheckWidenedType) {
checkNonNullNonVoidType(initializerType, node);
}
else {
checkTypeAssignableToAndOptionallyElaborate(initializerType, getWidenedTypeForVariableLikeDeclaration(node), node, node.initializer);
}
}
else {
checkTypeAssignableToAndOptionallyElaborate(initializerType, getWidenedTypeForVariableLikeDeclaration(node), node, node.initializer);
// check the binding pattern with empty elements
if (needCheckWidenedType) {
if (isArrayBindingPattern(node.name)) {
checkIteratedTypeOrElementType(widenedType, node, /* allowStringInput */ false, /* allowAsyncIterables */ false);
}
else if (strictNullChecks) {
checkNonNullNonVoidType(widenedType, node);
}
}
}
return;
Expand Down Expand Up @@ -31228,6 +31270,13 @@ namespace ts {

for (const prop of node.properties) {
if (prop.kind === SyntaxKind.SpreadAssignment) {
if (inDestructuring) {
// a rest property cannot be destructured any further
const expression = skipParentheses(prop.expression);
if (isArrayLiteralExpression(expression) || isObjectLiteralExpression(expression)) {
return grammarErrorOnNode(prop.expression, Diagnostics.A_rest_element_cannot_contain_a_binding_pattern);
}
}
continue;
}
const name = prop.name;
Expand Down Expand Up @@ -31890,7 +31939,7 @@ namespace ts {
return false;
}

return grammarErrorOnFirstToken(node, Diagnostics.A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file);
return grammarErrorOnFirstToken(node, Diagnostics.Top_level_declarations_in_d_ts_files_must_start_with_either_a_declare_or_export_modifier);
}

function checkGrammarTopLevelElementsForRequiredDeclareModifier(file: SourceFile): boolean {
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/commandLineParser.ts
Expand Up @@ -16,6 +16,7 @@ namespace ts {
["es2017", "lib.es2017.d.ts"],
["es2018", "lib.es2018.d.ts"],
["es2019", "lib.es2019.d.ts"],
["es2020", "lib.es2020.d.ts"],
["esnext", "lib.esnext.d.ts"],
// Host only
["dom", "lib.dom.d.ts"],
Expand Down Expand Up @@ -46,6 +47,8 @@ namespace ts {
["es2019.array", "lib.es2019.array.d.ts"],
["es2019.string", "lib.es2019.string.d.ts"],
["es2019.symbol", "lib.es2019.symbol.d.ts"],
["es2020.string", "lib.es2020.string.d.ts"],
["es2020.symbol.wellknown", "lib.es2020.symbol.wellknown.d.ts"],
["esnext.array", "lib.es2019.array.d.ts"],
["esnext.symbol", "lib.es2019.symbol.d.ts"],
["esnext.asynciterable", "lib.es2018.asynciterable.d.ts"],
Expand Down Expand Up @@ -210,6 +213,7 @@ namespace ts {
es2017: ScriptTarget.ES2017,
es2018: ScriptTarget.ES2018,
es2019: ScriptTarget.ES2019,
es2020: ScriptTarget.ES2020,
esnext: ScriptTarget.ESNext,
}),
affectsSourceFile: true,
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/diagnosticMessages.json
Expand Up @@ -139,7 +139,7 @@
"category": "Error",
"code": 1045
},
"A 'declare' modifier is required for a top level declaration in a .d.ts file.": {
"Top-level declarations in .d.ts files must start with either a 'declare' or 'export' modifier.": {
"category": "Error",
"code": 1046
},
Expand Down Expand Up @@ -691,7 +691,7 @@
"category": "Error",
"code": 1218
},
"Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option to remove this warning.": {
"Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option in your 'tsconfig' or 'jsconfig' to remove this warning.": {
"category": "Error",
"code": 1219
},
Expand Down
32 changes: 24 additions & 8 deletions src/compiler/moduleNameResolver.ts
Expand Up @@ -421,6 +421,7 @@ namespace ts {
*/
export interface ModuleResolutionCache extends NonRelativeModuleNameResolutionCache {
getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference): Map<ResolvedModuleWithFailedLookupLocations>;
/*@internal*/ directoryToModuleNameMap: CacheWithRedirects<Map<ResolvedModuleWithFailedLookupLocations>>;
}

/**
Expand All @@ -429,49 +430,64 @@ namespace ts {
*/
export interface NonRelativeModuleNameResolutionCache {
getOrCreateCacheForModuleName(nonRelativeModuleName: string, redirectedReference?: ResolvedProjectReference): PerModuleNameCache;
/*@internal*/ moduleNameToDirectoryMap: CacheWithRedirects<PerModuleNameCache>;
}

export interface PerModuleNameCache {
get(directory: string): ResolvedModuleWithFailedLookupLocations | undefined;
set(directory: string, result: ResolvedModuleWithFailedLookupLocations): void;
}

export function createModuleResolutionCache(currentDirectory: string, getCanonicalFileName: (s: string) => string): ModuleResolutionCache {
export function createModuleResolutionCache(currentDirectory: string, getCanonicalFileName: (s: string) => string, options?: CompilerOptions): ModuleResolutionCache {
return createModuleResolutionCacheWithMaps(
createCacheWithRedirects(),
createCacheWithRedirects(),
createCacheWithRedirects(options),
createCacheWithRedirects(options),
currentDirectory,
getCanonicalFileName
);
}


/*@internal*/
export interface CacheWithRedirects<T> {
ownMap: Map<T>;
redirectsMap: Map<Map<T>>;
getOrCreateMapOfCacheRedirects(redirectedReference: ResolvedProjectReference | undefined): Map<T>;
clear(): void;
setOwnOptions(newOptions: CompilerOptions): void;
setOwnMap(newOwnMap: Map<T>): void;
}

/*@internal*/
export function createCacheWithRedirects<T>(): CacheWithRedirects<T> {
const ownMap: Map<T> = createMap();
export function createCacheWithRedirects<T>(options?: CompilerOptions): CacheWithRedirects<T> {
let ownMap: Map<T> = createMap();
const redirectsMap: Map<Map<T>> = createMap();
return {
ownMap,
redirectsMap,
getOrCreateMapOfCacheRedirects,
clear
clear,
setOwnOptions,
setOwnMap
};

function setOwnOptions(newOptions: CompilerOptions) {
options = newOptions;
}

function setOwnMap(newOwnMap: Map<T>) {
ownMap = newOwnMap;
}

function getOrCreateMapOfCacheRedirects(redirectedReference: ResolvedProjectReference | undefined) {
if (!redirectedReference) {
return ownMap;
}
const path = redirectedReference.sourceFile.path;
let redirects = redirectsMap.get(path);
if (!redirects) {
redirects = createMap();
// Reuse map if redirected reference map uses same resolution
redirects = !options || optionsHaveModuleResolutionChanges(options, redirectedReference.commandLine.options) ? createMap() : ownMap;
redirectsMap.set(path, redirects);
}
return redirects;
Expand All @@ -490,7 +506,7 @@ namespace ts {
currentDirectory: string,
getCanonicalFileName: GetCanonicalFileName): ModuleResolutionCache {

return { getOrCreateCacheForDirectory, getOrCreateCacheForModuleName };
return { getOrCreateCacheForDirectory, getOrCreateCacheForModuleName, directoryToModuleNameMap, moduleNameToDirectoryMap };

function getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference) {
const path = toPath(directoryName, currentDirectory, getCanonicalFileName);
Expand Down

0 comments on commit 093cc72

Please sign in to comment.