mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'object-spread' into object-rest
This commit is contained in:
+10
-8
@@ -1138,8 +1138,8 @@ namespace ts {
|
||||
}
|
||||
else if (node.kind === SyntaxKind.ArrayLiteralExpression) {
|
||||
for (const e of (<ArrayLiteralExpression>node).elements) {
|
||||
if (e.kind === SyntaxKind.SpreadExpression) {
|
||||
bindAssignmentTargetFlow((<SpreadExpression>e).expression);
|
||||
if (e.kind === SyntaxKind.SpreadElement) {
|
||||
bindAssignmentTargetFlow((<SpreadElement>e).expression);
|
||||
}
|
||||
else {
|
||||
bindDestructuringTargetFlow(e);
|
||||
@@ -1154,8 +1154,8 @@ namespace ts {
|
||||
else if (p.kind === SyntaxKind.ShorthandPropertyAssignment) {
|
||||
bindAssignmentTargetFlow((<ShorthandPropertyAssignment>p).name);
|
||||
}
|
||||
else if (p.kind === SyntaxKind.SpreadElementExpression) {
|
||||
bindAssignmentTargetFlow((<SpreadElementExpression>p).expression);
|
||||
else if (p.kind === SyntaxKind.SpreadAssignment) {
|
||||
bindAssignmentTargetFlow((<SpreadAssignment>p).expression);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1237,9 +1237,11 @@ namespace ts {
|
||||
const postExpressionLabel = createBranchLabel();
|
||||
bindCondition(node.condition, trueLabel, falseLabel);
|
||||
currentFlow = finishFlowLabel(trueLabel);
|
||||
bind(node.questionToken);
|
||||
bind(node.whenTrue);
|
||||
addAntecedent(postExpressionLabel, currentFlow);
|
||||
currentFlow = finishFlowLabel(falseLabel);
|
||||
bind(node.colonToken);
|
||||
bind(node.whenFalse);
|
||||
addAntecedent(postExpressionLabel, currentFlow);
|
||||
currentFlow = finishFlowLabel(postExpressionLabel);
|
||||
@@ -1932,7 +1934,7 @@ namespace ts {
|
||||
case SyntaxKind.EnumMember:
|
||||
return bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.EnumMember, SymbolFlags.EnumMemberExcludes);
|
||||
|
||||
case SyntaxKind.SpreadElementExpression:
|
||||
case SyntaxKind.SpreadAssignment:
|
||||
case SyntaxKind.JsxSpreadAttribute:
|
||||
let root = container;
|
||||
let hasRest = false;
|
||||
@@ -3174,9 +3176,9 @@ namespace ts {
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.SpreadExpression:
|
||||
case SyntaxKind.SpreadElementExpression:
|
||||
// This node is ES2015 or ES next syntax, but is handled by a containing node.
|
||||
case SyntaxKind.SpreadElement:
|
||||
case SyntaxKind.SpreadAssignment:
|
||||
// This node is ES6 or ES next syntax, but is handled by a containing node.
|
||||
transformFlags |= TransformFlags.ContainsSpreadExpression;
|
||||
break;
|
||||
|
||||
|
||||
+81
-42
@@ -107,7 +107,12 @@ namespace ts {
|
||||
|
||||
getJsxElementAttributesType,
|
||||
getJsxIntrinsicTagNames,
|
||||
isOptionalParameter
|
||||
isOptionalParameter,
|
||||
tryFindAmbientModuleWithoutAugmentations: moduleName => {
|
||||
// we deliberately exclude augmentations
|
||||
// since we are only interested in declarations of the module itself
|
||||
return tryFindAmbientModule(moduleName, /*withAugmentations*/ false);
|
||||
}
|
||||
};
|
||||
|
||||
const tupleTypes: GenericType[] = [];
|
||||
@@ -1370,16 +1375,11 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
|
||||
const isRelative = isExternalModuleNameRelative(moduleName);
|
||||
const quotedName = '"' + moduleName + '"';
|
||||
if (!isRelative) {
|
||||
const symbol = getSymbol(globals, quotedName, SymbolFlags.ValueModule);
|
||||
if (symbol) {
|
||||
// merged symbol is module declaration symbol combined with all augmentations
|
||||
return getMergedSymbol(symbol);
|
||||
}
|
||||
const ambientModule = tryFindAmbientModule(moduleName, /*withAugmentations*/ true);
|
||||
if (ambientModule) {
|
||||
return ambientModule;
|
||||
}
|
||||
|
||||
const isRelative = isExternalModuleNameRelative(moduleName);
|
||||
const resolvedModule = getResolvedModule(getSourceFileOfNode(location), moduleReference);
|
||||
const resolutionDiagnostic = resolvedModule && getResolutionDiagnostic(compilerOptions, resolvedModule);
|
||||
const sourceFile = resolvedModule && !resolutionDiagnostic && host.getSourceFile(resolvedModule.resolvedFileName);
|
||||
@@ -4617,7 +4617,7 @@ namespace ts {
|
||||
result.valueDeclaration = declarations[0];
|
||||
}
|
||||
result.isReadonly = isReadonly;
|
||||
result.type = containingType.flags & TypeFlags.Intersection ? getIntersectionType(propTypes) : getUnionType(propTypes);
|
||||
result.type = containingType.flags & TypeFlags.Union ? getUnionType(propTypes) : getIntersectionType(propTypes);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -4782,6 +4782,15 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function tryFindAmbientModule(moduleName: string, withAugmentations: boolean) {
|
||||
if (isExternalModuleNameRelative(moduleName)) {
|
||||
return undefined;
|
||||
}
|
||||
const symbol = getSymbol(globals, `"${moduleName}"`, SymbolFlags.ValueModule);
|
||||
// merged symbol is module declaration symbol combined with all augmentations
|
||||
return symbol && withAugmentations ? getMergedSymbol(symbol) : symbol;
|
||||
}
|
||||
|
||||
function isOptionalParameter(node: ParameterDeclaration) {
|
||||
if (hasQuestionToken(node) || isJSDocOptionalParameter(node)) {
|
||||
return true;
|
||||
@@ -5900,12 +5909,15 @@ namespace ts {
|
||||
}
|
||||
|
||||
/**
|
||||
* Since the source of spread types are object literals and type literals, which are not binary,
|
||||
* Since the source of spread types are object literals, which are not binary,
|
||||
* this function should be called in a left folding style, with left = previous result of getSpreadType
|
||||
* and right = the new element to be spread.
|
||||
*/
|
||||
function getSpreadType(left: Type, right: Type, symbol: Symbol): ResolvedType {
|
||||
Debug.assert(!!(left.flags & TypeFlags.Object) && !!(right.flags & TypeFlags.Object), "Only object types may be spread.");
|
||||
function getSpreadType(left: Type, right: Type, symbol: Symbol): ResolvedType | IntrinsicType {
|
||||
Debug.assert(!!(left.flags & (TypeFlags.Object | TypeFlags.Any)) && !!(right.flags & (TypeFlags.Object | TypeFlags.Any)), "Only object types may be spread.");
|
||||
if (left.flags & TypeFlags.Any || right.flags & TypeFlags.Any) {
|
||||
return anyType;
|
||||
}
|
||||
const members = createMap<Symbol>();
|
||||
const skippedPrivateMembers = createMap<boolean>();
|
||||
let stringIndexInfo: IndexInfo;
|
||||
@@ -6925,6 +6937,27 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
if (target.flags & TypeFlags.TypeParameter) {
|
||||
// Given a type parameter K with a constraint keyof T, a type S is
|
||||
// assignable to K if S is assignable to keyof T.
|
||||
const constraint = getConstraintOfTypeParameter(<TypeParameter>target);
|
||||
if (constraint && constraint.flags & TypeFlags.Index) {
|
||||
if (result = isRelatedTo(source, constraint, reportErrors)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (target.flags & TypeFlags.Index) {
|
||||
// Given a type parameter T with a constraint C, a type S is assignable to
|
||||
// keyof T if S is assignable to keyof C.
|
||||
const constraint = getConstraintOfTypeParameter((<IndexType>target).type);
|
||||
if (constraint) {
|
||||
if (result = isRelatedTo(source, getIndexType(constraint), reportErrors)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (source.flags & TypeFlags.TypeParameter) {
|
||||
let constraint = getConstraintOfTypeParameter(<TypeParameter>source);
|
||||
|
||||
@@ -8657,7 +8690,7 @@ namespace ts {
|
||||
return getTypeOfDestructuredArrayElement(getAssignedType(node), indexOf(node.elements, element));
|
||||
}
|
||||
|
||||
function getAssignedTypeOfSpreadExpression(node: SpreadExpression): Type {
|
||||
function getAssignedTypeOfSpreadExpression(node: SpreadElement): Type {
|
||||
return getTypeOfDestructuredSpreadExpression(getAssignedType(<ArrayLiteralExpression>node.parent));
|
||||
}
|
||||
|
||||
@@ -8682,8 +8715,8 @@ namespace ts {
|
||||
return undefinedType;
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
return getAssignedTypeOfArrayLiteralElement(<ArrayLiteralExpression>parent, node);
|
||||
case SyntaxKind.SpreadExpression:
|
||||
return getAssignedTypeOfSpreadExpression(<SpreadExpression>parent);
|
||||
case SyntaxKind.SpreadElement:
|
||||
return getAssignedTypeOfSpreadExpression(<SpreadElement>parent);
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
return getAssignedTypeOfPropertyAssignment(<PropertyAssignment>parent);
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
@@ -10714,7 +10747,7 @@ namespace ts {
|
||||
return mapper && mapper.context;
|
||||
}
|
||||
|
||||
function checkSpreadExpression(node: SpreadExpression, contextualMapper?: TypeMapper): Type {
|
||||
function checkSpreadExpression(node: SpreadElement, contextualMapper?: TypeMapper): Type {
|
||||
// It is usually not safe to call checkExpressionCached if we can be contextually typing.
|
||||
// You can tell that we are contextually typing because of the contextualMapper parameter.
|
||||
// While it is true that a spread element can have a contextual type, it does not do anything
|
||||
@@ -10736,7 +10769,7 @@ namespace ts {
|
||||
const elementTypes: Type[] = [];
|
||||
const inDestructuringPattern = isAssignmentTarget(node);
|
||||
for (const e of elements) {
|
||||
if (inDestructuringPattern && e.kind === SyntaxKind.SpreadExpression) {
|
||||
if (inDestructuringPattern && e.kind === SyntaxKind.SpreadElement) {
|
||||
// Given the following situation:
|
||||
// var c: {};
|
||||
// [...c] = ["", 0];
|
||||
@@ -10749,7 +10782,7 @@ namespace ts {
|
||||
// get the contextual element type from it. So we do something similar to
|
||||
// getContextualTypeForElementExpression, which will crucially not error
|
||||
// if there is no index type / iterated type.
|
||||
const restArrayType = checkExpression((<SpreadExpression>e).expression, contextualMapper);
|
||||
const restArrayType = checkExpression((<SpreadElement>e).expression, contextualMapper);
|
||||
const restElementType = getIndexTypeOfType(restArrayType, IndexKind.Number) ||
|
||||
(languageVersion >= ScriptTarget.ES2015 ? getElementTypeOfIterable(restArrayType, /*errorNode*/ undefined) : undefined);
|
||||
if (restElementType) {
|
||||
@@ -10760,7 +10793,7 @@ namespace ts {
|
||||
const type = checkExpressionForMutableLocation(e, contextualMapper);
|
||||
elementTypes.push(type);
|
||||
}
|
||||
hasSpreadElement = hasSpreadElement || e.kind === SyntaxKind.SpreadExpression;
|
||||
hasSpreadElement = hasSpreadElement || e.kind === SyntaxKind.SpreadElement;
|
||||
}
|
||||
if (!hasSpreadElement) {
|
||||
// If array literal is actually a destructuring pattern, mark it as an implied type. We do this such
|
||||
@@ -10944,7 +10977,7 @@ namespace ts {
|
||||
prop.target = member;
|
||||
member = prop;
|
||||
}
|
||||
else if (memberDecl.kind === SyntaxKind.SpreadElementExpression) {
|
||||
else if (memberDecl.kind === SyntaxKind.SpreadAssignment) {
|
||||
if (propertiesArray.length > 0) {
|
||||
spread = getSpreadType(spread, createObjectLiteralType(), node.symbol);
|
||||
propertiesArray = [];
|
||||
@@ -10953,8 +10986,8 @@ namespace ts {
|
||||
hasComputedNumberProperty = false;
|
||||
typeFlags = 0;
|
||||
}
|
||||
const type = checkExpression((memberDecl as SpreadElementExpression).expression);
|
||||
if (!(type.flags & TypeFlags.Object)) {
|
||||
const type = checkExpression((memberDecl as SpreadAssignment).expression);
|
||||
if (!(type.flags & (TypeFlags.Object | TypeFlags.Any))) {
|
||||
error(memberDecl, Diagnostics.Spread_types_may_only_be_created_from_object_types);
|
||||
return unknownType;
|
||||
}
|
||||
@@ -11649,6 +11682,21 @@ namespace ts {
|
||||
diagnostics.add(createDiagnosticForNodeFromMessageChain(propNode, errorInfo));
|
||||
}
|
||||
|
||||
function markPropertyAsReferenced(prop: Symbol) {
|
||||
if (prop &&
|
||||
noUnusedIdentifiers &&
|
||||
(prop.flags & SymbolFlags.ClassMember) &&
|
||||
prop.valueDeclaration && (getModifierFlags(prop.valueDeclaration) & ModifierFlags.Private)) {
|
||||
if (prop.flags & SymbolFlags.Instantiated) {
|
||||
getSymbolLinks(prop).target.isReferenced = true;
|
||||
|
||||
}
|
||||
else {
|
||||
prop.isReferenced = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkPropertyAccessExpressionOrQualifiedName(node: PropertyAccessExpression | QualifiedName, left: Expression | QualifiedName, right: Identifier) {
|
||||
const type = checkNonNullExpression(left);
|
||||
if (isTypeAny(type) || type === silentNeverType) {
|
||||
@@ -11668,17 +11716,7 @@ namespace ts {
|
||||
return unknownType;
|
||||
}
|
||||
|
||||
if (noUnusedIdentifiers &&
|
||||
(prop.flags & SymbolFlags.ClassMember) &&
|
||||
prop.valueDeclaration && (getModifierFlags(prop.valueDeclaration) & ModifierFlags.Private)) {
|
||||
if (prop.flags & SymbolFlags.Instantiated) {
|
||||
getSymbolLinks(prop).target.isReferenced = true;
|
||||
|
||||
}
|
||||
else {
|
||||
prop.isReferenced = true;
|
||||
}
|
||||
}
|
||||
markPropertyAsReferenced(prop);
|
||||
|
||||
getNodeLinks(node).resolvedSymbol = prop;
|
||||
|
||||
@@ -11922,7 +11960,7 @@ namespace ts {
|
||||
function getSpreadArgumentIndex(args: Expression[]): number {
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const arg = args[i];
|
||||
if (arg && arg.kind === SyntaxKind.SpreadExpression) {
|
||||
if (arg && arg.kind === SyntaxKind.SpreadElement) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -13888,7 +13926,7 @@ namespace ts {
|
||||
error(name, Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(objectLiteralType), declarationNameToString(name));
|
||||
}
|
||||
}
|
||||
else if (property.kind !== SyntaxKind.SpreadElementExpression) {
|
||||
else if (property.kind !== SyntaxKind.SpreadAssignment) {
|
||||
error(property, Diagnostics.Property_assignment_expected);
|
||||
}
|
||||
}
|
||||
@@ -13910,7 +13948,7 @@ namespace ts {
|
||||
const elements = node.elements;
|
||||
const element = elements[elementIndex];
|
||||
if (element.kind !== SyntaxKind.OmittedExpression) {
|
||||
if (element.kind !== SyntaxKind.SpreadExpression) {
|
||||
if (element.kind !== SyntaxKind.SpreadElement) {
|
||||
const propName = "" + elementIndex;
|
||||
const type = isTypeAny(sourceType)
|
||||
? sourceType
|
||||
@@ -13937,7 +13975,7 @@ namespace ts {
|
||||
error(element, Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern);
|
||||
}
|
||||
else {
|
||||
const restExpression = (<SpreadExpression>element).expression;
|
||||
const restExpression = (<SpreadElement>element).expression;
|
||||
if (restExpression.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>restExpression).operatorToken.kind === SyntaxKind.EqualsToken) {
|
||||
error((<BinaryExpression>restExpression).operatorToken, Diagnostics.A_rest_element_cannot_have_an_initializer);
|
||||
}
|
||||
@@ -14570,8 +14608,8 @@ namespace ts {
|
||||
return checkBinaryExpression(<BinaryExpression>node, contextualMapper);
|
||||
case SyntaxKind.ConditionalExpression:
|
||||
return checkConditionalExpression(<ConditionalExpression>node, contextualMapper);
|
||||
case SyntaxKind.SpreadExpression:
|
||||
return checkSpreadExpression(<SpreadExpression>node, contextualMapper);
|
||||
case SyntaxKind.SpreadElement:
|
||||
return checkSpreadExpression(<SpreadElement>node, contextualMapper);
|
||||
case SyntaxKind.OmittedExpression:
|
||||
return undefinedWideningType;
|
||||
case SyntaxKind.YieldExpression:
|
||||
@@ -16470,6 +16508,7 @@ namespace ts {
|
||||
const parentType = getTypeForBindingElementParent(parent);
|
||||
const name = node.propertyName || <Identifier>node.name;
|
||||
const property = getPropertyOfType(parentType, getTextOfPropertyName(name));
|
||||
markPropertyAsReferenced(property);
|
||||
if (parent.initializer && property && getParentOfSymbol(property)) {
|
||||
checkClassPropertyAccess(parent, parent.initializer, parentType, property);
|
||||
}
|
||||
@@ -20528,7 +20567,7 @@ namespace ts {
|
||||
const GetOrSetAccessor = GetAccessor | SetAccessor;
|
||||
|
||||
for (const prop of node.properties) {
|
||||
if (prop.kind === SyntaxKind.SpreadElementExpression) {
|
||||
if (prop.kind === SyntaxKind.SpreadAssignment) {
|
||||
continue;
|
||||
}
|
||||
const name = prop.name;
|
||||
|
||||
@@ -265,6 +265,7 @@ namespace ts {
|
||||
"es2015": ScriptTarget.ES2015,
|
||||
"es2016": ScriptTarget.ES2016,
|
||||
"es2017": ScriptTarget.ES2017,
|
||||
"esnext": ScriptTarget.ESNext,
|
||||
}),
|
||||
description: Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES2015,
|
||||
paramType: Diagnostics.VERSION,
|
||||
|
||||
@@ -1127,6 +1127,18 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
export function createCompilerDiagnosticFromMessageChain(chain: DiagnosticMessageChain): Diagnostic {
|
||||
return {
|
||||
file: undefined,
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
|
||||
code: chain.code,
|
||||
category: chain.category,
|
||||
messageText: chain.next ? chain : chain.messageText
|
||||
};
|
||||
}
|
||||
|
||||
export function chainDiagnosticMessages(details: DiagnosticMessageChain, message: DiagnosticMessage, ...args: any[]): DiagnosticMessageChain;
|
||||
export function chainDiagnosticMessages(details: DiagnosticMessageChain, message: DiagnosticMessage): DiagnosticMessageChain {
|
||||
let text = getLocaleSpecificMessage(message);
|
||||
|
||||
@@ -2897,6 +2897,14 @@
|
||||
"category": "Error",
|
||||
"code": 6143
|
||||
},
|
||||
"Module '{0}' was resolved as locally declared ambient module in file '{1}'.": {
|
||||
"category": "Message",
|
||||
"code": 6144
|
||||
},
|
||||
"Module '{0}' was resolved as ambient module declared in '{1}' since this file was not modified.": {
|
||||
"category": "Message",
|
||||
"code": 6145
|
||||
},
|
||||
"Variable '{0}' implicitly has an '{1}' type.": {
|
||||
"category": "Error",
|
||||
"code": 7005
|
||||
@@ -3158,5 +3166,9 @@
|
||||
"Implement inherited abstract class": {
|
||||
"category": "Message",
|
||||
"code": 90007
|
||||
},
|
||||
"Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig": {
|
||||
"category": "Error",
|
||||
"code": 90009
|
||||
}
|
||||
}
|
||||
|
||||
+16
-4
@@ -741,6 +741,8 @@ const _super = (function (geti, seti) {
|
||||
return emitPropertyAssignment(<PropertyAssignment>node);
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
return emitShorthandPropertyAssignment(<ShorthandPropertyAssignment>node);
|
||||
case SyntaxKind.SpreadAssignment:
|
||||
return emitSpreadAssignment(node as SpreadAssignment);
|
||||
|
||||
// Enum
|
||||
case SyntaxKind.EnumMember:
|
||||
@@ -831,8 +833,8 @@ const _super = (function (geti, seti) {
|
||||
return emitTemplateExpression(<TemplateExpression>node);
|
||||
case SyntaxKind.YieldExpression:
|
||||
return emitYieldExpression(<YieldExpression>node);
|
||||
case SyntaxKind.SpreadExpression:
|
||||
return emitSpreadExpression(<SpreadExpression>node);
|
||||
case SyntaxKind.SpreadElement:
|
||||
return emitSpreadExpression(<SpreadElement>node);
|
||||
case SyntaxKind.ClassExpression:
|
||||
return emitClassExpression(<ClassExpression>node);
|
||||
case SyntaxKind.OmittedExpression:
|
||||
@@ -1383,7 +1385,7 @@ const _super = (function (geti, seti) {
|
||||
emitExpressionWithPrefix(" ", node.expression);
|
||||
}
|
||||
|
||||
function emitSpreadExpression(node: SpreadExpression) {
|
||||
function emitSpreadExpression(node: SpreadElement) {
|
||||
write("...");
|
||||
emitExpression(node.expression);
|
||||
}
|
||||
@@ -2111,6 +2113,13 @@ const _super = (function (geti, seti) {
|
||||
}
|
||||
}
|
||||
|
||||
function emitSpreadAssignment(node: SpreadAssignment) {
|
||||
if (node.expression) {
|
||||
write("...");
|
||||
emitExpression(node.expression);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Enum
|
||||
//
|
||||
@@ -2214,7 +2223,10 @@ const _super = (function (geti, seti) {
|
||||
helpersEmitted = true;
|
||||
}
|
||||
|
||||
if (compilerOptions.jsx !== JsxEmit.Preserve && !assignEmitted && (node.flags & NodeFlags.HasSpreadAttribute)) {
|
||||
if ((languageVersion < ScriptTarget.ESNext || currentSourceFile.scriptKind === ScriptKind.JSX || currentSourceFile.scriptKind === ScriptKind.TSX) &&
|
||||
compilerOptions.jsx !== JsxEmit.Preserve &&
|
||||
!assignEmitted &&
|
||||
node.flags & NodeFlags.HasSpreadAttribute) {
|
||||
writeLines(assignHelper);
|
||||
assignEmitted = true;
|
||||
}
|
||||
|
||||
+17
-4
@@ -692,12 +692,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function createSpread(expression: Expression, location?: TextRange) {
|
||||
const node = <SpreadExpression>createNode(SyntaxKind.SpreadExpression, location);
|
||||
const node = <SpreadElement>createNode(SyntaxKind.SpreadElement, location);
|
||||
node.expression = parenthesizeExpressionForList(expression);
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateSpread(node: SpreadExpression, expression: Expression) {
|
||||
export function updateSpread(node: SpreadElement, expression: Expression) {
|
||||
if (node.expression !== expression) {
|
||||
return updateNode(createSpread(expression, node), node);
|
||||
}
|
||||
@@ -1399,14 +1399,27 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression) {
|
||||
export function createSpreadAssignment(expression: Expression, location?: TextRange) {
|
||||
const node = <SpreadAssignment>createNode(SyntaxKind.SpreadAssignment, location);
|
||||
node.expression = expression !== undefined ? parenthesizeExpressionForList(expression) : undefined;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression) {
|
||||
if (node.name !== name || node.objectAssignmentInitializer !== objectAssignmentInitializer) {
|
||||
return updateNode(createShorthandPropertyAssignment(name, objectAssignmentInitializer, node), node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
// Top-level nodes
|
||||
export function updateSpreadAssignment(node: SpreadAssignment, expression: Expression) {
|
||||
if (node.expression !== expression) {
|
||||
return updateNode(createSpreadAssignment(expression, node), node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
// Top-level nodes
|
||||
|
||||
export function updateSourceFileNode(node: SourceFile, statements: Statement[]) {
|
||||
if (node.statements !== statements) {
|
||||
|
||||
@@ -2,12 +2,15 @@
|
||||
/// <reference path="diagnosticInformationMap.generated.ts" />
|
||||
|
||||
namespace ts {
|
||||
function trace(host: ModuleResolutionHost, message: DiagnosticMessage, ...args: any[]): void;
|
||||
function trace(host: ModuleResolutionHost): void {
|
||||
|
||||
/* @internal */
|
||||
export function trace(host: ModuleResolutionHost, message: DiagnosticMessage, ...args: any[]): void;
|
||||
export function trace(host: ModuleResolutionHost): void {
|
||||
host.trace(formatMessage.apply(undefined, arguments));
|
||||
}
|
||||
|
||||
function isTraceEnabled(compilerOptions: CompilerOptions, host: ModuleResolutionHost): boolean {
|
||||
/* @internal */
|
||||
export function isTraceEnabled(compilerOptions: CompilerOptions, host: ModuleResolutionHost): boolean {
|
||||
return compilerOptions.traceResolution && host.trace !== undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -74,8 +74,8 @@ namespace ts {
|
||||
visitNode(cbNode, (<ShorthandPropertyAssignment>node).questionToken) ||
|
||||
visitNode(cbNode, (<ShorthandPropertyAssignment>node).equalsToken) ||
|
||||
visitNode(cbNode, (<ShorthandPropertyAssignment>node).objectAssignmentInitializer);
|
||||
case SyntaxKind.SpreadElementExpression:
|
||||
return visitNode(cbNode, (<SpreadElementExpression>node).expression);
|
||||
case SyntaxKind.SpreadAssignment:
|
||||
return visitNode(cbNode, (<SpreadAssignment>node).expression);
|
||||
case SyntaxKind.Parameter:
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.PropertySignature:
|
||||
@@ -199,8 +199,8 @@ namespace ts {
|
||||
visitNode(cbNode, (<ConditionalExpression>node).whenTrue) ||
|
||||
visitNode(cbNode, (<ConditionalExpression>node).colonToken) ||
|
||||
visitNode(cbNode, (<ConditionalExpression>node).whenFalse);
|
||||
case SyntaxKind.SpreadExpression:
|
||||
return visitNode(cbNode, (<SpreadExpression>node).expression);
|
||||
case SyntaxKind.SpreadElement:
|
||||
return visitNode(cbNode, (<SpreadElement>node).expression);
|
||||
case SyntaxKind.Block:
|
||||
case SyntaxKind.ModuleBlock:
|
||||
return visitNodes(cbNodes, (<Block>node).statements);
|
||||
@@ -4130,15 +4130,15 @@ namespace ts {
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseSpreadExpression(): Expression {
|
||||
const node = <SpreadExpression>createNode(SyntaxKind.SpreadExpression);
|
||||
function parseSpreadElement(): Expression {
|
||||
const node = <SpreadElement>createNode(SyntaxKind.SpreadElement);
|
||||
parseExpected(SyntaxKind.DotDotDotToken);
|
||||
node.expression = parseAssignmentExpressionOrHigher();
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseArgumentOrArrayLiteralElement(): Expression {
|
||||
return token() === SyntaxKind.DotDotDotToken ? parseSpreadExpression() :
|
||||
return token() === SyntaxKind.DotDotDotToken ? parseSpreadElement() :
|
||||
token() === SyntaxKind.CommaToken ? <Expression>createNode(SyntaxKind.OmittedExpression) :
|
||||
parseAssignmentExpressionOrHigher();
|
||||
}
|
||||
@@ -4173,7 +4173,7 @@ namespace ts {
|
||||
const fullStart = scanner.getStartPos();
|
||||
const dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken);
|
||||
if (dotDotDotToken) {
|
||||
const spreadElement = <SpreadElementExpression>createNode(SyntaxKind.SpreadElementExpression, fullStart);
|
||||
const spreadElement = <SpreadAssignment>createNode(SyntaxKind.SpreadAssignment, fullStart);
|
||||
spreadElement.expression = parseAssignmentExpressionOrHigher();
|
||||
return addJSDocComment(finishNode(spreadElement));
|
||||
}
|
||||
|
||||
+182
-32
@@ -239,11 +239,11 @@ namespace ts {
|
||||
const { line, character } = getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start);
|
||||
const fileName = diagnostic.file.fileName;
|
||||
const relativeFileName = convertToRelativePath(fileName, host.getCurrentDirectory(), fileName => host.getCanonicalFileName(fileName));
|
||||
output += `${ relativeFileName }(${ line + 1 },${ character + 1 }): `;
|
||||
output += `${relativeFileName}(${line + 1},${character + 1}): `;
|
||||
}
|
||||
|
||||
const category = DiagnosticCategory[diagnostic.category].toLowerCase();
|
||||
output += `${ category } TS${ diagnostic.code }: ${ flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine()) }${ host.getNewLine() }`;
|
||||
output += `${category} TS${diagnostic.code}: ${flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine())}${host.getNewLine()}`;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
@@ -462,6 +462,130 @@ namespace ts {
|
||||
return classifiableNames;
|
||||
}
|
||||
|
||||
interface OldProgramState {
|
||||
program: Program;
|
||||
file: SourceFile;
|
||||
modifiedFilePaths: Path[];
|
||||
}
|
||||
|
||||
function resolveModuleNamesReusingOldState(moduleNames: string[], containingFile: string, file: SourceFile, oldProgramState?: OldProgramState) {
|
||||
if (!oldProgramState && !file.ambientModuleNames.length) {
|
||||
// if old program state is not supplied and file does not contain locally defined ambient modules
|
||||
// then the best we can do is fallback to the default logic
|
||||
return resolveModuleNamesWorker(moduleNames, containingFile);
|
||||
}
|
||||
|
||||
// at this point we know that either
|
||||
// - file has local declarations for ambient modules
|
||||
// OR
|
||||
// - old program state is available
|
||||
// OR
|
||||
// - both of items above
|
||||
// With this it is possible that we can tell how some module names from the initial list will be resolved
|
||||
// without doing actual resolution (in particular if some name was resolved to ambient module).
|
||||
// Such names should be excluded from the list of module names that will be provided to `resolveModuleNamesWorker`
|
||||
// since we don't want to resolve them again.
|
||||
|
||||
// this is a list of modules for which we cannot predict resolution so they should be actually resolved
|
||||
let unknownModuleNames: string[];
|
||||
// this is a list of combined results assembles from predicted and resolved results.
|
||||
// Order in this list matches the order in the original list of module names `moduleNames` which is important
|
||||
// so later we can split results to resolutions of modules and resolutions of module augmentations.
|
||||
let result: ResolvedModuleFull[];
|
||||
// a transient placeholder that is used to mark predicted resolution in the result list
|
||||
const predictedToResolveToAmbientModuleMarker: ResolvedModuleFull = <any>{};
|
||||
|
||||
for (let i = 0; i < moduleNames.length; i++) {
|
||||
const moduleName = moduleNames[i];
|
||||
// module name is known to be resolved to ambient module if
|
||||
// - module name is contained in the list of ambient modules that are locally declared in the file
|
||||
// - in the old program module name was resolved to ambient module whose declaration is in non-modified file
|
||||
// (so the same module declaration will land in the new program)
|
||||
let isKnownToResolveToAmbientModule = false;
|
||||
if (contains(file.ambientModuleNames, moduleName)) {
|
||||
isKnownToResolveToAmbientModule = true;
|
||||
if (isTraceEnabled(options, host)) {
|
||||
trace(host, Diagnostics.Module_0_was_resolved_as_locally_declared_ambient_module_in_file_1, moduleName, containingFile);
|
||||
}
|
||||
}
|
||||
else {
|
||||
isKnownToResolveToAmbientModule = checkModuleNameResolvedToAmbientModuleInNonModifiedFile(moduleName, oldProgramState);
|
||||
}
|
||||
|
||||
if (isKnownToResolveToAmbientModule) {
|
||||
if (!unknownModuleNames) {
|
||||
// found a first module name for which result can be prediced
|
||||
// this means that this module name should not be passed to `resolveModuleNamesWorker`.
|
||||
// We'll use a separate list for module names that are definitely unknown.
|
||||
result = new Array(moduleNames.length);
|
||||
// copy all module names that appear before the current one in the list
|
||||
// since they are known to be unknown
|
||||
unknownModuleNames = moduleNames.slice(0, i);
|
||||
}
|
||||
// mark prediced resolution in the result list
|
||||
result[i] = predictedToResolveToAmbientModuleMarker;
|
||||
}
|
||||
else if (unknownModuleNames) {
|
||||
// found unknown module name and we are already using separate list for those - add it to the list
|
||||
unknownModuleNames.push(moduleName);
|
||||
}
|
||||
}
|
||||
|
||||
if (!unknownModuleNames) {
|
||||
// we've looked throught the list but have not seen any predicted resolution
|
||||
// use default logic
|
||||
return resolveModuleNamesWorker(moduleNames, containingFile);
|
||||
}
|
||||
|
||||
const resolutions = unknownModuleNames.length
|
||||
? resolveModuleNamesWorker(unknownModuleNames, containingFile)
|
||||
: emptyArray;
|
||||
|
||||
// combine results of resolutions and predicted results
|
||||
let j = 0;
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
if (result[i] == predictedToResolveToAmbientModuleMarker) {
|
||||
result[i] = undefined;
|
||||
}
|
||||
else {
|
||||
result[i] = resolutions[j];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
Debug.assert(j === resolutions.length);
|
||||
return result;
|
||||
|
||||
function checkModuleNameResolvedToAmbientModuleInNonModifiedFile(moduleName: string, oldProgramState?: OldProgramState): boolean {
|
||||
if (!oldProgramState) {
|
||||
return false;
|
||||
}
|
||||
const resolutionToFile = getResolvedModule(oldProgramState.file, moduleName);
|
||||
if (resolutionToFile) {
|
||||
// module used to be resolved to file - ignore it
|
||||
return false;
|
||||
}
|
||||
const ambientModule = oldProgram.getTypeChecker().tryFindAmbientModuleWithoutAugmentations(moduleName);
|
||||
if (!(ambientModule && ambientModule.declarations)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// at least one of declarations should come from non-modified source file
|
||||
const firstUnmodifiedFile = forEach(ambientModule.declarations, d => {
|
||||
const f = getSourceFileOfNode(d);
|
||||
return !contains(oldProgramState.modifiedFilePaths, f.path) && f;
|
||||
});
|
||||
|
||||
if (!firstUnmodifiedFile) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isTraceEnabled(options, host)) {
|
||||
trace(host, Diagnostics.Module_0_was_resolved_as_ambient_module_declared_in_1_since_this_file_was_not_modified, moduleName, firstUnmodifiedFile.fileName);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function tryReuseStructureFromOldProgram(): boolean {
|
||||
if (!oldProgram) {
|
||||
return false;
|
||||
@@ -489,7 +613,7 @@ namespace ts {
|
||||
// check if program source files has changed in the way that can affect structure of the program
|
||||
const newSourceFiles: SourceFile[] = [];
|
||||
const filePaths: Path[] = [];
|
||||
const modifiedSourceFiles: SourceFile[] = [];
|
||||
const modifiedSourceFiles: { oldFile: SourceFile, newFile: SourceFile }[] = [];
|
||||
|
||||
for (const oldSourceFile of oldProgram.getSourceFiles()) {
|
||||
let newSourceFile = host.getSourceFileByPath
|
||||
@@ -532,29 +656,8 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
const newSourceFilePath = getNormalizedAbsolutePath(newSourceFile.fileName, currentDirectory);
|
||||
if (resolveModuleNamesWorker) {
|
||||
const moduleNames = map(concatenate(newSourceFile.imports, newSourceFile.moduleAugmentations), getTextOfLiteral);
|
||||
const resolutions = resolveModuleNamesWorker(moduleNames, newSourceFilePath);
|
||||
// ensure that module resolution results are still correct
|
||||
const resolutionsChanged = hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, moduleResolutionIsEqualTo);
|
||||
if (resolutionsChanged) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (resolveTypeReferenceDirectiveNamesWorker) {
|
||||
const typesReferenceDirectives = map(newSourceFile.typeReferenceDirectives, x => x.fileName);
|
||||
const resolutions = resolveTypeReferenceDirectiveNamesWorker(typesReferenceDirectives, newSourceFilePath);
|
||||
// ensure that types resolutions are still correct
|
||||
const resolutionsChanged = hasChangesInResolutions(typesReferenceDirectives, resolutions, oldSourceFile.resolvedTypeReferenceDirectiveNames, typeDirectiveIsEqualTo);
|
||||
if (resolutionsChanged) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// pass the cache of module/types resolutions from the old source file
|
||||
newSourceFile.resolvedModules = oldSourceFile.resolvedModules;
|
||||
newSourceFile.resolvedTypeReferenceDirectiveNames = oldSourceFile.resolvedTypeReferenceDirectiveNames;
|
||||
modifiedSourceFiles.push(newSourceFile);
|
||||
// tentatively approve the file
|
||||
modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile });
|
||||
}
|
||||
else {
|
||||
// file has no changes - use it as is
|
||||
@@ -565,6 +668,33 @@ namespace ts {
|
||||
newSourceFiles.push(newSourceFile);
|
||||
}
|
||||
|
||||
const modifiedFilePaths = modifiedSourceFiles.map(f => f.newFile.path);
|
||||
// try to verify results of module resolution
|
||||
for (const { oldFile: oldSourceFile, newFile: newSourceFile } of modifiedSourceFiles) {
|
||||
const newSourceFilePath = getNormalizedAbsolutePath(newSourceFile.fileName, currentDirectory);
|
||||
if (resolveModuleNamesWorker) {
|
||||
const moduleNames = map(concatenate(newSourceFile.imports, newSourceFile.moduleAugmentations), getTextOfLiteral);
|
||||
const resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFilePath, newSourceFile, { file: oldSourceFile, program: oldProgram, modifiedFilePaths });
|
||||
// ensure that module resolution results are still correct
|
||||
const resolutionsChanged = hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, moduleResolutionIsEqualTo);
|
||||
if (resolutionsChanged) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (resolveTypeReferenceDirectiveNamesWorker) {
|
||||
const typesReferenceDirectives = map(newSourceFile.typeReferenceDirectives, x => x.fileName);
|
||||
const resolutions = resolveTypeReferenceDirectiveNamesWorker(typesReferenceDirectives, newSourceFilePath);
|
||||
// ensure that types resolutions are still correct
|
||||
const resolutionsChanged = hasChangesInResolutions(typesReferenceDirectives, resolutions, oldSourceFile.resolvedTypeReferenceDirectiveNames, typeDirectiveIsEqualTo);
|
||||
if (resolutionsChanged) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// pass the cache of module/types resolutions from the old source file
|
||||
newSourceFile.resolvedModules = oldSourceFile.resolvedModules;
|
||||
newSourceFile.resolvedTypeReferenceDirectiveNames = oldSourceFile.resolvedTypeReferenceDirectiveNames;
|
||||
}
|
||||
|
||||
// update fileName -> file mapping
|
||||
for (let i = 0, len = newSourceFiles.length; i < len; i++) {
|
||||
filesByName.set(filePaths[i], newSourceFiles[i]);
|
||||
@@ -574,7 +704,7 @@ namespace ts {
|
||||
fileProcessingDiagnostics = oldProgram.getFileProcessingDiagnostics();
|
||||
|
||||
for (const modifiedFile of modifiedSourceFiles) {
|
||||
fileProcessingDiagnostics.reattachFileDiagnostics(modifiedFile);
|
||||
fileProcessingDiagnostics.reattachFileDiagnostics(modifiedFile.newFile);
|
||||
}
|
||||
resolvedTypeReferenceDirectives = oldProgram.getResolvedTypeReferenceDirectives();
|
||||
oldProgram.structureIsReused = true;
|
||||
@@ -994,9 +1124,11 @@ namespace ts {
|
||||
|
||||
const isJavaScriptFile = isSourceFileJavaScript(file);
|
||||
const isExternalModuleFile = isExternalModule(file);
|
||||
const isDtsFile = isDeclarationFile(file);
|
||||
|
||||
let imports: LiteralExpression[];
|
||||
let moduleAugmentations: LiteralExpression[];
|
||||
let ambientModules: string[];
|
||||
|
||||
// If we are importing helpers, we need to add a synthetic reference to resolve the
|
||||
// helpers library.
|
||||
@@ -1018,6 +1150,7 @@ namespace ts {
|
||||
|
||||
file.imports = imports || emptyArray;
|
||||
file.moduleAugmentations = moduleAugmentations || emptyArray;
|
||||
file.ambientModuleNames = ambientModules || emptyArray;
|
||||
|
||||
return;
|
||||
|
||||
@@ -1053,6 +1186,10 @@ namespace ts {
|
||||
(moduleAugmentations || (moduleAugmentations = [])).push(moduleName);
|
||||
}
|
||||
else if (!inAmbientModule) {
|
||||
if (isDtsFile) {
|
||||
// for global .d.ts files record name of ambient module
|
||||
(ambientModules || (ambientModules = [])).push(moduleName.text);
|
||||
}
|
||||
// An AmbientExternalModuleDeclaration declares an external module.
|
||||
// This type of declaration is permitted only in the global module.
|
||||
// The StringLiteral must specify a top - level external module name.
|
||||
@@ -1298,7 +1435,7 @@ namespace ts {
|
||||
if (file.imports.length || file.moduleAugmentations.length) {
|
||||
file.resolvedModules = createMap<ResolvedModuleFull>();
|
||||
const moduleNames = map(concatenate(file.imports, file.moduleAugmentations), getTextOfLiteral);
|
||||
const resolutions = resolveModuleNamesWorker(moduleNames, getNormalizedAbsolutePath(file.fileName, currentDirectory));
|
||||
const resolutions = resolveModuleNamesReusingOldState(moduleNames, getNormalizedAbsolutePath(file.fileName, currentDirectory), file);
|
||||
Debug.assert(resolutions.length === moduleNames.length);
|
||||
for (let i = 0; i < moduleNames.length; i++) {
|
||||
const resolution = resolutions[i];
|
||||
@@ -1548,13 +1685,24 @@ namespace ts {
|
||||
const emitFilePath = toPath(emitFileName, currentDirectory, getCanonicalFileName);
|
||||
// Report error if the output overwrites input file
|
||||
if (filesByName.contains(emitFilePath)) {
|
||||
createEmitBlockingDiagnostics(emitFileName, Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file);
|
||||
if (options.noEmitOverwritenFiles && !options.out && !options.outDir && !options.outFile) {
|
||||
blockEmittingOfFile(emitFileName);
|
||||
}
|
||||
else {
|
||||
let chain: DiagnosticMessageChain;
|
||||
if (!options.configFilePath) {
|
||||
// The program is from either an inferred project or an external project
|
||||
chain = chainDiagnosticMessages(/*details*/ undefined, Diagnostics.Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript_files_Learn_more_at_https_Colon_Slash_Slashaka_ms_Slashtsconfig);
|
||||
}
|
||||
chain = chainDiagnosticMessages(chain, Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file, emitFileName);
|
||||
blockEmittingOfFile(emitFileName, createCompilerDiagnosticFromMessageChain(chain));
|
||||
}
|
||||
}
|
||||
|
||||
// Report error if multiple files write into same file
|
||||
if (emitFilesSeen.contains(emitFilePath)) {
|
||||
// Already seen the same emit file - report error
|
||||
createEmitBlockingDiagnostics(emitFileName, Diagnostics.Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files);
|
||||
blockEmittingOfFile(emitFileName, createCompilerDiagnostic(Diagnostics.Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files, emitFileName));
|
||||
}
|
||||
else {
|
||||
emitFilesSeen.set(emitFilePath, true);
|
||||
@@ -1563,9 +1711,11 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function createEmitBlockingDiagnostics(emitFileName: string, message: DiagnosticMessage) {
|
||||
function blockEmittingOfFile(emitFileName: string, diag?: Diagnostic) {
|
||||
hasEmitBlockingDiagnostics.set(toPath(emitFileName, currentDirectory, getCanonicalFileName), true);
|
||||
programDiagnostics.add(createCompilerDiagnostic(message, emitFileName));
|
||||
if (diag) {
|
||||
programDiagnostics.add(diag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -117,7 +117,10 @@ namespace ts {
|
||||
transformers.push(transformJsx);
|
||||
}
|
||||
|
||||
transformers.push(transformESNext);
|
||||
if (languageVersion < ScriptTarget.ESNext) {
|
||||
transformers.push(transformESNext);
|
||||
}
|
||||
|
||||
if (languageVersion < ScriptTarget.ES2017) {
|
||||
transformers.push(transformES2017);
|
||||
}
|
||||
|
||||
@@ -325,13 +325,13 @@ namespace ts {
|
||||
emitDestructuringAssignment(bindingTarget, createDestructuringPropertyAccess(value, propName), p);
|
||||
}
|
||||
}
|
||||
else if (i === properties.length - 1 && p.kind === SyntaxKind.SpreadElementExpression) {
|
||||
Debug.assert((p as SpreadElementExpression).expression.kind === SyntaxKind.Identifier);
|
||||
else if (i === properties.length - 1 && p.kind === SyntaxKind.SpreadAssignment) {
|
||||
Debug.assert((p as SpreadAssignment).expression.kind === SyntaxKind.Identifier);
|
||||
if (es2015.length) {
|
||||
emitRestAssignment(es2015, value, location, target);
|
||||
es2015 = [];
|
||||
}
|
||||
const propName = (p as SpreadElementExpression).expression as Identifier;
|
||||
const propName = (p as SpreadAssignment).expression as Identifier;
|
||||
const restCall = createRestCall(value, target.properties, p => p.name, target);
|
||||
emitDestructuringAssignment(propName, restCall, p);
|
||||
}
|
||||
@@ -356,11 +356,11 @@ namespace ts {
|
||||
const e = elements[i];
|
||||
if (e.kind !== SyntaxKind.OmittedExpression) {
|
||||
// Assignment for target = value.propName should highligh whole property, hence use e as source map node
|
||||
if (e.kind !== SyntaxKind.SpreadExpression) {
|
||||
if (e.kind !== SyntaxKind.SpreadElement) {
|
||||
emitDestructuringAssignment(e, createElementAccess(value, createLiteral(i)), e);
|
||||
}
|
||||
else if (i === numElements - 1) {
|
||||
emitDestructuringAssignment((<SpreadExpression>e).expression, createArraySlice(value, i), e);
|
||||
emitDestructuringAssignment((<SpreadElement>e).expression, createArraySlice(value, i), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2400,7 +2400,7 @@ namespace ts {
|
||||
*
|
||||
* @param node A SpreadExpression node.
|
||||
*/
|
||||
function visitExpressionOfSpread(node: SpreadExpression) {
|
||||
function visitExpressionOfSpread(node: SpreadElement) {
|
||||
return visitNode(node.expression, visitor, isExpression);
|
||||
}
|
||||
|
||||
@@ -2776,11 +2776,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
const callArgument = singleOrUndefined((<CallExpression>statementExpression).arguments);
|
||||
if (!callArgument || !nodeIsSynthesized(callArgument) || callArgument.kind !== SyntaxKind.SpreadExpression) {
|
||||
if (!callArgument || !nodeIsSynthesized(callArgument) || callArgument.kind !== SyntaxKind.SpreadElement) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const expression = (<SpreadExpression>callArgument).expression;
|
||||
const expression = (<SpreadElement>callArgument).expression;
|
||||
return isIdentifier(expression) && expression === parameter.name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,12 +58,12 @@ namespace ts {
|
||||
let chunkObject: (ShorthandPropertyAssignment | PropertyAssignment)[];
|
||||
const objects: Expression[] = [];
|
||||
for (const e of elements) {
|
||||
if (e.kind === SyntaxKind.SpreadElementExpression) {
|
||||
if (e.kind === SyntaxKind.SpreadAssignment) {
|
||||
if (chunkObject) {
|
||||
objects.push(createObjectLiteral(chunkObject));
|
||||
chunkObject = undefined;
|
||||
}
|
||||
const target = (e as SpreadElementExpression).expression;
|
||||
const target = (e as SpreadAssignment).expression;
|
||||
objects.push(visitNode(target, visitor, isExpression));
|
||||
}
|
||||
else {
|
||||
|
||||
+14
-11
@@ -246,7 +246,7 @@ namespace ts {
|
||||
ConditionalExpression,
|
||||
TemplateExpression,
|
||||
YieldExpression,
|
||||
SpreadExpression,
|
||||
SpreadElement,
|
||||
ClassExpression,
|
||||
OmittedExpression,
|
||||
ExpressionWithTypeArguments,
|
||||
@@ -320,7 +320,7 @@ namespace ts {
|
||||
// Property assignments
|
||||
PropertyAssignment,
|
||||
ShorthandPropertyAssignment,
|
||||
SpreadElementExpression,
|
||||
SpreadAssignment,
|
||||
|
||||
// Enum
|
||||
EnumMember,
|
||||
@@ -663,7 +663,6 @@ namespace ts {
|
||||
initializer?: Expression; // Optional initializer
|
||||
}
|
||||
|
||||
// @kind(SyntaxKind.PropertyDeclaration)
|
||||
export interface PropertyDeclaration extends ClassElement {
|
||||
kind: SyntaxKind.PropertyDeclaration;
|
||||
questionToken?: QuestionToken; // Present for use with reporting a grammar error
|
||||
@@ -677,7 +676,7 @@ namespace ts {
|
||||
name?: PropertyName;
|
||||
}
|
||||
|
||||
export type ObjectLiteralElementLike = PropertyAssignment | ShorthandPropertyAssignment | MethodDeclaration | AccessorDeclaration | SpreadElementExpression;
|
||||
export type ObjectLiteralElementLike = PropertyAssignment | ShorthandPropertyAssignment | MethodDeclaration | AccessorDeclaration | SpreadAssignment;
|
||||
|
||||
export interface PropertyAssignment extends ObjectLiteralElement {
|
||||
kind: SyntaxKind.PropertyAssignment;
|
||||
@@ -696,8 +695,8 @@ namespace ts {
|
||||
objectAssignmentInitializer?: Expression;
|
||||
}
|
||||
|
||||
export interface SpreadElementExpression extends ObjectLiteralElement {
|
||||
kind: SyntaxKind.SpreadElementExpression;
|
||||
export interface SpreadAssignment extends ObjectLiteralElement {
|
||||
kind: SyntaxKind.SpreadAssignment;
|
||||
expression: Expression;
|
||||
}
|
||||
|
||||
@@ -1286,9 +1285,8 @@ namespace ts {
|
||||
multiLine?: boolean;
|
||||
}
|
||||
|
||||
// @kind(SyntaxKind.SpreadExpression)
|
||||
export interface SpreadExpression extends Expression {
|
||||
kind: SyntaxKind.SpreadExpression;
|
||||
export interface SpreadElement extends Expression {
|
||||
kind: SyntaxKind.SpreadElement;
|
||||
expression: Expression;
|
||||
}
|
||||
|
||||
@@ -2110,6 +2108,7 @@ namespace ts {
|
||||
/* @internal */ imports: LiteralExpression[];
|
||||
/* @internal */ moduleAugmentations: LiteralExpression[];
|
||||
/* @internal */ patternAmbientModules?: PatternAmbientModule[];
|
||||
/* @internal */ ambientModuleNames: string[];
|
||||
// The synthesized identifier for an imported external helpers module.
|
||||
/* @internal */ externalHelpersModuleName?: Identifier;
|
||||
}
|
||||
@@ -2304,6 +2303,8 @@ namespace ts {
|
||||
isOptionalParameter(node: ParameterDeclaration): boolean;
|
||||
getAmbientModules(): Symbol[];
|
||||
|
||||
/* @internal */ tryFindAmbientModuleWithoutAugmentations(moduleName: string): Symbol;
|
||||
|
||||
// Should not be called directly. Should only be accessed through the Program instance.
|
||||
/* @internal */ getDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[];
|
||||
/* @internal */ getGlobalDiagnostics(): Diagnostic[];
|
||||
@@ -2723,7 +2724,7 @@ namespace ts {
|
||||
EnumLike = Enum | EnumLiteral,
|
||||
UnionOrIntersection = Union | Intersection,
|
||||
StructuredType = Object | Union | Intersection,
|
||||
StructuredOrTypeParameter = StructuredType | TypeParameter,
|
||||
StructuredOrTypeParameter = StructuredType | TypeParameter | Index,
|
||||
|
||||
// 'Narrowable' types are types where narrowing actually narrows.
|
||||
// This *should* be every type other than null, undefined, void, and never
|
||||
@@ -3072,6 +3073,7 @@ namespace ts {
|
||||
moduleResolution?: ModuleResolutionKind;
|
||||
newLine?: NewLineKind;
|
||||
noEmit?: boolean;
|
||||
/*@internal*/noEmitOverwritenFiles?: boolean;
|
||||
noEmitHelpers?: boolean;
|
||||
noEmitOnError?: boolean;
|
||||
noErrorTruncation?: boolean;
|
||||
@@ -3174,7 +3176,8 @@ namespace ts {
|
||||
ES2015 = 2,
|
||||
ES2016 = 3,
|
||||
ES2017 = 4,
|
||||
Latest = ES2017,
|
||||
ESNext = 5,
|
||||
Latest = ESNext,
|
||||
}
|
||||
|
||||
export const enum LanguageVariant {
|
||||
|
||||
@@ -1195,7 +1195,7 @@ namespace ts {
|
||||
case SyntaxKind.PostfixUnaryExpression:
|
||||
case SyntaxKind.BinaryExpression:
|
||||
case SyntaxKind.ConditionalExpression:
|
||||
case SyntaxKind.SpreadExpression:
|
||||
case SyntaxKind.SpreadElement:
|
||||
case SyntaxKind.TemplateExpression:
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
case SyntaxKind.OmittedExpression:
|
||||
@@ -1657,7 +1657,7 @@ namespace ts {
|
||||
return (<ForInStatement | ForOfStatement>parent).initializer === node ? AssignmentKind.Definite : AssignmentKind.None;
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
case SyntaxKind.SpreadExpression:
|
||||
case SyntaxKind.SpreadElement:
|
||||
node = parent;
|
||||
break;
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
@@ -2242,7 +2242,7 @@ namespace ts {
|
||||
case SyntaxKind.YieldExpression:
|
||||
return 2;
|
||||
|
||||
case SyntaxKind.SpreadExpression:
|
||||
case SyntaxKind.SpreadElement:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
@@ -3878,7 +3878,7 @@ namespace ts {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.PropertyAssignment
|
||||
|| kind === SyntaxKind.ShorthandPropertyAssignment
|
||||
|| kind === SyntaxKind.SpreadElementExpression
|
||||
|| kind === SyntaxKind.SpreadAssignment
|
||||
|| kind === SyntaxKind.MethodDeclaration
|
||||
|| kind === SyntaxKind.GetAccessor
|
||||
|| kind === SyntaxKind.SetAccessor
|
||||
@@ -3966,8 +3966,8 @@ namespace ts {
|
||||
|| kind === SyntaxKind.NoSubstitutionTemplateLiteral;
|
||||
}
|
||||
|
||||
export function isSpreadExpression(node: Node): node is SpreadExpression {
|
||||
return node.kind === SyntaxKind.SpreadExpression;
|
||||
export function isSpreadExpression(node: Node): node is SpreadElement {
|
||||
return node.kind === SyntaxKind.SpreadElement;
|
||||
}
|
||||
|
||||
export function isExpressionWithTypeArguments(node: Node): node is ExpressionWithTypeArguments {
|
||||
@@ -4025,7 +4025,7 @@ namespace ts {
|
||||
|| kind === SyntaxKind.YieldExpression
|
||||
|| kind === SyntaxKind.ArrowFunction
|
||||
|| kind === SyntaxKind.BinaryExpression
|
||||
|| kind === SyntaxKind.SpreadExpression
|
||||
|| kind === SyntaxKind.SpreadElement
|
||||
|| kind === SyntaxKind.AsExpression
|
||||
|| kind === SyntaxKind.OmittedExpression
|
||||
|| isUnaryExpressionKind(kind);
|
||||
|
||||
+16
-6
@@ -267,9 +267,9 @@ namespace ts {
|
||||
case SyntaxKind.VoidExpression:
|
||||
case SyntaxKind.AwaitExpression:
|
||||
case SyntaxKind.YieldExpression:
|
||||
case SyntaxKind.SpreadExpression:
|
||||
case SyntaxKind.SpreadElement:
|
||||
case SyntaxKind.NonNullExpression:
|
||||
result = reduceNode((<ParenthesizedExpression | DeleteExpression | TypeOfExpression | VoidExpression | AwaitExpression | YieldExpression | SpreadExpression | NonNullExpression>node).expression, f, result);
|
||||
result = reduceNode((<ParenthesizedExpression | DeleteExpression | TypeOfExpression | VoidExpression | AwaitExpression | YieldExpression | SpreadElement | NonNullExpression>node).expression, f, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.PrefixUnaryExpression:
|
||||
@@ -510,6 +510,10 @@ namespace ts {
|
||||
result = reduceNode((<ShorthandPropertyAssignment>node).objectAssignmentInitializer, f, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.SpreadAssignment:
|
||||
result = reduceNode((node as SpreadAssignment).expression, f, result);
|
||||
break;
|
||||
|
||||
// Top-level nodes
|
||||
case SyntaxKind.SourceFile:
|
||||
result = reduceLeft((<SourceFile>node).statements, f, result);
|
||||
@@ -553,6 +557,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
aggregateTransformFlags(node);
|
||||
const visited = visitor(node);
|
||||
if (visited === node) {
|
||||
return node;
|
||||
@@ -621,6 +626,7 @@ namespace ts {
|
||||
// Visit each original node.
|
||||
for (let i = 0; i < count; i++) {
|
||||
const node = nodes[i + start];
|
||||
aggregateTransformFlags(node);
|
||||
const visited = node !== undefined ? visitor(node) : undefined;
|
||||
if (updated !== undefined || visited === undefined || visited !== node) {
|
||||
if (updated === undefined) {
|
||||
@@ -870,9 +876,9 @@ namespace ts {
|
||||
return updateYield(<YieldExpression>node,
|
||||
visitNode((<YieldExpression>node).expression, visitor, isExpression));
|
||||
|
||||
case SyntaxKind.SpreadExpression:
|
||||
return updateSpread(<SpreadExpression>node,
|
||||
visitNode((<SpreadExpression>node).expression, visitor, isExpression));
|
||||
case SyntaxKind.SpreadElement:
|
||||
return updateSpread(<SpreadElement>node,
|
||||
visitNode((<SpreadElement>node).expression, visitor, isExpression));
|
||||
|
||||
case SyntaxKind.ClassExpression:
|
||||
return updateClassExpression(<ClassExpression>node,
|
||||
@@ -1125,7 +1131,11 @@ namespace ts {
|
||||
visitNode((<ShorthandPropertyAssignment>node).name, visitor, isIdentifier),
|
||||
visitNode((<ShorthandPropertyAssignment>node).objectAssignmentInitializer, visitor, isExpression));
|
||||
|
||||
// Top-level nodes
|
||||
case SyntaxKind.SpreadAssignment:
|
||||
return updateSpreadAssignment(node as SpreadAssignment,
|
||||
visitNode((node as SpreadAssignment).expression, visitor, isExpression));
|
||||
|
||||
// Top-level nodes
|
||||
case SyntaxKind.SourceFile:
|
||||
context.startLexicalEnvironment();
|
||||
return updateSourceFileNode(<SourceFile>node,
|
||||
|
||||
Reference in New Issue
Block a user