Skip to content

Commit

Permalink
Merge pull request #469 from microsoft/main
Browse files Browse the repository at this point in the history
Create a new pull request by comparing changes across two branches
  • Loading branch information
GulajavaMinistudio authored Aug 30, 2023
2 parents cd3aff4 + c5f92d4 commit a34a8f7
Show file tree
Hide file tree
Showing 64 changed files with 1,719 additions and 333 deletions.
9 changes: 5 additions & 4 deletions .vscode/settings.template.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
// To use the locally built compiler, after 'npm run build':
// "typescript.tsdk": "built/local"

"[typescript][javascript][yaml]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "dprint.dprint"
},
// Enables dprint formatting on all supported files. Setting this as the
// default for all file types is safe as dprint will just ignore any file
// it doesn't support or has explicitly excluded in .dprint.jsonc.
"editor.defaultFormatter": "dprint.dprint",
"editor.formatOnSave": true,

// To ignore commits listed in .git-blame-ignore-revs in GitLens:
"gitlens.advanced.blame.customArguments": [
Expand Down
192 changes: 96 additions & 96 deletions package-lock.json

Large diffs are not rendered by default.

72 changes: 50 additions & 22 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,6 @@ import {
isAssignmentOperator,
isAssignmentPattern,
isAssignmentTarget,
isAsyncFunction,
isAutoAccessorPropertyDeclaration,
isAwaitExpression,
isBinaryExpression,
Expand Down Expand Up @@ -1918,6 +1917,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
var anyType = createIntrinsicType(TypeFlags.Any, "any");
var autoType = createIntrinsicType(TypeFlags.Any, "any", ObjectFlags.NonInferrableType);
var wildcardType = createIntrinsicType(TypeFlags.Any, "any");
var blockedStringType = createIntrinsicType(TypeFlags.Any, "any");
var errorType = createIntrinsicType(TypeFlags.Any, "error");
var unresolvedType = createIntrinsicType(TypeFlags.Any, "unresolved");
var nonInferrableAnyType = createIntrinsicType(TypeFlags.Any, "any", ObjectFlags.ContainsWideningType);
Expand Down Expand Up @@ -3874,7 +3874,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
function isSameScopeDescendentOf(initial: Node, parent: Node | undefined, stopAt: Node): boolean {
return !!parent && !!findAncestor(initial, n =>
n === parent
|| (n === stopAt || isFunctionLike(n) && (!getImmediatelyInvokedFunctionExpression(n) || isAsyncFunction(n)) ? "quit" : false));
|| (n === stopAt || isFunctionLike(n) && (!getImmediatelyInvokedFunctionExpression(n) || (getFunctionFlags(n) & FunctionFlags.AsyncGenerator)) ? "quit" : false));
}

function getAnyImportSyntax(node: Node): AnyImportSyntax | undefined {
Expand Down Expand Up @@ -8534,11 +8534,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
...oldcontext,
usedSymbolNames: new Set(oldcontext.usedSymbolNames),
remappedSymbolNames: new Map(),
remappedSymbolReferences: new Map(oldcontext.remappedSymbolReferences?.entries()),
tracker: undefined!,
};
const tracker: SymbolTracker = {
...oldcontext.tracker.inner,
trackSymbol: (sym, decl, meaning) => {
if (context.remappedSymbolNames?.has(getSymbolId(sym))) return false; // If the context has a remapped name for the symbol, it *should* mean it's been made visible
const accessibleResult = isSymbolAccessible(sym, decl, meaning, /*shouldComputeAliasesToMakeVisible*/ false);
if (accessibleResult.accessibility === SymbolAccessibility.Accessible) {
// Lookup the root symbol of the chain of refs we'll use to access it and serialize it
Expand Down Expand Up @@ -8791,9 +8793,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// If it's a property: emit `export default _default` with a `_default` prop
// If it's a class/interface/function: emit a class/interface/function with a `default` modifier
// These forms can merge, eg (`export default 12; export default interface A {}`)
function serializeSymbolWorker(symbol: Symbol, isPrivate: boolean, propertyAsAlias: boolean): void {
const symbolName = unescapeLeadingUnderscores(symbol.escapedName);
const isDefault = symbol.escapedName === InternalSymbolName.Default;
function serializeSymbolWorker(symbol: Symbol, isPrivate: boolean, propertyAsAlias: boolean, escapedSymbolName = symbol.escapedName): void {
const symbolName = unescapeLeadingUnderscores(escapedSymbolName);
const isDefault = escapedSymbolName === InternalSymbolName.Default;
if (isPrivate && !(context.flags & NodeBuilderFlags.AllowAnonymousIdentifier) && isStringANonContextualKeyword(symbolName) && !isDefault) {
// Oh no. We cannot use this symbol's name as it's name... It's likely some jsdoc had an invalid name like `export` or `default` :(
context.encounteredError = true;
Expand All @@ -8812,7 +8814,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const modifierFlags = (!isPrivate ? ModifierFlags.Export : 0) | (isDefault && !needsPostExportDefault ? ModifierFlags.Default : 0);
const isConstMergedWithNS = symbol.flags & SymbolFlags.Module &&
symbol.flags & (SymbolFlags.BlockScopedVariable | SymbolFlags.FunctionScopedVariable | SymbolFlags.Property) &&
symbol.escapedName !== InternalSymbolName.ExportEquals;
escapedSymbolName !== InternalSymbolName.ExportEquals;
const isConstMergedWithNSPrintableAsSignatureMerge = isConstMergedWithNS && isTypeRepresentableAsFunctionNamespaceMerge(getTypeOfSymbol(symbol), symbol);
if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method) || isConstMergedWithNSPrintableAsSignatureMerge) {
serializeAsFunctionNamespaceMerge(getTypeOfSymbol(symbol), symbol, getInternalSymbolName(symbol, symbolName), modifierFlags);
Expand All @@ -8824,7 +8826,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// symbol of name `export=` which needs to be handled like an alias. It's not great, but it is what it is.
if (
symbol.flags & (SymbolFlags.BlockScopedVariable | SymbolFlags.FunctionScopedVariable | SymbolFlags.Property | SymbolFlags.Accessor)
&& symbol.escapedName !== InternalSymbolName.ExportEquals
&& escapedSymbolName !== InternalSymbolName.ExportEquals
&& !(symbol.flags & SymbolFlags.Prototype)
&& !(symbol.flags & SymbolFlags.Class)
&& !(symbol.flags & SymbolFlags.Method)
Expand All @@ -8840,7 +8842,18 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
else {
const type = getTypeOfSymbol(symbol);
const localName = getInternalSymbolName(symbol, symbolName);
if (!(symbol.flags & SymbolFlags.Function) && isTypeRepresentableAsFunctionNamespaceMerge(type, symbol)) {
if (type.symbol && type.symbol !== symbol && type.symbol.flags & SymbolFlags.Function && some(type.symbol.declarations, isFunctionExpressionOrArrowFunction) && (type.symbol.members?.size || type.symbol.exports?.size)) {
// assignment of a anonymous expando/class-like function, the func/ns/merge branch below won't trigger,
// and the assignment form has to reference the unreachable anonymous type so will error.
// Instead, serialize the type's symbol, but with the current symbol's name, rather than the anonymous one.
if (!context.remappedSymbolReferences) {
context.remappedSymbolReferences = new Map();
}
context.remappedSymbolReferences.set(getSymbolId(type.symbol), symbol); // save name remapping as local name for target symbol
serializeSymbolWorker(type.symbol, isPrivate, propertyAsAlias, escapedSymbolName);
context.remappedSymbolReferences.delete(getSymbolId(type.symbol));
}
else if (!(symbol.flags & SymbolFlags.Function) && isTypeRepresentableAsFunctionNamespaceMerge(type, symbol)) {
// If the type looks like a function declaration + ns could represent it, and it's type is sourced locally, rewrite it into a function declaration + ns
serializeAsFunctionNamespaceMerge(type, symbol, localName, modifierFlags);
}
Expand Down Expand Up @@ -10160,6 +10173,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
* It will also use a representation of a number as written instead of a decimal form, e.g. `0o11` instead of `9`.
*/
function getNameOfSymbolAsWritten(symbol: Symbol, context?: NodeBuilderContext): string {
if (context?.remappedSymbolReferences?.has(getSymbolId(symbol))) {
symbol = context.remappedSymbolReferences.get(getSymbolId(symbol))!;
}
if (
context && symbol.escapedName === InternalSymbolName.Default && !(context.flags & NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope) &&
// If it's not the first part of an entity name, it must print as `default`
Expand Down Expand Up @@ -12855,7 +12871,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const baseTypes = getBaseTypes(source);
if (baseTypes.length) {
if (source.symbol && members === getMembersOfSymbol(source.symbol)) {
members = createSymbolTable(source.declaredProperties);
const symbolTable = createSymbolTable();
// copy all symbols (except type parameters), including the ones with internal names like `InternalSymbolName.Index`
for (const symbol of members.values()) {
if (!(symbol.flags & SymbolFlags.TypeParameter)) {
symbolTable.set(symbol.escapedName, symbol);
}
}
members = symbolTable;
}
setStructuredTypeMembers(type, members, callSignatures, constructSignatures, indexInfos);
const thisArgument = lastOrUndefined(typeArguments);
Expand Down Expand Up @@ -19075,10 +19098,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {

function instantiateSymbol(symbol: Symbol, mapper: TypeMapper): Symbol {
const links = getSymbolLinks(symbol);
// If the type of the symbol is already resolved, and if that type could not possibly
// be affected by instantiation, simply return the symbol itself.
if (links.type && !couldContainTypeVariables(links.type)) {
// If the type of the symbol is already resolved, and if that type could not possibly
// be affected by instantiation, simply return the symbol itself.
return symbol;
if (!(symbol.flags & SymbolFlags.SetAccessor)) {
return symbol;
}
// If we're a setter, check writeType.
if (links.writeType && !couldContainTypeVariables(links.writeType)) {
return symbol;
}
}
if (getCheckFlags(symbol) & CheckFlags.Instantiated) {
// If symbol being instantiated is itself a instantiation, fetch the original target and combine the
Expand Down Expand Up @@ -25704,7 +25733,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const constraint = getConstraintOfTypeParameter(inference.typeParameter);
if (constraint) {
const instantiatedConstraint = instantiateType(constraint, context.nonFixingMapper);
if (!inferredType || inferredType === wildcardType || !context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) {
if (!inferredType || inferredType === blockedStringType || !context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) {
// If the fallback type satisfies the constraint, we pick it. Otherwise, we pick the constraint.
inference.inferredType = fallbackType && context.compareTypes(fallbackType, getTypeWithThisArgument(instantiatedConstraint, fallbackType)) ? fallbackType : instantiatedConstraint;
}
Expand Down Expand Up @@ -32100,7 +32129,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
return isErrorType(apparentType) ? errorType : apparentType;
}
prop = getPropertyOfType(apparentType, right.escapedText, /*skipObjectFunctionPropertyAugment*/ false, /*includeTypeOnlyMembers*/ node.kind === SyntaxKind.QualifiedName);
prop = getPropertyOfType(apparentType, right.escapedText, /*skipObjectFunctionPropertyAugment*/ isConstEnumObjectType(apparentType), /*includeTypeOnlyMembers*/ node.kind === SyntaxKind.QualifiedName);
}
// In `Foo.Bar.Baz`, 'Foo' is not referenced if 'Bar' is a const enum or a module containing only const enums.
// `Foo` is also not referenced in `enum FooCopy { Bar = Foo.Bar }`, because the enum member value gets inlined
Expand Down Expand Up @@ -35577,13 +35606,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const len = signature.parameters.length - (signatureHasRestParameter(signature) ? 1 : 0);
for (let i = 0; i < len; i++) {
const declaration = signature.parameters[i].valueDeclaration as ParameterDeclaration;
if (declaration.type) {
const typeNode = getEffectiveTypeAnnotationNode(declaration);
if (typeNode) {
const source = addOptionality(getTypeFromTypeNode(typeNode), /*isProperty*/ false, isOptionalDeclaration(declaration));
const target = getTypeAtPosition(context, i);
inferTypes(inferenceContext.inferences, source, target);
}
const typeNode = getEffectiveTypeAnnotationNode(declaration);
if (typeNode) {
const source = addOptionality(getTypeFromTypeNode(typeNode), /*isProperty*/ false, isOptionalDeclaration(declaration));
const target = getTypeAtPosition(context, i);
inferTypes(inferenceContext.inferences, source, target);
}
}
}
Expand Down Expand Up @@ -38520,7 +38547,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
case SyntaxKind.NoSubstitutionTemplateLiteral:
case SyntaxKind.StringLiteral:
return hasSkipDirectInferenceFlag(node) ?
wildcardType :
blockedStringType :
getFreshTypeOfLiteralType(getStringLiteralType((node as StringLiteralLike).text));
case SyntaxKind.NumericLiteral: {
checkGrammarNumericLiteral(node as NumericLiteral);
Expand Down Expand Up @@ -49987,6 +50014,7 @@ interface NodeBuilderContext {
typeParameterNamesByTextNextNameCount?: Map<string, number>;
usedSymbolNames?: Set<string>;
remappedSymbolNames?: Map<SymbolId, string>;
remappedSymbolReferences?: Map<SymbolId, Symbol>;
reverseMappedStack?: ReverseMappedSymbol[];
}

Expand Down
7 changes: 3 additions & 4 deletions src/compiler/commandLineParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@ import {
toFileNameLowerCase,
toPath,
tracing,
trimString,
TsConfigOnlyOption,
TsConfigSourceFile,
TypeAcquisition,
Expand Down Expand Up @@ -1699,13 +1698,13 @@ function createDiagnosticForInvalidCustomType(opt: CommandLineOptionOfCustomType
}

/** @internal */
export function parseCustomTypeOption(opt: CommandLineOptionOfCustomType, value: string, errors: Diagnostic[]) {
return convertJsonOptionOfCustomType(opt, trimString(value || ""), errors);
export function parseCustomTypeOption(opt: CommandLineOptionOfCustomType, value: string | undefined, errors: Diagnostic[]) {
return convertJsonOptionOfCustomType(opt, (value ?? "").trim(), errors);
}

/** @internal */
export function parseListTypeOption(opt: CommandLineOptionOfListType, value = "", errors: Diagnostic[]): string | (string | number)[] | undefined {
value = trimString(value);
value = value.trim();
if (startsWith(value, "-")) {
return undefined;
}
Expand Down
Loading

0 comments on commit a34a8f7

Please sign in to comment.