mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into disambiguating
This commit is contained in:
+14
-8
@@ -518,15 +518,21 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
declareSymbolAndAddToSymbolTable(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes);
|
||||
|
||||
let currentModuleIsConstEnumOnly = state === ModuleInstanceState.ConstEnumOnly;
|
||||
if (node.symbol.constEnumOnlyModule === undefined) {
|
||||
// non-merged case - use the current state
|
||||
node.symbol.constEnumOnlyModule = currentModuleIsConstEnumOnly;
|
||||
if (node.symbol.flags & (SymbolFlags.Function | SymbolFlags.Class | SymbolFlags.RegularEnum)) {
|
||||
// if module was already merged with some function, class or non-const enum
|
||||
// treat is a non-const-enum-only
|
||||
node.symbol.constEnumOnlyModule = false;
|
||||
}
|
||||
else {
|
||||
// merged case: module is const enum only if all its pieces are non-instantiated or const enum
|
||||
node.symbol.constEnumOnlyModule = node.symbol.constEnumOnlyModule && currentModuleIsConstEnumOnly;
|
||||
let currentModuleIsConstEnumOnly = state === ModuleInstanceState.ConstEnumOnly;
|
||||
if (node.symbol.constEnumOnlyModule === undefined) {
|
||||
// non-merged case - use the current state
|
||||
node.symbol.constEnumOnlyModule = currentModuleIsConstEnumOnly;
|
||||
}
|
||||
else {
|
||||
// merged case: module is const enum only if all its pieces are non-instantiated or const enum
|
||||
node.symbol.constEnumOnlyModule = node.symbol.constEnumOnlyModule && currentModuleIsConstEnumOnly;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1056,4 +1062,4 @@ namespace ts {
|
||||
: declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+380
-219
@@ -59,17 +59,21 @@ namespace ts {
|
||||
isArgumentsSymbol: symbol => symbol === argumentsSymbol,
|
||||
getDiagnostics,
|
||||
getGlobalDiagnostics,
|
||||
getTypeOfSymbolAtLocation,
|
||||
|
||||
// The language service will always care about the narrowed type of a symbol, because that is
|
||||
// the type the language says the symbol should have.
|
||||
getTypeOfSymbolAtLocation: getNarrowedTypeOfSymbol,
|
||||
getDeclaredTypeOfSymbol,
|
||||
getPropertiesOfType,
|
||||
getPropertyOfType,
|
||||
getSignaturesOfType,
|
||||
getIndexTypeOfType,
|
||||
getBaseTypes,
|
||||
getReturnTypeOfSignature,
|
||||
getSymbolsInScope,
|
||||
getSymbolAtLocation,
|
||||
getShorthandAssignmentValueSymbol,
|
||||
getTypeAtLocation,
|
||||
getTypeAtLocation: getTypeOfNode,
|
||||
typeToString,
|
||||
getSymbolDisplayBuilder,
|
||||
symbolToString,
|
||||
@@ -159,8 +163,9 @@ namespace ts {
|
||||
let emitAwaiter = false;
|
||||
let emitGenerator = false;
|
||||
|
||||
let resolutionTargets: Object[] = [];
|
||||
let resolutionTargets: TypeSystemEntity[] = [];
|
||||
let resolutionResults: boolean[] = [];
|
||||
let resolutionPropertyNames: TypeSystemPropertyName[] = [];
|
||||
|
||||
let mergedSymbols: Symbol[] = [];
|
||||
let symbolLinks: SymbolLinks[] = [];
|
||||
@@ -201,6 +206,15 @@ namespace ts {
|
||||
let assignableRelation: Map<RelationComparisonResult> = {};
|
||||
let identityRelation: Map<RelationComparisonResult> = {};
|
||||
|
||||
type TypeSystemEntity = Symbol | Type | Signature;
|
||||
|
||||
const enum TypeSystemPropertyName {
|
||||
Type,
|
||||
ResolvedBaseConstructorType,
|
||||
DeclaredType,
|
||||
ResolvedReturnType
|
||||
}
|
||||
|
||||
initializeTypeChecker();
|
||||
|
||||
return checker;
|
||||
@@ -1992,15 +2006,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
return _displayBuilder || (_displayBuilder = {
|
||||
symbolToString: symbolToString,
|
||||
typeToString: typeToString,
|
||||
buildSymbolDisplay: buildSymbolDisplay,
|
||||
buildTypeDisplay: buildTypeDisplay,
|
||||
buildTypeParameterDisplay: buildTypeParameterDisplay,
|
||||
buildParameterDisplay: buildParameterDisplay,
|
||||
buildDisplayForParametersAndDelimiters: buildDisplayForParametersAndDelimiters,
|
||||
buildDisplayForTypeParametersAndDelimiters: buildDisplayForTypeParametersAndDelimiters,
|
||||
buildDisplayForTypeArgumentsAndDelimiters: buildDisplayForTypeArgumentsAndDelimiters,
|
||||
buildTypeParameterDisplayFromSymbol: buildTypeParameterDisplayFromSymbol,
|
||||
buildSignatureDisplay: buildSignatureDisplay,
|
||||
buildReturnTypeDisplay: buildReturnTypeDisplay
|
||||
@@ -2189,35 +2200,69 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
// Push an entry on the type resolution stack. If an entry with the given target is not already on the stack,
|
||||
// a new entry with that target and an associated result value of true is pushed on the stack, and the value
|
||||
// true is returned. Otherwise, a circularity has occurred and the result values of the existing entry and
|
||||
// all entries pushed after it are changed to false, and the value false is returned. The target object provides
|
||||
// a unique identity for a particular type resolution result: Symbol instances are used to track resolution of
|
||||
// SymbolLinks.type, SymbolLinks instances are used to track resolution of SymbolLinks.declaredType, and
|
||||
// Signature instances are used to track resolution of Signature.resolvedReturnType.
|
||||
function pushTypeResolution(target: Object): boolean {
|
||||
let i = 0;
|
||||
let count = resolutionTargets.length;
|
||||
while (i < count && resolutionTargets[i] !== target) {
|
||||
i++;
|
||||
}
|
||||
if (i < count) {
|
||||
do {
|
||||
resolutionResults[i++] = false;
|
||||
/**
|
||||
* Push an entry on the type resolution stack. If an entry with the given target and the given property name
|
||||
* is already on the stack, and no entries in between already have a type, then a circularity has occurred.
|
||||
* In this case, the result values of the existing entry and all entries pushed after it are changed to false,
|
||||
* and the value false is returned. Otherwise, the new entry is just pushed onto the stack, and true is returned.
|
||||
* In order to see if the same query has already been done before, the target object and the propertyName both
|
||||
* must match the one passed in.
|
||||
*
|
||||
* @param target The symbol, type, or signature whose type is being queried
|
||||
* @param propertyName The property name that should be used to query the target for its type
|
||||
*/
|
||||
function pushTypeResolution(target: TypeSystemEntity, propertyName: TypeSystemPropertyName): boolean {
|
||||
let resolutionCycleStartIndex = findResolutionCycleStartIndex(target, propertyName);
|
||||
if (resolutionCycleStartIndex >= 0) {
|
||||
// A cycle was found
|
||||
let { length } = resolutionTargets;
|
||||
for (let i = resolutionCycleStartIndex; i < length; i++) {
|
||||
resolutionResults[i] = false;
|
||||
}
|
||||
while (i < count);
|
||||
return false;
|
||||
}
|
||||
resolutionTargets.push(target);
|
||||
resolutionResults.push(true);
|
||||
resolutionPropertyNames.push(propertyName);
|
||||
return true;
|
||||
}
|
||||
|
||||
function findResolutionCycleStartIndex(target: TypeSystemEntity, propertyName: TypeSystemPropertyName): number {
|
||||
for (let i = resolutionTargets.length - 1; i >= 0; i--) {
|
||||
if (hasType(resolutionTargets[i], resolutionPropertyNames[i])) {
|
||||
return -1;
|
||||
}
|
||||
if (resolutionTargets[i] === target && resolutionPropertyNames[i] === propertyName) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
function hasType(target: TypeSystemEntity, propertyName: TypeSystemPropertyName): Type {
|
||||
if (propertyName === TypeSystemPropertyName.Type) {
|
||||
return getSymbolLinks(<Symbol>target).type;
|
||||
}
|
||||
if (propertyName === TypeSystemPropertyName.DeclaredType) {
|
||||
return getSymbolLinks(<Symbol>target).declaredType;
|
||||
}
|
||||
if (propertyName === TypeSystemPropertyName.ResolvedBaseConstructorType) {
|
||||
Debug.assert(!!((<Type>target).flags & TypeFlags.Class));
|
||||
return (<InterfaceType>target).resolvedBaseConstructorType;
|
||||
}
|
||||
if (propertyName === TypeSystemPropertyName.ResolvedReturnType) {
|
||||
return (<Signature>target).resolvedReturnType;
|
||||
}
|
||||
|
||||
Debug.fail("Unhandled TypeSystemPropertyName " + propertyName);
|
||||
}
|
||||
|
||||
// Pop an entry from the type resolution stack and return its associated result value. The result value will
|
||||
// be true if no circularities were detected, or false if a circularity was found.
|
||||
function popTypeResolution(): boolean {
|
||||
resolutionTargets.pop();
|
||||
resolutionPropertyNames.pop();
|
||||
return resolutionResults.pop();
|
||||
}
|
||||
|
||||
@@ -2480,7 +2525,7 @@ namespace ts {
|
||||
return links.type = checkExpression((<ExportAssignment>declaration).expression);
|
||||
}
|
||||
// Handle variable, parameter or property
|
||||
if (!pushTypeResolution(symbol)) {
|
||||
if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) {
|
||||
return unknownType;
|
||||
}
|
||||
let type = getWidenedTypeForVariableLikeDeclaration(<VariableLikeDeclaration>declaration, /*reportErrors*/ true);
|
||||
@@ -2521,7 +2566,7 @@ namespace ts {
|
||||
function getTypeOfAccessors(symbol: Symbol): Type {
|
||||
let links = getSymbolLinks(symbol);
|
||||
if (!links.type) {
|
||||
if (!pushTypeResolution(symbol)) {
|
||||
if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) {
|
||||
return unknownType;
|
||||
}
|
||||
let getter = <AccessorDeclaration>getDeclarationOfKind(symbol, SyntaxKind.GetAccessor);
|
||||
@@ -2737,7 +2782,7 @@ namespace ts {
|
||||
if (!baseTypeNode) {
|
||||
return type.resolvedBaseConstructorType = undefinedType;
|
||||
}
|
||||
if (!pushTypeResolution(type)) {
|
||||
if (!pushTypeResolution(type, TypeSystemPropertyName.ResolvedBaseConstructorType)) {
|
||||
return unknownType;
|
||||
}
|
||||
let baseConstructorType = checkExpression(baseTypeNode.expression);
|
||||
@@ -2864,7 +2909,7 @@ namespace ts {
|
||||
if (!links.declaredType) {
|
||||
// Note that we use the links object as the target here because the symbol object is used as the unique
|
||||
// identity for resolution of the 'type' property in SymbolLinks.
|
||||
if (!pushTypeResolution(links)) {
|
||||
if (!pushTypeResolution(symbol, TypeSystemPropertyName.DeclaredType)) {
|
||||
return unknownType;
|
||||
}
|
||||
let declaration = <TypeAliasDeclaration>getDeclarationOfKind(symbol, SyntaxKind.TypeAliasDeclaration);
|
||||
@@ -3080,44 +3125,57 @@ namespace ts {
|
||||
setObjectTypeMembers(type, members, arrayType.callSignatures, arrayType.constructSignatures, arrayType.stringIndexType, arrayType.numberIndexType);
|
||||
}
|
||||
|
||||
function signatureListsIdentical(s: Signature[], t: Signature[]): boolean {
|
||||
if (s.length !== t.length) {
|
||||
return false;
|
||||
}
|
||||
for (let i = 0; i < s.length; i++) {
|
||||
if (!compareSignatures(s[i], t[i], /*compareReturnTypes*/ false, compareTypes)) {
|
||||
return false;
|
||||
function findMatchingSignature(signature: Signature, signatureList: Signature[]): Signature {
|
||||
for (let s of signatureList) {
|
||||
// Only signatures with no type parameters may differ in return types
|
||||
if (compareSignatures(signature, s, /*compareReturnTypes*/ !!signature.typeParameters, compareTypes)) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// If the lists of call or construct signatures in the given types are all identical except for return types,
|
||||
// and if none of the signatures are generic, return a list of signatures that has substitutes a union of the
|
||||
// return types of the corresponding signatures in each resulting signature.
|
||||
function getUnionSignatures(types: Type[], kind: SignatureKind): Signature[] {
|
||||
let signatureLists = map(types, t => getSignaturesOfType(t, kind));
|
||||
let signatures = signatureLists[0];
|
||||
for (let signature of signatures) {
|
||||
if (signature.typeParameters) {
|
||||
return emptyArray;
|
||||
}
|
||||
}
|
||||
function findMatchingSignatures(signature: Signature, signatureLists: Signature[][]): Signature[] {
|
||||
let result: Signature[] = undefined;
|
||||
for (let i = 1; i < signatureLists.length; i++) {
|
||||
if (!signatureListsIdentical(signatures, signatureLists[i])) {
|
||||
return emptyArray;
|
||||
let match = findMatchingSignature(signature, signatureLists[i]);
|
||||
if (!match) {
|
||||
return undefined;
|
||||
}
|
||||
if (!result) {
|
||||
result = [signature];
|
||||
}
|
||||
if (match !== signature) {
|
||||
result.push(match);
|
||||
}
|
||||
}
|
||||
let result = map(signatures, cloneSignature);
|
||||
for (var i = 0; i < result.length; i++) {
|
||||
let s = result[i];
|
||||
// Clear resolved return type we possibly got from cloneSignature
|
||||
s.resolvedReturnType = undefined;
|
||||
s.unionSignatures = map(signatureLists, signatures => signatures[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// The signatures of a union type are those signatures that are present and identical in each of the
|
||||
// constituent types, except that non-generic signatures may differ in return types. When signatures
|
||||
// differ in return types, the resulting return type is the union of the constituent return types.
|
||||
function getUnionSignatures(types: Type[], kind: SignatureKind): Signature[] {
|
||||
let signatureLists = map(types, t => getSignaturesOfType(t, kind));
|
||||
let result: Signature[] = undefined;
|
||||
for (let source of signatureLists[0]) {
|
||||
let unionSignatures = findMatchingSignatures(source, signatureLists);
|
||||
if (unionSignatures) {
|
||||
let signature: Signature = undefined;
|
||||
if (unionSignatures.length === 1 || source.typeParameters) {
|
||||
signature = source;
|
||||
}
|
||||
else {
|
||||
signature = cloneSignature(source);
|
||||
// Clear resolved return type we possibly got from cloneSignature
|
||||
signature.resolvedReturnType = undefined;
|
||||
signature.unionSignatures = unionSignatures;
|
||||
}
|
||||
(result || (result = [])).push(signature);
|
||||
}
|
||||
}
|
||||
return result || emptyArray;
|
||||
}
|
||||
|
||||
function getUnionIndexType(types: Type[], kind: IndexKind): Type {
|
||||
let indexTypes: Type[] = [];
|
||||
for (let type of types) {
|
||||
@@ -3275,9 +3333,6 @@ namespace ts {
|
||||
* type itself. Note that the apparent type of a union type is the union type itself.
|
||||
*/
|
||||
function getApparentType(type: Type): Type {
|
||||
if (type.flags & TypeFlags.Union) {
|
||||
type = getReducedTypeOfUnionType(<UnionType>type);
|
||||
}
|
||||
if (type.flags & TypeFlags.TypeParameter) {
|
||||
do {
|
||||
type = getConstraintOfTypeParameter(<TypeParameter>type);
|
||||
@@ -3382,6 +3437,29 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Check if a property with the given name is known anywhere in the given type. In an object
|
||||
// type, a property is considered known if the object type is empty, if it has any index
|
||||
// signatures, or if the property is actually declared in the type. In a union or intersection
|
||||
// type, a property is considered known if it is known in any constituent type.
|
||||
function isKnownProperty(type: Type, name: string): boolean {
|
||||
if (type.flags & TypeFlags.ObjectType && type !== globalObjectType) {
|
||||
var resolved = resolveStructuredTypeMembers(type);
|
||||
return !!(resolved.properties.length === 0 ||
|
||||
resolved.stringIndexType ||
|
||||
resolved.numberIndexType ||
|
||||
getPropertyOfType(type, name));
|
||||
}
|
||||
if (type.flags & TypeFlags.UnionOrIntersection) {
|
||||
for (let t of (<UnionOrIntersectionType>type).types) {
|
||||
if (isKnownProperty(t, name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function getSignaturesOfStructuredType(type: Type, kind: SignatureKind): Signature[] {
|
||||
if (type.flags & TypeFlags.StructuredType) {
|
||||
let resolved = resolveStructuredTypeMembers(<ObjectType>type);
|
||||
@@ -3551,7 +3629,7 @@ namespace ts {
|
||||
|
||||
function getReturnTypeOfSignature(signature: Signature): Type {
|
||||
if (!signature.resolvedReturnType) {
|
||||
if (!pushTypeResolution(signature)) {
|
||||
if (!pushTypeResolution(signature, TypeSystemPropertyName.ResolvedReturnType)) {
|
||||
return unknownType;
|
||||
}
|
||||
let type: Type;
|
||||
@@ -3991,26 +4069,79 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function isSubtypeOfAny(candidate: Type, types: Type[]): boolean {
|
||||
function isObjectLiteralTypeDuplicateOf(source: ObjectType, target: ObjectType): boolean {
|
||||
let sourceProperties = getPropertiesOfObjectType(source);
|
||||
let targetProperties = getPropertiesOfObjectType(target);
|
||||
if (sourceProperties.length !== targetProperties.length) {
|
||||
return false;
|
||||
}
|
||||
for (let sourceProp of sourceProperties) {
|
||||
let targetProp = getPropertyOfObjectType(target, sourceProp.name);
|
||||
if (!targetProp ||
|
||||
getDeclarationFlagsFromSymbol(targetProp) & (NodeFlags.Private | NodeFlags.Protected) ||
|
||||
!isTypeDuplicateOf(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function isTupleTypeDuplicateOf(source: TupleType, target: TupleType): boolean {
|
||||
let sourceTypes = source.elementTypes;
|
||||
let targetTypes = target.elementTypes;
|
||||
if (sourceTypes.length !== targetTypes.length) {
|
||||
return false;
|
||||
}
|
||||
for (var i = 0; i < sourceTypes.length; i++) {
|
||||
if (!isTypeDuplicateOf(sourceTypes[i], targetTypes[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns true if the source type is a duplicate of the target type. A source type is a duplicate of
|
||||
// a target type if the the two are identical, with the exception that the source type may have null or
|
||||
// undefined in places where the target type doesn't. This is by design an asymmetric relationship.
|
||||
function isTypeDuplicateOf(source: Type, target: Type): boolean {
|
||||
if (source === target) {
|
||||
return true;
|
||||
}
|
||||
if (source.flags & TypeFlags.Undefined || source.flags & TypeFlags.Null && !(target.flags & TypeFlags.Undefined)) {
|
||||
return true;
|
||||
}
|
||||
if (source.flags & TypeFlags.ObjectLiteral && target.flags & TypeFlags.ObjectType) {
|
||||
return isObjectLiteralTypeDuplicateOf(<ObjectType>source, <ObjectType>target);
|
||||
}
|
||||
if (isArrayType(source) && isArrayType(target)) {
|
||||
return isTypeDuplicateOf((<TypeReference>source).typeArguments[0], (<TypeReference>target).typeArguments[0]);
|
||||
}
|
||||
if (isTupleType(source) && isTupleType(target)) {
|
||||
return isTupleTypeDuplicateOf(<TupleType>source, <TupleType>target);
|
||||
}
|
||||
return isTypeIdenticalTo(source, target);
|
||||
}
|
||||
|
||||
function isTypeDuplicateOfSomeType(candidate: Type, types: Type[]): boolean {
|
||||
for (let type of types) {
|
||||
if (candidate !== type && isTypeSubtypeOf(candidate, type)) {
|
||||
if (candidate !== type && isTypeDuplicateOf(candidate, type)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function removeSubtypes(types: Type[]) {
|
||||
function removeDuplicateTypes(types: Type[]) {
|
||||
let i = types.length;
|
||||
while (i > 0) {
|
||||
i--;
|
||||
if (isSubtypeOfAny(types[i], types)) {
|
||||
if (isTypeDuplicateOfSomeType(types[i], types)) {
|
||||
types.splice(i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function containsTypeAny(types: Type[]) {
|
||||
function containsTypeAny(types: Type[]): boolean {
|
||||
for (let type of types) {
|
||||
if (isTypeAny(type)) {
|
||||
return true;
|
||||
@@ -4029,30 +4160,26 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function compareTypeIds(type1: Type, type2: Type): number {
|
||||
return type1.id - type2.id;
|
||||
}
|
||||
|
||||
// The noSubtypeReduction flag is there because it isn't possible to always do subtype reduction. The flag
|
||||
// is true when creating a union type from a type node and when instantiating a union type. In both of those
|
||||
// cases subtype reduction has to be deferred to properly support recursive union types. For example, a
|
||||
// type alias of the form "type Item = string | (() => Item)" cannot be reduced during its declaration.
|
||||
function getUnionType(types: Type[], noSubtypeReduction?: boolean): Type {
|
||||
// We always deduplicate the constituent type set based on object identity, but we'll also deduplicate
|
||||
// based on the structure of the types unless the noDeduplication flag is true, which is the case when
|
||||
// creating a union type from a type node and when instantiating a union type. In both of those cases,
|
||||
// structural deduplication has to be deferred to properly support recursive union types. For example,
|
||||
// a type of the form "type Item = string | (() => Item)" cannot be deduplicated during its declaration.
|
||||
function getUnionType(types: Type[], noDeduplication?: boolean): Type {
|
||||
if (types.length === 0) {
|
||||
return emptyObjectType;
|
||||
}
|
||||
let typeSet: Type[] = [];
|
||||
addTypesToSet(typeSet, types, TypeFlags.Union);
|
||||
typeSet.sort(compareTypeIds);
|
||||
if (noSubtypeReduction) {
|
||||
if (containsTypeAny(typeSet)) {
|
||||
return anyType;
|
||||
}
|
||||
if (containsTypeAny(typeSet)) {
|
||||
return anyType;
|
||||
}
|
||||
if (noDeduplication) {
|
||||
removeAllButLast(typeSet, undefinedType);
|
||||
removeAllButLast(typeSet, nullType);
|
||||
}
|
||||
else {
|
||||
removeSubtypes(typeSet);
|
||||
removeDuplicateTypes(typeSet);
|
||||
}
|
||||
if (typeSet.length === 1) {
|
||||
return typeSet[0];
|
||||
@@ -4062,38 +4189,19 @@ namespace ts {
|
||||
if (!type) {
|
||||
type = unionTypes[id] = <UnionType>createObjectType(TypeFlags.Union | getWideningFlagsOfTypes(typeSet));
|
||||
type.types = typeSet;
|
||||
type.reducedType = noSubtypeReduction ? undefined : type;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
// Subtype reduction is basically an optimization we do to avoid excessively large union types, which take longer
|
||||
// to process and look strange in quick info and error messages. Semantically there is no difference between the
|
||||
// reduced type and the type itself. So, when we detect a circularity we simply say that the reduced type is the
|
||||
// type itself.
|
||||
function getReducedTypeOfUnionType(type: UnionType): Type {
|
||||
if (!type.reducedType) {
|
||||
type.reducedType = circularType;
|
||||
let reducedType = getUnionType(type.types, /*noSubtypeReduction*/ false);
|
||||
if (type.reducedType === circularType) {
|
||||
type.reducedType = reducedType;
|
||||
}
|
||||
}
|
||||
else if (type.reducedType === circularType) {
|
||||
type.reducedType = type;
|
||||
}
|
||||
return type.reducedType;
|
||||
}
|
||||
|
||||
function getTypeFromUnionTypeNode(node: UnionTypeNode): Type {
|
||||
let links = getNodeLinks(node);
|
||||
if (!links.resolvedType) {
|
||||
links.resolvedType = getUnionType(map(node.types, getTypeFromTypeNode), /*noSubtypeReduction*/ true);
|
||||
links.resolvedType = getUnionType(map(node.types, getTypeFromTypeNode), /*noDeduplication*/ true);
|
||||
}
|
||||
return links.resolvedType;
|
||||
}
|
||||
|
||||
// We do not perform supertype reduction on intersection types. Intersection types are created only by the &
|
||||
// We do not perform structural deduplication on intersection types. Intersection types are created only by the &
|
||||
// type operator and we can't reduce those because we want to support recursive intersection types. For example,
|
||||
// a type alias of the form "type List<T> = T & { next: List<T> }" cannot be reduced during its declaration.
|
||||
// Also, unlike union types, the order of the constituent types is preserved in order that overload resolution
|
||||
@@ -4196,7 +4304,7 @@ namespace ts {
|
||||
// Callers should first ensure this by calling isTypeNode
|
||||
case SyntaxKind.Identifier:
|
||||
case SyntaxKind.QualifiedName:
|
||||
let symbol = getSymbolInfo(node);
|
||||
let symbol = getSymbolAtLocation(node);
|
||||
return symbol && getDeclaredTypeOfSymbol(symbol);
|
||||
default:
|
||||
return unknownType;
|
||||
@@ -4374,7 +4482,7 @@ namespace ts {
|
||||
return createTupleType(instantiateList((<TupleType>type).elementTypes, mapper, instantiateType));
|
||||
}
|
||||
if (type.flags & TypeFlags.Union) {
|
||||
return getUnionType(instantiateList((<UnionType>type).types, mapper, instantiateType), /*noSubtypeReduction*/ true);
|
||||
return getUnionType(instantiateList((<UnionType>type).types, mapper, instantiateType), /*noDeduplication*/ true);
|
||||
}
|
||||
if (type.flags & TypeFlags.Intersection) {
|
||||
return getIntersectionType(instantiateList((<IntersectionType>type).types, mapper, instantiateType));
|
||||
@@ -4519,6 +4627,16 @@ namespace ts {
|
||||
errorInfo = chainDiagnosticMessages(errorInfo, message, arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
function reportRelationError(message: DiagnosticMessage, source: Type, target: Type) {
|
||||
let sourceType = typeToString(source);
|
||||
let targetType = typeToString(target);
|
||||
if (sourceType === targetType) {
|
||||
sourceType = typeToString(source, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType);
|
||||
targetType = typeToString(target, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType);
|
||||
}
|
||||
reportError(message || Diagnostics.Type_0_is_not_assignable_to_type_1, sourceType, targetType);
|
||||
}
|
||||
|
||||
// Compare two types and return
|
||||
// Ternary.True if they are related with no assumptions,
|
||||
// Ternary.Maybe if they are related with assumptions of other relationships, or
|
||||
@@ -4538,7 +4656,23 @@ namespace ts {
|
||||
if (source === numberType && target.flags & TypeFlags.Enum) return Ternary.True;
|
||||
}
|
||||
}
|
||||
|
||||
if (relation !== identityRelation && source.flags & TypeFlags.FreshObjectLiteral) {
|
||||
if (hasExcessProperties(<FreshObjectLiteralType>source, target, reportErrors)) {
|
||||
if (reportErrors) {
|
||||
reportRelationError(headMessage, source, target);
|
||||
}
|
||||
return Ternary.False;
|
||||
}
|
||||
// Above we check for excess properties with respect to the entire target type. When union
|
||||
// and intersection types are further deconstructed on the target side, we don't want to
|
||||
// make the check again (as it might fail for a partial target type). Therefore we obtain
|
||||
// the regular source type and proceed with that.
|
||||
source = getRegularTypeOfObjectLiteral(source);
|
||||
}
|
||||
|
||||
let saveErrorInfo = errorInfo;
|
||||
|
||||
if (source.flags & TypeFlags.Reference && target.flags & TypeFlags.Reference && (<TypeReference>source).target === (<TypeReference>target).target) {
|
||||
// We have type references to same target type, see if relationship holds for all type arguments
|
||||
if (result = typesRelatedTo((<TypeReference>source).typeArguments, (<TypeReference>target).typeArguments, reportErrors)) {
|
||||
@@ -4615,18 +4749,22 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (reportErrors) {
|
||||
headMessage = headMessage || Diagnostics.Type_0_is_not_assignable_to_type_1;
|
||||
let sourceType = typeToString(source);
|
||||
let targetType = typeToString(target);
|
||||
if (sourceType === targetType) {
|
||||
sourceType = typeToString(source, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType);
|
||||
targetType = typeToString(target, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType);
|
||||
}
|
||||
reportError(headMessage, sourceType, targetType);
|
||||
reportRelationError(headMessage, source, target);
|
||||
}
|
||||
return Ternary.False;
|
||||
}
|
||||
|
||||
function hasExcessProperties(source: FreshObjectLiteralType, target: Type, reportErrors: boolean): boolean {
|
||||
for (let prop of getPropertiesOfObjectType(source)) {
|
||||
if (!isKnownProperty(target, prop.name)) {
|
||||
if (reportErrors) {
|
||||
reportError(Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, symbolToString(prop), typeToString(target));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function eachTypeRelatedToSomeType(source: UnionOrIntersectionType, target: UnionOrIntersectionType): Ternary {
|
||||
let result = Ternary.True;
|
||||
let sourceTypes = source.types;
|
||||
@@ -5323,6 +5461,24 @@ namespace ts {
|
||||
return !!(type.flags & TypeFlags.Tuple);
|
||||
}
|
||||
|
||||
function getRegularTypeOfObjectLiteral(type: Type): Type {
|
||||
if (type.flags & TypeFlags.FreshObjectLiteral) {
|
||||
let regularType = (<FreshObjectLiteralType>type).regularType;
|
||||
if (!regularType) {
|
||||
regularType = <ResolvedType>createType((<ResolvedType>type).flags & ~TypeFlags.FreshObjectLiteral);
|
||||
regularType.symbol = (<ResolvedType>type).symbol;
|
||||
regularType.members = (<ResolvedType>type).members;
|
||||
regularType.properties = (<ResolvedType>type).properties;
|
||||
regularType.callSignatures = (<ResolvedType>type).callSignatures;
|
||||
regularType.constructSignatures = (<ResolvedType>type).constructSignatures;
|
||||
regularType.stringIndexType = (<ResolvedType>type).stringIndexType;
|
||||
regularType.numberIndexType = (<ResolvedType>type).numberIndexType;
|
||||
}
|
||||
return regularType;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
function getWidenedTypeOfObjectLiteral(type: Type): Type {
|
||||
let properties = getPropertiesOfObjectType(type);
|
||||
let members: SymbolTable = {};
|
||||
@@ -5853,47 +6009,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function resolveLocation(node: Node) {
|
||||
// Resolve location from top down towards node if it is a context sensitive expression
|
||||
// That helps in making sure not assigning types as any when resolved out of order
|
||||
let containerNodes: Node[] = [];
|
||||
for (let parent = node.parent; parent; parent = parent.parent) {
|
||||
if ((isExpression(parent) || isObjectLiteralMethod(node)) &&
|
||||
isContextSensitive(<Expression>parent)) {
|
||||
containerNodes.unshift(parent);
|
||||
}
|
||||
}
|
||||
|
||||
ts.forEach(containerNodes, node => { getTypeOfNode(node); });
|
||||
}
|
||||
|
||||
function getSymbolAtLocation(node: Node): Symbol {
|
||||
resolveLocation(node);
|
||||
return getSymbolInfo(node);
|
||||
}
|
||||
|
||||
function getTypeAtLocation(node: Node): Type {
|
||||
resolveLocation(node);
|
||||
return getTypeOfNode(node);
|
||||
}
|
||||
|
||||
function getTypeOfSymbolAtLocation(symbol: Symbol, node: Node): Type {
|
||||
resolveLocation(node);
|
||||
// Get the narrowed type of symbol at given location instead of just getting
|
||||
// the type of the symbol.
|
||||
// eg.
|
||||
// function foo(a: string | number) {
|
||||
// if (typeof a === "string") {
|
||||
// a/**/
|
||||
// }
|
||||
// }
|
||||
// getTypeOfSymbol for a would return type of parameter symbol string | number
|
||||
// Unless we provide location /**/, checker wouldn't know how to narrow the type
|
||||
// By using getNarrowedTypeOfSymbol would return string since it would be able to narrow
|
||||
// it by typeguard in the if true condition
|
||||
return getNarrowedTypeOfSymbol(symbol, node);
|
||||
}
|
||||
|
||||
// Get the narrowed type of a given symbol at a given location
|
||||
function getNarrowedTypeOfSymbol(symbol: Symbol, node: Node) {
|
||||
let type = getTypeOfSymbol(symbol);
|
||||
@@ -6990,7 +7105,7 @@ namespace ts {
|
||||
let stringIndexType = getIndexType(IndexKind.String);
|
||||
let numberIndexType = getIndexType(IndexKind.Number);
|
||||
let result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexType, numberIndexType);
|
||||
result.flags |= TypeFlags.ObjectLiteral | TypeFlags.ContainsObjectLiteral | (typeFlags & TypeFlags.ContainsUndefinedOrNull);
|
||||
result.flags |= TypeFlags.ObjectLiteral | TypeFlags.FreshObjectLiteral | TypeFlags.ContainsObjectLiteral | (typeFlags & TypeFlags.ContainsUndefinedOrNull);
|
||||
return result;
|
||||
|
||||
function getIndexType(kind: IndexKind) {
|
||||
@@ -7221,10 +7336,9 @@ namespace ts {
|
||||
* For example, in the element <MyClass>, the element instance type is `MyClass` (not `typeof MyClass`).
|
||||
*/
|
||||
function getJsxElementInstanceType(node: JsxOpeningLikeElement) {
|
||||
if (!(getNodeLinks(node).jsxFlags & JsxFlags.ClassElement)) {
|
||||
// There is no such thing as an instance type for a non-class element
|
||||
return undefined;
|
||||
}
|
||||
// There is no such thing as an instance type for a non-class element. This
|
||||
// line shouldn't be hit.
|
||||
Debug.assert(!!(getNodeLinks(node).jsxFlags & JsxFlags.ClassElement), 'Should not call getJsxElementInstanceType on non-class Element');
|
||||
|
||||
let classSymbol = getJsxElementTagSymbol(node);
|
||||
if (classSymbol === unknownSymbol) {
|
||||
@@ -7247,16 +7361,11 @@ namespace ts {
|
||||
if (signatures.length === 0) {
|
||||
// We found no signatures at all, which is an error
|
||||
error(node.tagName, Diagnostics.JSX_element_type_0_does_not_have_any_construct_or_call_signatures, getTextOfNode(node.tagName));
|
||||
return undefined;
|
||||
return unknownType;
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the constructor/factory returns an object type
|
||||
let returnType = getUnionType(signatures.map(s => getReturnTypeOfSignature(s)));
|
||||
if (!isTypeAny(returnType) && !(returnType.flags & TypeFlags.ObjectType)) {
|
||||
error(node.tagName, Diagnostics.The_return_type_of_a_JSX_element_constructor_must_return_an_object_type);
|
||||
return undefined;
|
||||
}
|
||||
let returnType = getUnionType(signatures.map(getReturnTypeOfSignature));
|
||||
|
||||
// Issue an error if this return type isn't assignable to JSX.ElementClass
|
||||
let elemClassType = getJsxGlobalElementClassType();
|
||||
@@ -7317,7 +7426,7 @@ namespace ts {
|
||||
let elemInstanceType = getJsxElementInstanceType(node);
|
||||
|
||||
if (isTypeAny(elemInstanceType)) {
|
||||
return links.resolvedJsxType = anyType;
|
||||
return links.resolvedJsxType = elemInstanceType;
|
||||
}
|
||||
|
||||
let propsName = getJsxElementPropertiesName();
|
||||
@@ -8522,6 +8631,9 @@ namespace ts {
|
||||
if (!produceDiagnostics) {
|
||||
for (let candidate of candidates) {
|
||||
if (hasCorrectArity(node, args, candidate)) {
|
||||
if (candidate.typeParameters && typeArguments) {
|
||||
candidate = getSignatureInstantiation(candidate, map(typeArguments, getTypeFromTypeNode));
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
@@ -8870,7 +8982,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function checkAssertion(node: AssertionExpression) {
|
||||
let exprType = checkExpression(node.expression);
|
||||
let exprType = getRegularTypeOfObjectLiteral(checkExpression(node.expression));
|
||||
let targetType = getTypeFromTypeNode(node.type);
|
||||
if (produceDiagnostics && targetType !== unknownType) {
|
||||
let widenedType = getWidenedType(exprType);
|
||||
@@ -9695,7 +9807,7 @@ namespace ts {
|
||||
return getUnionType([leftType, rightType]);
|
||||
case SyntaxKind.EqualsToken:
|
||||
checkAssignmentOperator(rightType);
|
||||
return rightType;
|
||||
return getRegularTypeOfObjectLiteral(rightType);
|
||||
case SyntaxKind.CommaToken:
|
||||
return rightType;
|
||||
}
|
||||
@@ -10120,7 +10232,7 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
checkTypeAssignableTo(typePredicate.type,
|
||||
getTypeAtLocation(node.parameters[typePredicate.parameterIndex]),
|
||||
getTypeOfNode(node.parameters[typePredicate.parameterIndex]),
|
||||
typePredicateNode.type);
|
||||
}
|
||||
}
|
||||
@@ -10331,10 +10443,19 @@ namespace ts {
|
||||
// TS 1.0 spec (April 2014): 8.3.2
|
||||
// Constructors of classes with no extends clause may not contain super calls, whereas
|
||||
// constructors of derived classes must contain at least one super call somewhere in their function body.
|
||||
if (getClassExtendsHeritageClauseElement(<ClassDeclaration>node.parent)) {
|
||||
let containingClassDecl = <ClassDeclaration>node.parent;
|
||||
if (getClassExtendsHeritageClauseElement(containingClassDecl)) {
|
||||
let containingClassSymbol = getSymbolOfNode(containingClassDecl);
|
||||
let containingClassInstanceType = <InterfaceType>getDeclaredTypeOfSymbol(containingClassSymbol);
|
||||
let baseConstructorType = getBaseConstructorTypeOfClass(containingClassInstanceType);
|
||||
|
||||
if (containsSuperCall(node.body)) {
|
||||
// The first statement in the body of a constructor must be a super call if both of the following are true:
|
||||
if (baseConstructorType === nullType) {
|
||||
error(node, Diagnostics.A_constructor_cannot_contain_a_super_call_when_its_class_extends_null);
|
||||
}
|
||||
|
||||
// The first statement in the body of a constructor (excluding prologue directives) must be a super call
|
||||
// if both of the following are true:
|
||||
// - The containing class is a derived class.
|
||||
// - The constructor declares parameter properties
|
||||
// or the containing class declares instance member variables with initializers.
|
||||
@@ -10342,18 +10463,30 @@ namespace ts {
|
||||
forEach((<ClassDeclaration>node.parent).members, isInstancePropertyWithInitializer) ||
|
||||
forEach(node.parameters, p => p.flags & (NodeFlags.Public | NodeFlags.Private | NodeFlags.Protected));
|
||||
|
||||
// Skip past any prologue directives to find the first statement
|
||||
// to ensure that it was a super call.
|
||||
if (superCallShouldBeFirst) {
|
||||
let statements = (<Block>node.body).statements;
|
||||
if (!statements.length || statements[0].kind !== SyntaxKind.ExpressionStatement || !isSuperCallExpression((<ExpressionStatement>statements[0]).expression)) {
|
||||
error(node, Diagnostics.A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_or_has_parameter_properties);
|
||||
let superCallStatement: ExpressionStatement;
|
||||
for (let statement of statements) {
|
||||
if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCallExpression((<ExpressionStatement>statement).expression)) {
|
||||
superCallStatement = <ExpressionStatement>statement;
|
||||
break;
|
||||
}
|
||||
if (!isPrologueDirective(statement)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!superCallStatement) {
|
||||
error(node, Diagnostics.A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_or_has_parameter_properties);
|
||||
}
|
||||
else {
|
||||
// In such a required super call, it is a compile-time error for argument expressions to reference this.
|
||||
markThisReferencesAsErrors((<ExpressionStatement>statements[0]).expression);
|
||||
markThisReferencesAsErrors(superCallStatement.expression);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
else if (baseConstructorType !== nullType) {
|
||||
error(node, Diagnostics.Constructors_for_derived_classes_must_contain_a_super_call);
|
||||
}
|
||||
}
|
||||
@@ -10744,9 +10877,6 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
|
||||
// Exports should be checked only if enclosing module contains both exported and non exported declarations.
|
||||
// In case if all declarations are non-exported check is unnecessary.
|
||||
|
||||
// if localSymbol is defined on node then node itself is exported - check is required
|
||||
let symbol = node.localSymbol;
|
||||
if (!symbol) {
|
||||
@@ -10766,27 +10896,45 @@ namespace ts {
|
||||
|
||||
// we use SymbolFlags.ExportValue, SymbolFlags.ExportType and SymbolFlags.ExportNamespace
|
||||
// to denote disjoint declarationSpaces (without making new enum type).
|
||||
let exportedDeclarationSpaces: SymbolFlags = 0;
|
||||
let nonExportedDeclarationSpaces: SymbolFlags = 0;
|
||||
forEach(symbol.declarations, d => {
|
||||
let exportedDeclarationSpaces = SymbolFlags.None;
|
||||
let nonExportedDeclarationSpaces = SymbolFlags.None;
|
||||
let defaultExportedDeclarationSpaces = SymbolFlags.None;
|
||||
for (let d of symbol.declarations) {
|
||||
let declarationSpaces = getDeclarationSpaces(d);
|
||||
if (getEffectiveDeclarationFlags(d, NodeFlags.Export)) {
|
||||
exportedDeclarationSpaces |= declarationSpaces;
|
||||
let effectiveDeclarationFlags = getEffectiveDeclarationFlags(d, NodeFlags.Export | NodeFlags.Default);
|
||||
|
||||
if (effectiveDeclarationFlags & NodeFlags.Export) {
|
||||
if (effectiveDeclarationFlags & NodeFlags.Default) {
|
||||
defaultExportedDeclarationSpaces |= declarationSpaces;
|
||||
}
|
||||
else {
|
||||
exportedDeclarationSpaces |= declarationSpaces;
|
||||
}
|
||||
}
|
||||
else {
|
||||
nonExportedDeclarationSpaces |= declarationSpaces;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let commonDeclarationSpace = exportedDeclarationSpaces & nonExportedDeclarationSpaces;
|
||||
// Spaces for anyting not declared a 'default export'.
|
||||
let nonDefaultExportedDeclarationSpaces = exportedDeclarationSpaces | nonExportedDeclarationSpaces;
|
||||
|
||||
let commonDeclarationSpacesForExportsAndLocals = exportedDeclarationSpaces & nonExportedDeclarationSpaces;
|
||||
let commonDeclarationSpacesForDefaultAndNonDefault = defaultExportedDeclarationSpaces & nonDefaultExportedDeclarationSpaces;
|
||||
|
||||
if (commonDeclarationSpace) {
|
||||
if (commonDeclarationSpacesForExportsAndLocals || commonDeclarationSpacesForDefaultAndNonDefault) {
|
||||
// declaration spaces for exported and non-exported declarations intersect
|
||||
forEach(symbol.declarations, d => {
|
||||
if (getDeclarationSpaces(d) & commonDeclarationSpace) {
|
||||
for (let d of symbol.declarations) {
|
||||
let declarationSpaces = getDeclarationSpaces(d);
|
||||
|
||||
// Only error on the declarations that conributed to the intersecting spaces.
|
||||
if (declarationSpaces & commonDeclarationSpacesForDefaultAndNonDefault) {
|
||||
error(d.name, Diagnostics.Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration_instead, declarationNameToString(d.name));
|
||||
}
|
||||
else if (declarationSpaces & commonDeclarationSpacesForExportsAndLocals) {
|
||||
error(d.name, Diagnostics.Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local, declarationNameToString(d.name));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function getDeclarationSpaces(d: Declaration): SymbolFlags {
|
||||
@@ -12631,28 +12779,7 @@ namespace ts {
|
||||
}
|
||||
let initializer = member.initializer;
|
||||
if (initializer) {
|
||||
autoValue = getConstantValueForEnumMemberInitializer(initializer);
|
||||
if (autoValue === undefined) {
|
||||
if (enumIsConst) {
|
||||
error(initializer, Diagnostics.In_const_enum_declarations_member_initializer_must_be_constant_expression);
|
||||
}
|
||||
else if (!ambient) {
|
||||
// Only here do we need to check that the initializer is assignable to the enum type.
|
||||
// If it is a constant value (not undefined), it is syntactically constrained to be a number.
|
||||
// Also, we do not need to check this for ambients because there is already
|
||||
// a syntax error if it is not a constant.
|
||||
checkTypeAssignableTo(checkExpression(initializer), enumType, initializer, /*headMessage*/ undefined);
|
||||
}
|
||||
}
|
||||
else if (enumIsConst) {
|
||||
if (isNaN(autoValue)) {
|
||||
error(initializer, Diagnostics.const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN);
|
||||
}
|
||||
else if (!isFinite(autoValue)) {
|
||||
error(initializer, Diagnostics.const_enum_member_initializer_was_evaluated_to_a_non_finite_value);
|
||||
}
|
||||
}
|
||||
|
||||
autoValue = computeConstantValueForEnumMemberInitializer(initializer, enumType, enumIsConst, ambient);
|
||||
}
|
||||
else if (ambient && !enumIsConst) {
|
||||
autoValue = undefined;
|
||||
@@ -12666,8 +12793,36 @@ namespace ts {
|
||||
nodeLinks.flags |= NodeCheckFlags.EnumValuesComputed;
|
||||
}
|
||||
|
||||
function getConstantValueForEnumMemberInitializer(initializer: Expression): number {
|
||||
return evalConstant(initializer);
|
||||
function computeConstantValueForEnumMemberInitializer(initializer: Expression, enumType: Type, enumIsConst: boolean, ambient: boolean): number {
|
||||
// Controls if error should be reported after evaluation of constant value is completed
|
||||
// Can be false if another more precise error was already reported during evaluation.
|
||||
let reportError = true;
|
||||
let value = evalConstant(initializer);
|
||||
|
||||
if (reportError) {
|
||||
if (value === undefined) {
|
||||
if (enumIsConst) {
|
||||
error(initializer, Diagnostics.In_const_enum_declarations_member_initializer_must_be_constant_expression);
|
||||
}
|
||||
else if (!ambient) {
|
||||
// Only here do we need to check that the initializer is assignable to the enum type.
|
||||
// If it is a constant value (not undefined), it is syntactically constrained to be a number.
|
||||
// Also, we do not need to check this for ambients because there is already
|
||||
// a syntax error if it is not a constant.
|
||||
checkTypeAssignableTo(checkExpression(initializer), enumType, initializer, /*headMessage*/ undefined);
|
||||
}
|
||||
}
|
||||
else if (enumIsConst) {
|
||||
if (isNaN(value)) {
|
||||
error(initializer, Diagnostics.const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN);
|
||||
}
|
||||
else if (!isFinite(value)) {
|
||||
error(initializer, Diagnostics.const_enum_member_initializer_was_evaluated_to_a_non_finite_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
|
||||
function evalConstant(e: Node): number {
|
||||
switch (e.kind) {
|
||||
@@ -12776,6 +12931,8 @@ namespace ts {
|
||||
|
||||
// illegal case: forward reference
|
||||
if (!isDefinedBefore(propertyDecl, member)) {
|
||||
reportError = false;
|
||||
error(e, Diagnostics.A_member_initializer_in_a_const_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_const_enums);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -13742,7 +13899,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getSymbolInfo(node: Node) {
|
||||
function getSymbolAtLocation(node: Node) {
|
||||
if (isInsideWithStatementBody(node)) {
|
||||
// We cannot answer semantic questions within a with block, do not proceed any further
|
||||
return undefined;
|
||||
@@ -13762,7 +13919,7 @@ namespace ts {
|
||||
else if (node.parent.kind === SyntaxKind.BindingElement &&
|
||||
node.parent.parent.kind === SyntaxKind.ObjectBindingPattern &&
|
||||
node === (<BindingElement>node.parent).propertyName) {
|
||||
let typeOfPattern = getTypeAtLocation(node.parent.parent);
|
||||
let typeOfPattern = getTypeOfNode(node.parent.parent);
|
||||
let propertyDeclaration = typeOfPattern && getPropertyOfType(typeOfPattern, (<Identifier>node).text);
|
||||
|
||||
if (propertyDeclaration) {
|
||||
@@ -13845,24 +14002,24 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (isTypeDeclaration(node)) {
|
||||
// In this case, we call getSymbolOfNode instead of getSymbolInfo because it is a declaration
|
||||
// In this case, we call getSymbolOfNode instead of getSymbolAtLocation because it is a declaration
|
||||
let symbol = getSymbolOfNode(node);
|
||||
return getDeclaredTypeOfSymbol(symbol);
|
||||
}
|
||||
|
||||
if (isTypeDeclarationName(node)) {
|
||||
let symbol = getSymbolInfo(node);
|
||||
let symbol = getSymbolAtLocation(node);
|
||||
return symbol && getDeclaredTypeOfSymbol(symbol);
|
||||
}
|
||||
|
||||
if (isDeclaration(node)) {
|
||||
// In this case, we call getSymbolOfNode instead of getSymbolInfo because it is a declaration
|
||||
// In this case, we call getSymbolOfNode instead of getSymbolAtLocation because it is a declaration
|
||||
let symbol = getSymbolOfNode(node);
|
||||
return getTypeOfSymbol(symbol);
|
||||
}
|
||||
|
||||
if (isDeclarationName(node)) {
|
||||
let symbol = getSymbolInfo(node);
|
||||
let symbol = getSymbolAtLocation(node);
|
||||
return symbol && getTypeOfSymbol(symbol);
|
||||
}
|
||||
|
||||
@@ -13871,7 +14028,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (isInRightSideOfImportOrExportAssignment(<Identifier>node)) {
|
||||
let symbol = getSymbolInfo(node);
|
||||
let symbol = getSymbolAtLocation(node);
|
||||
let declaredType = symbol && getDeclaredTypeOfSymbol(symbol);
|
||||
return declaredType !== unknownType ? declaredType : getTypeOfSymbol(symbol);
|
||||
}
|
||||
@@ -14040,7 +14197,11 @@ namespace ts {
|
||||
return true;
|
||||
}
|
||||
// const enums and modules that contain only const enums are not considered values from the emit perespective
|
||||
return target !== unknownSymbol && target && target.flags & SymbolFlags.Value && !isConstEnumOrConstEnumOnlyModule(target);
|
||||
// unless 'preserveConstEnums' option is set to true
|
||||
return target !== unknownSymbol &&
|
||||
target &&
|
||||
target.flags & SymbolFlags.Value &&
|
||||
(compilerOptions.preserveConstEnums || !isConstEnumOrConstEnumOnlyModule(target));
|
||||
}
|
||||
|
||||
function isConstEnumOrConstEnumOnlyModule(s: Symbol): boolean {
|
||||
|
||||
@@ -254,6 +254,7 @@ namespace ts {
|
||||
Only_a_void_function_can_be_called_with_the_new_keyword: { code: 2350, category: DiagnosticCategory.Error, key: "Only a void function can be called with the 'new' keyword." },
|
||||
Cannot_use_new_with_an_expression_whose_type_lacks_a_call_or_construct_signature: { code: 2351, category: DiagnosticCategory.Error, key: "Cannot use 'new' with an expression whose type lacks a call or construct signature." },
|
||||
Neither_type_0_nor_type_1_is_assignable_to_the_other: { code: 2352, category: DiagnosticCategory.Error, key: "Neither type '{0}' nor type '{1}' is assignable to the other." },
|
||||
Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1: { code: 2353, category: DiagnosticCategory.Error, key: "Object literal may only specify known properties, and '{0}' does not exist in type '{1}'." },
|
||||
No_best_common_type_exists_among_return_expressions: { code: 2354, category: DiagnosticCategory.Error, key: "No best common type exists among return expressions." },
|
||||
A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value_or_consist_of_a_single_throw_statement: { code: 2355, category: DiagnosticCategory.Error, key: "A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement." },
|
||||
An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type: { code: 2356, category: DiagnosticCategory.Error, key: "An arithmetic operand must be of type 'any', 'number' or an enum type." },
|
||||
@@ -293,7 +294,7 @@ namespace ts {
|
||||
Multiple_constructor_implementations_are_not_allowed: { code: 2392, category: DiagnosticCategory.Error, key: "Multiple constructor implementations are not allowed." },
|
||||
Duplicate_function_implementation: { code: 2393, category: DiagnosticCategory.Error, key: "Duplicate function implementation." },
|
||||
Overload_signature_is_not_compatible_with_function_implementation: { code: 2394, category: DiagnosticCategory.Error, key: "Overload signature is not compatible with function implementation." },
|
||||
Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local: { code: 2395, category: DiagnosticCategory.Error, key: "Individual declarations in merged declaration {0} must be all exported or all local." },
|
||||
Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local: { code: 2395, category: DiagnosticCategory.Error, key: "Individual declarations in merged declaration '{0}' must be all exported or all local." },
|
||||
Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters: { code: 2396, category: DiagnosticCategory.Error, key: "Duplicate identifier 'arguments'. Compiler uses 'arguments' to initialize rest parameters." },
|
||||
Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference: { code: 2399, category: DiagnosticCategory.Error, key: "Duplicate identifier '_this'. Compiler uses variable declaration '_this' to capture 'this' reference." },
|
||||
Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference: { code: 2400, category: DiagnosticCategory.Error, key: "Expression resolves to variable declaration '_this' that compiler uses to capture 'this' reference." },
|
||||
@@ -424,6 +425,8 @@ namespace ts {
|
||||
JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property: { code: 2607, category: DiagnosticCategory.Error, key: "JSX element class does not support attributes because it does not have a '{0}' property" },
|
||||
The_global_type_JSX_0_may_not_have_more_than_one_property: { code: 2608, category: DiagnosticCategory.Error, key: "The global type 'JSX.{0}' may not have more than one property" },
|
||||
Cannot_emit_namespaced_JSX_elements_in_React: { code: 2650, category: DiagnosticCategory.Error, key: "Cannot emit namespaced JSX elements in React" },
|
||||
A_member_initializer_in_a_const_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_const_enums: { code: 2651, category: DiagnosticCategory.Error, key: "A member initializer in a 'const' enum declaration cannot reference members declared after it, including members defined in other 'const' enums." },
|
||||
Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration_instead: { code: 2652, category: DiagnosticCategory.Error, key: "Merged declaration '{0}' cannot include a default export declaration. Consider adding a separate 'export default {0}' declaration instead." },
|
||||
Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." },
|
||||
Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." },
|
||||
Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported interface has or is using private name '{1}'." },
|
||||
@@ -508,7 +511,6 @@ namespace ts {
|
||||
Option_noEmit_cannot_be_specified_with_option_out_or_outDir: { code: 5040, category: DiagnosticCategory.Error, key: "Option 'noEmit' cannot be specified with option 'out' or 'outDir'." },
|
||||
Option_noEmit_cannot_be_specified_with_option_declaration: { code: 5041, category: DiagnosticCategory.Error, key: "Option 'noEmit' cannot be specified with option 'declaration'." },
|
||||
Option_project_cannot_be_mixed_with_source_files_on_a_command_line: { code: 5042, category: DiagnosticCategory.Error, key: "Option 'project' cannot be mixed with source files on a command line." },
|
||||
Option_sourceMap_cannot_be_specified_with_option_isolatedModules: { code: 5043, category: DiagnosticCategory.Error, key: "Option 'sourceMap' cannot be specified with option 'isolatedModules'." },
|
||||
Option_declaration_cannot_be_specified_with_option_isolatedModules: { code: 5044, category: DiagnosticCategory.Error, key: "Option 'declaration' cannot be specified with option 'isolatedModules'." },
|
||||
Option_noEmitOnError_cannot_be_specified_with_option_isolatedModules: { code: 5045, category: DiagnosticCategory.Error, key: "Option 'noEmitOnError' cannot be specified with option 'isolatedModules'." },
|
||||
Option_out_cannot_be_specified_with_option_isolatedModules: { code: 5046, category: DiagnosticCategory.Error, key: "Option 'out' cannot be specified with option 'isolatedModules'." },
|
||||
@@ -613,5 +615,6 @@ namespace ts {
|
||||
Expected_corresponding_JSX_closing_tag_for_0: { code: 17002, category: DiagnosticCategory.Error, key: "Expected corresponding JSX closing tag for '{0}'." },
|
||||
JSX_attribute_expected: { code: 17003, category: DiagnosticCategory.Error, key: "JSX attribute expected." },
|
||||
Cannot_use_JSX_unless_the_jsx_flag_is_provided: { code: 17004, category: DiagnosticCategory.Error, key: "Cannot use JSX unless the '--jsx' flag is provided." },
|
||||
A_constructor_cannot_contain_a_super_call_when_its_class_extends_null: { code: 17005, category: DiagnosticCategory.Error, key: "A constructor cannot contain a 'super' call when its class extends 'null'" },
|
||||
};
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
{
|
||||
"Unterminated string literal.": {
|
||||
"category": "Error",
|
||||
"code": 1002
|
||||
@@ -1005,6 +1005,10 @@
|
||||
"category": "Error",
|
||||
"code": 2352
|
||||
},
|
||||
"Object literal may only specify known properties, and '{0}' does not exist in type '{1}'.": {
|
||||
"category": "Error",
|
||||
"code": 2353
|
||||
},
|
||||
"No best common type exists among return expressions.": {
|
||||
"category": "Error",
|
||||
"code": 2354
|
||||
@@ -1161,7 +1165,7 @@
|
||||
"category": "Error",
|
||||
"code": 2394
|
||||
},
|
||||
"Individual declarations in merged declaration {0} must be all exported or all local.": {
|
||||
"Individual declarations in merged declaration '{0}' must be all exported or all local.": {
|
||||
"category": "Error",
|
||||
"code": 2395
|
||||
},
|
||||
@@ -1685,6 +1689,14 @@
|
||||
"category": "Error",
|
||||
"code": 2650
|
||||
},
|
||||
"A member initializer in a 'const' enum declaration cannot reference members declared after it, including members defined in other 'const' enums.": {
|
||||
"category": "Error",
|
||||
"code": 2651
|
||||
},
|
||||
"Merged declaration '{0}' cannot include a default export declaration. Consider adding a separate 'export default {0}' declaration instead.": {
|
||||
"category": "Error",
|
||||
"code": 2652
|
||||
},
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
"code": 4000
|
||||
@@ -2021,10 +2033,6 @@
|
||||
"category": "Error",
|
||||
"code": 5042
|
||||
},
|
||||
"Option 'sourceMap' cannot be specified with option 'isolatedModules'.": {
|
||||
"category": "Error",
|
||||
"code": 5043
|
||||
},
|
||||
"Option 'declaration' cannot be specified with option 'isolatedModules'.": {
|
||||
"category": "Error",
|
||||
"code": 5044
|
||||
@@ -2445,5 +2453,9 @@
|
||||
"Cannot use JSX unless the '--jsx' flag is provided.": {
|
||||
"category": "Error",
|
||||
"code": 17004
|
||||
},
|
||||
"A constructor cannot contain a 'super' call when its class extends 'null'": {
|
||||
"category": "Error",
|
||||
"code": 17005
|
||||
}
|
||||
}
|
||||
|
||||
+94
-16
@@ -1425,6 +1425,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
case SyntaxKind.IfStatement:
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
case SyntaxKind.JsxExpression:
|
||||
case SyntaxKind.NewExpression:
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
case SyntaxKind.PostfixUnaryExpression:
|
||||
@@ -3012,6 +3013,26 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
return result;
|
||||
}
|
||||
|
||||
function emitEs6ExportDefaultCompat(node: Node) {
|
||||
if (node.parent.kind === SyntaxKind.SourceFile) {
|
||||
Debug.assert(!!(node.flags & NodeFlags.Default) || node.kind === SyntaxKind.ExportAssignment);
|
||||
// only allow export default at a source file level
|
||||
if (compilerOptions.module === ModuleKind.CommonJS || compilerOptions.module === ModuleKind.AMD || compilerOptions.module === ModuleKind.UMD) {
|
||||
if (!currentSourceFile.symbol.exports["___esModule"]) {
|
||||
if (languageVersion === ScriptTarget.ES5) {
|
||||
// default value of configurable, enumerable, writable are `false`.
|
||||
write("Object.defineProperty(exports, \"__esModule\", { value: true });");
|
||||
writeLine();
|
||||
}
|
||||
else if (languageVersion === ScriptTarget.ES3) {
|
||||
write("exports.__esModule = true;");
|
||||
writeLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function emitExportMemberAssignment(node: FunctionLikeDeclaration | ClassDeclaration) {
|
||||
if (node.flags & NodeFlags.Export) {
|
||||
writeLine();
|
||||
@@ -3034,9 +3055,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
}
|
||||
else {
|
||||
if (node.flags & NodeFlags.Default) {
|
||||
emitEs6ExportDefaultCompat(node);
|
||||
if (languageVersion === ScriptTarget.ES3) {
|
||||
write("exports[\"default\"]");
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
write("exports.default");
|
||||
}
|
||||
}
|
||||
@@ -5407,17 +5430,43 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
(!isExternalModule(currentSourceFile) && resolver.isTopLevelValueImportEqualsWithEntityName(node))) {
|
||||
emitLeadingComments(node);
|
||||
emitStart(node);
|
||||
if (isES6ExportedDeclaration(node)) {
|
||||
write("export ");
|
||||
write("var ");
|
||||
|
||||
// variable declaration for import-equals declaration can be hoisted in system modules
|
||||
// in this case 'var' should be omitted and emit should contain only initialization
|
||||
let variableDeclarationIsHoisted = shouldHoistVariable(node, /*checkIfSourceFileLevelDecl*/ true);
|
||||
|
||||
// is it top level export import v = a.b.c in system module?
|
||||
// if yes - it needs to be rewritten as exporter('v', v = a.b.c)
|
||||
let isExported = isSourceFileLevelDeclarationInSystemJsModule(node, /*isExported*/ true);
|
||||
|
||||
if (!variableDeclarationIsHoisted) {
|
||||
Debug.assert(!isExported);
|
||||
|
||||
if (isES6ExportedDeclaration(node)) {
|
||||
write("export ");
|
||||
write("var ");
|
||||
}
|
||||
else if (!(node.flags & NodeFlags.Export)) {
|
||||
write("var ");
|
||||
}
|
||||
}
|
||||
else if (!(node.flags & NodeFlags.Export)) {
|
||||
write("var ");
|
||||
|
||||
|
||||
if (isExported) {
|
||||
write(`${exportFunctionForFile}("`);
|
||||
emitNodeWithoutSourceMap(node.name);
|
||||
write(`", `);
|
||||
}
|
||||
|
||||
emitModuleMemberName(node);
|
||||
write(" = ");
|
||||
emit(node.moduleReference);
|
||||
write(";");
|
||||
|
||||
if (isExported) {
|
||||
write(")");
|
||||
}
|
||||
|
||||
write(";");
|
||||
emitEnd(node);
|
||||
emitExportImportAssignments(node);
|
||||
emitTrailingComments(node);
|
||||
@@ -5538,6 +5587,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
write(")");
|
||||
}
|
||||
else {
|
||||
emitEs6ExportDefaultCompat(node);
|
||||
emitContainingModuleName(node);
|
||||
if (languageVersion === ScriptTarget.ES3) {
|
||||
write("[\"default\"] = ");
|
||||
@@ -5756,6 +5806,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
write(`function ${exportStarFunction}(m) {`);
|
||||
increaseIndent();
|
||||
writeLine();
|
||||
write(`var exports = {};`);
|
||||
writeLine();
|
||||
write(`for(var n in m) {`);
|
||||
increaseIndent();
|
||||
writeLine();
|
||||
@@ -5763,10 +5815,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
if (localNames) {
|
||||
write(`&& !${localNames}.hasOwnProperty(n)`);
|
||||
}
|
||||
write(`) ${exportFunctionForFile}(n, m[n]);`);
|
||||
write(`) exports[n] = m[n];`);
|
||||
decreaseIndent();
|
||||
writeLine();
|
||||
write("}");
|
||||
writeLine();
|
||||
write(`${exportFunctionForFile}(exports);`)
|
||||
decreaseIndent();
|
||||
writeLine();
|
||||
write("}");
|
||||
@@ -5938,6 +5992,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (isInternalModuleImportEqualsDeclaration(node)) {
|
||||
if (!hoistedVars) {
|
||||
hoistedVars = [];
|
||||
}
|
||||
|
||||
hoistedVars.push(node.name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isBindingPattern(node)) {
|
||||
forEach((<BindingPattern>node).elements, visit);
|
||||
@@ -6099,16 +6162,23 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
if ((<ExportDeclaration>importNode).exportClause) {
|
||||
// export {a, b as c} from 'foo'
|
||||
// emit as:
|
||||
// exports('a', _foo["a"])
|
||||
// exports('c', _foo["b"])
|
||||
// var reexports = {}
|
||||
// reexports['a'] = _foo["a"];
|
||||
// reexports['c'] = _foo["b"];
|
||||
// exports_(reexports);
|
||||
let reexportsVariableName = makeUniqueName("reexports");
|
||||
writeLine();
|
||||
write(`var ${reexportsVariableName} = {};`)
|
||||
writeLine();
|
||||
for (let e of (<ExportDeclaration>importNode).exportClause.elements) {
|
||||
writeLine();
|
||||
write(`${exportFunctionForFile}("`);
|
||||
write(`${reexportsVariableName}["`);
|
||||
emitNodeWithoutSourceMap(e.name);
|
||||
write(`", ${parameterName}["`);
|
||||
write(`"] = ${parameterName}["`);
|
||||
emitNodeWithoutSourceMap(e.propertyName || e.name);
|
||||
write(`"]);`);
|
||||
write(`"];`);
|
||||
writeLine();
|
||||
}
|
||||
write(`${exportFunctionForFile}(${reexportsVariableName});`);
|
||||
}
|
||||
else {
|
||||
writeLine();
|
||||
@@ -6135,14 +6205,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
writeLine();
|
||||
for (let i = startIndex; i < node.statements.length; ++i) {
|
||||
let statement = node.statements[i];
|
||||
// - imports/exports are not emitted for system modules
|
||||
// - external module related imports/exports are not emitted for system modules
|
||||
// - function declarations are not emitted because they were already hoisted
|
||||
switch (statement.kind) {
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
continue;
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
if (!isInternalModuleImportEqualsDeclaration(statement)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
writeLine();
|
||||
emit(statement);
|
||||
@@ -6768,6 +6841,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
return leadingComments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all but the pinned or triple slash comments.
|
||||
* @param ranges The array to be filtered
|
||||
* @param onlyPinnedOrTripleSlashComments whether the filtering should be performed.
|
||||
*/
|
||||
function filterComments(ranges: CommentRange[], onlyPinnedOrTripleSlashComments: boolean): CommentRange[] {
|
||||
// If we're removing comments, then we want to strip out all but the pinned or
|
||||
// triple slash comments.
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace ts {
|
||||
/* @internal */ export let ioWriteTime = 0;
|
||||
|
||||
/** The version of the TypeScript compiler release */
|
||||
export const version = "1.5.3";
|
||||
export const version = "1.6.0";
|
||||
|
||||
export function findConfigFile(searchPath: string): string {
|
||||
let fileName = "tsconfig.json";
|
||||
@@ -341,7 +341,7 @@ namespace ts {
|
||||
});
|
||||
}
|
||||
|
||||
function getDeclarationDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
function getDeclarationDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
return runWithCancellationToken(() => {
|
||||
if (!isDeclarationFile(sourceFile)) {
|
||||
let resolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile, cancellationToken);
|
||||
@@ -350,7 +350,7 @@ namespace ts {
|
||||
return ts.getDeclarationDiagnostics(getEmitHost(writeFile), resolver, sourceFile);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function getOptionsDiagnostics(): Diagnostic[] {
|
||||
let allDiagnostics: Diagnostic[] = [];
|
||||
@@ -602,10 +602,6 @@ namespace ts {
|
||||
|
||||
function verifyCompilerOptions() {
|
||||
if (options.isolatedModules) {
|
||||
if (options.sourceMap) {
|
||||
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_sourceMap_cannot_be_specified_with_option_isolatedModules));
|
||||
}
|
||||
|
||||
if (options.declaration) {
|
||||
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_declaration_cannot_be_specified_with_option_isolatedModules));
|
||||
}
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
|
||||
namespace ts {
|
||||
export interface SourceFile {
|
||||
fileWatcher: FileWatcher;
|
||||
fileWatcher?: FileWatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+19
-5
@@ -1404,6 +1404,7 @@ namespace ts {
|
||||
getPropertyOfType(type: Type, propertyName: string): Symbol;
|
||||
getSignaturesOfType(type: Type, kind: SignatureKind): Signature[];
|
||||
getIndexTypeOfType(type: Type, kind: IndexKind): Type;
|
||||
getBaseTypes(type: InterfaceType): ObjectType[];
|
||||
getReturnTypeOfSignature(signature: Signature): Type;
|
||||
|
||||
getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[];
|
||||
@@ -1762,10 +1763,12 @@ namespace ts {
|
||||
FromSignature = 0x00040000, // Created for signature assignment check
|
||||
ObjectLiteral = 0x00080000, // Originates in an object literal
|
||||
/* @internal */
|
||||
ContainsUndefinedOrNull = 0x00100000, // Type is or contains Undefined or Null type
|
||||
FreshObjectLiteral = 0x00100000, // Fresh object literal type
|
||||
/* @internal */
|
||||
ContainsObjectLiteral = 0x00200000, // Type is or contains object literal type
|
||||
ESSymbol = 0x00400000, // Type of symbol primitive introduced in ES6
|
||||
ContainsUndefinedOrNull = 0x00200000, // Type is or contains Undefined or Null type
|
||||
/* @internal */
|
||||
ContainsObjectLiteral = 0x00400000, // Type is or contains object literal type
|
||||
ESSymbol = 0x00800000, // Type of symbol primitive introduced in ES6
|
||||
|
||||
/* @internal */
|
||||
Intrinsic = Any | String | Number | Boolean | ESSymbol | Void | Undefined | Null,
|
||||
@@ -1774,10 +1777,10 @@ namespace ts {
|
||||
StringLike = String | StringLiteral,
|
||||
NumberLike = Number | Enum,
|
||||
ObjectType = Class | Interface | Reference | Tuple | Anonymous,
|
||||
UnionOrIntersection = Union | Intersection,
|
||||
UnionOrIntersection = Union | Intersection,
|
||||
StructuredType = ObjectType | Union | Intersection,
|
||||
/* @internal */
|
||||
RequiresWidening = ContainsUndefinedOrNull | ContainsObjectLiteral
|
||||
RequiresWidening = ContainsUndefinedOrNull | ContainsObjectLiteral
|
||||
}
|
||||
|
||||
// Properties common to all types
|
||||
@@ -1806,7 +1809,9 @@ namespace ts {
|
||||
typeParameters: TypeParameter[]; // Type parameters (undefined if non-generic)
|
||||
outerTypeParameters: TypeParameter[]; // Outer type parameters (undefined if none)
|
||||
localTypeParameters: TypeParameter[]; // Local type parameters (undefined if none)
|
||||
/* @internal */
|
||||
resolvedBaseConstructorType?: Type; // Resolved base constructor type of class
|
||||
/* @internal */
|
||||
resolvedBaseTypes: ObjectType[]; // Resolved base types
|
||||
}
|
||||
|
||||
@@ -1858,6 +1863,14 @@ namespace ts {
|
||||
numberIndexType?: Type; // Numeric index type
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
// Object literals are initially marked fresh. Freshness disappears following an assignment,
|
||||
// before a type assertion, or when when an object literal's type is widened. The regular
|
||||
// version of a fresh type is identical except for the TypeFlags.FreshObjectLiteral flag.
|
||||
export interface FreshObjectLiteralType extends ResolvedType {
|
||||
regularType: ResolvedType; // Regular version of fresh type
|
||||
}
|
||||
|
||||
// Just a place to cache element types of iterables and iterators
|
||||
/* @internal */
|
||||
export interface IterableOrIteratorType extends ObjectType, UnionType {
|
||||
@@ -2211,6 +2224,7 @@ namespace ts {
|
||||
|
||||
export interface CompilerHost {
|
||||
getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void): SourceFile;
|
||||
getCancellationToken?(): CancellationToken;
|
||||
getDefaultLibFileName(options: CompilerOptions): string;
|
||||
writeFile: WriteFileCallback;
|
||||
getCurrentDirectory(): string;
|
||||
|
||||
@@ -965,7 +965,7 @@ namespace ts {
|
||||
return (<ExternalModuleReference>(<ImportEqualsDeclaration>node).moduleReference).expression;
|
||||
}
|
||||
|
||||
export function isInternalModuleImportEqualsDeclaration(node: Node) {
|
||||
export function isInternalModuleImportEqualsDeclaration(node: Node): node is ImportEqualsDeclaration {
|
||||
return node.kind === SyntaxKind.ImportEqualsDeclaration && (<ImportEqualsDeclaration>node).moduleReference.kind !== SyntaxKind.ExternalModuleReference;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,9 +26,8 @@ module FourSlash {
|
||||
export interface FourSlashFile {
|
||||
// The contents of the file (with markers, etc stripped out)
|
||||
content: string;
|
||||
|
||||
fileName: string;
|
||||
|
||||
version: number;
|
||||
// File-specific options (name/value pairs)
|
||||
fileOptions: { [index: string]: string; };
|
||||
}
|
||||
@@ -1876,7 +1875,7 @@ module FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
private verifyProjectInfo(expected: string[]) {
|
||||
public verifyProjectInfo(expected: string[]) {
|
||||
if (this.testType === FourSlashTestType.Server) {
|
||||
let actual = (<ts.server.SessionClient>this.languageService).getProjectInfo(
|
||||
this.activeFile.fileName,
|
||||
@@ -2058,11 +2057,8 @@ module FourSlash {
|
||||
return result;
|
||||
}
|
||||
|
||||
public verifGetScriptLexicalStructureListContains(
|
||||
name: string,
|
||||
kind: string,
|
||||
markerPosition?: number) {
|
||||
this.taoInvalidReason = 'verifGetScriptLexicalStructureListContains impossible';
|
||||
public verifyGetScriptLexicalStructureListContains(name: string, kind: string) {
|
||||
this.taoInvalidReason = 'verifyGetScriptLexicalStructureListContains impossible';
|
||||
|
||||
let items = this.languageService.getNavigationBarItems(this.activeFile.fileName);
|
||||
|
||||
@@ -2264,7 +2260,7 @@ module FourSlash {
|
||||
return 'line ' + (pos.line + 1) + ', col ' + pos.character;
|
||||
}
|
||||
|
||||
private getMarkerByName(markerName: string) {
|
||||
public getMarkerByName(markerName: string) {
|
||||
let markerPos = this.testData.markerPositions[markerName];
|
||||
if (markerPos === undefined) {
|
||||
let markerNames: string[] = [];
|
||||
@@ -2739,4 +2735,4 @@ module FourSlash {
|
||||
fileName: fileName
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@ var Buffer: BufferConstructor = require('buffer').Buffer;
|
||||
// this will work in the browser via browserify
|
||||
var _chai: typeof chai = require('chai');
|
||||
var assert: typeof _chai.assert = _chai.assert;
|
||||
var expect: typeof _chai.expect = _chai.expect;
|
||||
declare var __dirname: string; // Node-specific
|
||||
var global = <any>Function("return this").call(null);
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ interface FindFileResult {
|
||||
}
|
||||
|
||||
interface IOLog {
|
||||
timestamp: string;
|
||||
arguments: string[];
|
||||
executingPath: string;
|
||||
currentDirectory: string;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/// <reference path="harness.ts" />
|
||||
|
||||
class RunnerBase {
|
||||
abstract class RunnerBase {
|
||||
constructor() { }
|
||||
|
||||
// contains the tests to run
|
||||
@@ -18,9 +18,7 @@ class RunnerBase {
|
||||
/** Setup the runner's tests so that they are ready to be executed by the harness
|
||||
* The first test should be a describe/it block that sets up the harness's compiler instance appropriately
|
||||
*/
|
||||
public initializeTests(): void {
|
||||
throw new Error('method not implemented');
|
||||
}
|
||||
public abstract initializeTests(): void;
|
||||
|
||||
/** Replaces instances of full paths with fileNames only */
|
||||
static removeFullPaths(path: string) {
|
||||
|
||||
@@ -202,9 +202,7 @@ namespace ts.server {
|
||||
return {
|
||||
isMemberCompletion: false,
|
||||
isNewIdentifierLocation: false,
|
||||
entries: response.body,
|
||||
fileName: fileName,
|
||||
position: position
|
||||
entries: response.body
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+45
-45
@@ -109,13 +109,13 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
export class Session {
|
||||
projectService: ProjectService;
|
||||
pendingOperation = false;
|
||||
fileHash: ts.Map<number> = {};
|
||||
nextFileId = 1;
|
||||
errorTimer: any; /*NodeJS.Timer | number*/
|
||||
immediateId: any;
|
||||
changeSeq = 0;
|
||||
protected projectService: ProjectService;
|
||||
private pendingOperation = false;
|
||||
private fileHash: ts.Map<number> = {};
|
||||
private nextFileId = 1;
|
||||
private errorTimer: any; /*NodeJS.Timer | number*/
|
||||
private immediateId: any;
|
||||
private changeSeq = 0;
|
||||
|
||||
constructor(
|
||||
private host: ServerHost,
|
||||
@@ -129,7 +129,7 @@ namespace ts.server {
|
||||
});
|
||||
}
|
||||
|
||||
handleEvent(eventName: string, project: Project, fileName: string) {
|
||||
private handleEvent(eventName: string, project: Project, fileName: string) {
|
||||
if (eventName == "context") {
|
||||
this.projectService.log("got context event, updating diagnostics for" + fileName, "Info");
|
||||
this.updateErrorCheck([{ fileName, project }], this.changeSeq,
|
||||
@@ -137,7 +137,7 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
logError(err: Error, cmd: string) {
|
||||
public logError(err: Error, cmd: string) {
|
||||
var typedErr = <StackTraceError>err;
|
||||
var msg = "Exception on executing command " + cmd;
|
||||
if (typedErr.message) {
|
||||
@@ -149,11 +149,11 @@ namespace ts.server {
|
||||
this.projectService.log(msg);
|
||||
}
|
||||
|
||||
sendLineToClient(line: string) {
|
||||
private sendLineToClient(line: string) {
|
||||
this.host.write(line + this.host.newLine);
|
||||
}
|
||||
|
||||
send(msg: protocol.Message) {
|
||||
public send(msg: protocol.Message) {
|
||||
var json = JSON.stringify(msg);
|
||||
if (this.logger.isVerbose()) {
|
||||
this.logger.info(msg.type + ": " + json);
|
||||
@@ -162,7 +162,7 @@ namespace ts.server {
|
||||
'\r\n\r\n' + json);
|
||||
}
|
||||
|
||||
event(info: any, eventName: string) {
|
||||
public event(info: any, eventName: string) {
|
||||
var ev: protocol.Event = {
|
||||
seq: 0,
|
||||
type: "event",
|
||||
@@ -172,7 +172,7 @@ namespace ts.server {
|
||||
this.send(ev);
|
||||
}
|
||||
|
||||
response(info: any, cmdName: string, reqSeq = 0, errorMsg?: string) {
|
||||
private response(info: any, cmdName: string, reqSeq = 0, errorMsg?: string) {
|
||||
var res: protocol.Response = {
|
||||
seq: 0,
|
||||
type: "response",
|
||||
@@ -189,11 +189,11 @@ namespace ts.server {
|
||||
this.send(res);
|
||||
}
|
||||
|
||||
output(body: any, commandName: string, requestSequence = 0, errorMessage?: string) {
|
||||
public output(body: any, commandName: string, requestSequence = 0, errorMessage?: string) {
|
||||
this.response(body, commandName, requestSequence, errorMessage);
|
||||
}
|
||||
|
||||
semanticCheck(file: string, project: Project) {
|
||||
private semanticCheck(file: string, project: Project) {
|
||||
try {
|
||||
var diags = project.compilerService.languageService.getSemanticDiagnostics(file);
|
||||
|
||||
@@ -207,7 +207,7 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
syntacticCheck(file: string, project: Project) {
|
||||
private syntacticCheck(file: string, project: Project) {
|
||||
try {
|
||||
var diags = project.compilerService.languageService.getSyntacticDiagnostics(file);
|
||||
if (diags) {
|
||||
@@ -220,12 +220,12 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
errorCheck(file: string, project: Project) {
|
||||
private errorCheck(file: string, project: Project) {
|
||||
this.syntacticCheck(file, project);
|
||||
this.semanticCheck(file, project);
|
||||
}
|
||||
|
||||
updateProjectStructure(seq: number, matchSeq: (seq: number) => boolean, ms = 1500) {
|
||||
private updateProjectStructure(seq: number, matchSeq: (seq: number) => boolean, ms = 1500) {
|
||||
setTimeout(() => {
|
||||
if (matchSeq(seq)) {
|
||||
this.projectService.updateProjectStructure();
|
||||
@@ -233,7 +233,7 @@ namespace ts.server {
|
||||
}, ms);
|
||||
}
|
||||
|
||||
updateErrorCheck(checkList: PendingErrorCheck[], seq: number,
|
||||
private updateErrorCheck(checkList: PendingErrorCheck[], seq: number,
|
||||
matchSeq: (seq: number) => boolean, ms = 1500, followMs = 200) {
|
||||
if (followMs > ms) {
|
||||
followMs = ms;
|
||||
@@ -269,7 +269,7 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
getDefinition(line: number, offset: number, fileName: string): protocol.FileSpan[] {
|
||||
private getDefinition(line: number, offset: number, fileName: string): protocol.FileSpan[] {
|
||||
var file = ts.normalizePath(fileName);
|
||||
var project = this.projectService.getProjectForFile(file);
|
||||
if (!project) {
|
||||
@@ -291,7 +291,7 @@ namespace ts.server {
|
||||
}));
|
||||
}
|
||||
|
||||
getTypeDefinition(line: number, offset: number, fileName: string): protocol.FileSpan[] {
|
||||
private getTypeDefinition(line: number, offset: number, fileName: string): protocol.FileSpan[] {
|
||||
var file = ts.normalizePath(fileName);
|
||||
var project = this.projectService.getProjectForFile(file);
|
||||
if (!project) {
|
||||
@@ -313,7 +313,7 @@ namespace ts.server {
|
||||
}));
|
||||
}
|
||||
|
||||
getOccurrences(line: number, offset: number, fileName: string): protocol.OccurrencesResponseItem[]{
|
||||
private getOccurrences(line: number, offset: number, fileName: string): protocol.OccurrencesResponseItem[]{
|
||||
fileName = ts.normalizePath(fileName);
|
||||
let project = this.projectService.getProjectForFile(fileName);
|
||||
|
||||
@@ -343,7 +343,7 @@ namespace ts.server {
|
||||
});
|
||||
}
|
||||
|
||||
getProjectInfo(fileName: string, needFileNameList: boolean): protocol.ProjectInfo {
|
||||
private getProjectInfo(fileName: string, needFileNameList: boolean): protocol.ProjectInfo {
|
||||
fileName = ts.normalizePath(fileName)
|
||||
let project = this.projectService.getProjectForFile(fileName)
|
||||
|
||||
@@ -358,7 +358,7 @@ namespace ts.server {
|
||||
return projectInfo;
|
||||
}
|
||||
|
||||
getRenameLocations(line: number, offset: number, fileName: string,findInComments: boolean, findInStrings: boolean): protocol.RenameResponseBody {
|
||||
private getRenameLocations(line: number, offset: number, fileName: string,findInComments: boolean, findInStrings: boolean): protocol.RenameResponseBody {
|
||||
var file = ts.normalizePath(fileName);
|
||||
var project = this.projectService.getProjectForFile(file);
|
||||
if (!project) {
|
||||
@@ -426,7 +426,7 @@ namespace ts.server {
|
||||
return { info: renameInfo, locs: bakedRenameLocs };
|
||||
}
|
||||
|
||||
getReferences(line: number, offset: number, fileName: string): protocol.ReferencesResponseBody {
|
||||
private getReferences(line: number, offset: number, fileName: string): protocol.ReferencesResponseBody {
|
||||
// TODO: get all projects for this file; report refs for all projects deleting duplicates
|
||||
// can avoid duplicates by eliminating same ref file from subsequent projects
|
||||
var file = ts.normalizePath(fileName);
|
||||
@@ -473,12 +473,12 @@ namespace ts.server {
|
||||
};
|
||||
}
|
||||
|
||||
openClientFile(fileName: string) {
|
||||
private openClientFile(fileName: string) {
|
||||
var file = ts.normalizePath(fileName);
|
||||
this.projectService.openClientFile(file);
|
||||
}
|
||||
|
||||
getQuickInfo(line: number, offset: number, fileName: string): protocol.QuickInfoResponseBody {
|
||||
private getQuickInfo(line: number, offset: number, fileName: string): protocol.QuickInfoResponseBody {
|
||||
var file = ts.normalizePath(fileName);
|
||||
var project = this.projectService.getProjectForFile(file);
|
||||
if (!project) {
|
||||
@@ -504,7 +504,7 @@ namespace ts.server {
|
||||
};
|
||||
}
|
||||
|
||||
getFormattingEditsForRange(line: number, offset: number, endLine: number, endOffset: number, fileName: string): protocol.CodeEdit[] {
|
||||
private getFormattingEditsForRange(line: number, offset: number, endLine: number, endOffset: number, fileName: string): protocol.CodeEdit[] {
|
||||
var file = ts.normalizePath(fileName);
|
||||
var project = this.projectService.getProjectForFile(file);
|
||||
if (!project) {
|
||||
@@ -531,7 +531,7 @@ namespace ts.server {
|
||||
});
|
||||
}
|
||||
|
||||
getFormattingEditsAfterKeystroke(line: number, offset: number, key: string, fileName: string): protocol.CodeEdit[] {
|
||||
private getFormattingEditsAfterKeystroke(line: number, offset: number, key: string, fileName: string): protocol.CodeEdit[] {
|
||||
var file = ts.normalizePath(fileName);
|
||||
|
||||
var project = this.projectService.getProjectForFile(file);
|
||||
@@ -607,7 +607,7 @@ namespace ts.server {
|
||||
});
|
||||
}
|
||||
|
||||
getCompletions(line: number, offset: number, prefix: string, fileName: string): protocol.CompletionEntry[] {
|
||||
private getCompletions(line: number, offset: number, prefix: string, fileName: string): protocol.CompletionEntry[] {
|
||||
if (!prefix) {
|
||||
prefix = "";
|
||||
}
|
||||
@@ -633,7 +633,7 @@ namespace ts.server {
|
||||
}, []).sort((a, b) => a.name.localeCompare(b.name));
|
||||
}
|
||||
|
||||
getCompletionEntryDetails(line: number, offset: number,
|
||||
private getCompletionEntryDetails(line: number, offset: number,
|
||||
entryNames: string[], fileName: string): protocol.CompletionEntryDetails[] {
|
||||
var file = ts.normalizePath(fileName);
|
||||
var project = this.projectService.getProjectForFile(file);
|
||||
@@ -653,7 +653,7 @@ namespace ts.server {
|
||||
}, []);
|
||||
}
|
||||
|
||||
getSignatureHelpItems(line: number, offset: number, fileName: string): protocol.SignatureHelpItems {
|
||||
private getSignatureHelpItems(line: number, offset: number, fileName: string): protocol.SignatureHelpItems {
|
||||
var file = ts.normalizePath(fileName);
|
||||
var project = this.projectService.getProjectForFile(file);
|
||||
if (!project) {
|
||||
@@ -682,7 +682,7 @@ namespace ts.server {
|
||||
return result;
|
||||
}
|
||||
|
||||
getDiagnostics(delay: number, fileNames: string[]) {
|
||||
private getDiagnostics(delay: number, fileNames: string[]) {
|
||||
var checkList = fileNames.reduce((accum: PendingErrorCheck[], fileName: string) => {
|
||||
fileName = ts.normalizePath(fileName);
|
||||
var project = this.projectService.getProjectForFile(fileName);
|
||||
@@ -697,7 +697,7 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
change(line: number, offset: number, endLine: number, endOffset: number, insertString: string, fileName: string) {
|
||||
private change(line: number, offset: number, endLine: number, endOffset: number, insertString: string, fileName: string) {
|
||||
var file = ts.normalizePath(fileName);
|
||||
var project = this.projectService.getProjectForFile(file);
|
||||
if (project) {
|
||||
@@ -712,7 +712,7 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
reload(fileName: string, tempFileName: string, reqSeq = 0) {
|
||||
private reload(fileName: string, tempFileName: string, reqSeq = 0) {
|
||||
var file = ts.normalizePath(fileName);
|
||||
var tmpfile = ts.normalizePath(tempFileName);
|
||||
var project = this.projectService.getProjectForFile(file);
|
||||
@@ -725,7 +725,7 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
saveToTmp(fileName: string, tempFileName: string) {
|
||||
private saveToTmp(fileName: string, tempFileName: string) {
|
||||
var file = ts.normalizePath(fileName);
|
||||
var tmpfile = ts.normalizePath(tempFileName);
|
||||
|
||||
@@ -735,12 +735,12 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
closeClientFile(fileName: string) {
|
||||
private closeClientFile(fileName: string) {
|
||||
var file = ts.normalizePath(fileName);
|
||||
this.projectService.closeClientFile(file);
|
||||
}
|
||||
|
||||
decorateNavigationBarItem(project: Project, fileName: string, items: ts.NavigationBarItem[]): protocol.NavigationBarItem[] {
|
||||
private decorateNavigationBarItem(project: Project, fileName: string, items: ts.NavigationBarItem[]): protocol.NavigationBarItem[] {
|
||||
if (!items) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -759,7 +759,7 @@ namespace ts.server {
|
||||
}));
|
||||
}
|
||||
|
||||
getNavigationBarItems(fileName: string): protocol.NavigationBarItem[] {
|
||||
private getNavigationBarItems(fileName: string): protocol.NavigationBarItem[] {
|
||||
var file = ts.normalizePath(fileName);
|
||||
var project = this.projectService.getProjectForFile(file);
|
||||
if (!project) {
|
||||
@@ -775,7 +775,7 @@ namespace ts.server {
|
||||
return this.decorateNavigationBarItem(project, fileName, items);
|
||||
}
|
||||
|
||||
getNavigateToItems(searchValue: string, fileName: string, maxResultCount?: number): protocol.NavtoItem[] {
|
||||
private getNavigateToItems(searchValue: string, fileName: string, maxResultCount?: number): protocol.NavtoItem[] {
|
||||
var file = ts.normalizePath(fileName);
|
||||
var project = this.projectService.getProjectForFile(file);
|
||||
if (!project) {
|
||||
@@ -814,7 +814,7 @@ namespace ts.server {
|
||||
});
|
||||
}
|
||||
|
||||
getBraceMatching(line: number, offset: number, fileName: string): protocol.TextSpan[] {
|
||||
private getBraceMatching(line: number, offset: number, fileName: string): protocol.TextSpan[] {
|
||||
var file = ts.normalizePath(fileName);
|
||||
|
||||
var project = this.projectService.getProjectForFile(file);
|
||||
@@ -836,7 +836,7 @@ namespace ts.server {
|
||||
}));
|
||||
}
|
||||
|
||||
exit() {
|
||||
public exit() {
|
||||
}
|
||||
|
||||
private handlers : Map<(request: protocol.Request) => {response?: any, responseRequired?: boolean}> = {
|
||||
@@ -942,14 +942,14 @@ namespace ts.server {
|
||||
return {response: this.getProjectInfo(file, needFileNameList), responseRequired: true};
|
||||
},
|
||||
};
|
||||
addProtocolHandler(command: string, handler: (request: protocol.Request) => {response?: any, responseRequired: boolean}) {
|
||||
public addProtocolHandler(command: string, handler: (request: protocol.Request) => {response?: any, responseRequired: boolean}) {
|
||||
if (this.handlers[command]) {
|
||||
throw new Error(`Protocol handler already exists for command "${command}"`);
|
||||
}
|
||||
this.handlers[command] = handler;
|
||||
}
|
||||
|
||||
executeCommand(request: protocol.Request) : {response?: any, responseRequired?: boolean} {
|
||||
public executeCommand(request: protocol.Request) : {response?: any, responseRequired?: boolean} {
|
||||
var handler = this.handlers[request.command];
|
||||
if (handler) {
|
||||
return handler(request);
|
||||
@@ -960,7 +960,7 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
onMessage(message: string) {
|
||||
public onMessage(message: string) {
|
||||
if (this.logger.isVerbose()) {
|
||||
this.logger.info("request: " + message);
|
||||
var start = this.hrtime();
|
||||
|
||||
+70
-29
@@ -48,6 +48,7 @@ namespace ts {
|
||||
getConstructSignatures(): Signature[];
|
||||
getStringIndexType(): Type;
|
||||
getNumberIndexType(): Type;
|
||||
getBaseTypes(): ObjectType[]
|
||||
}
|
||||
|
||||
export interface Signature {
|
||||
@@ -260,26 +261,25 @@ namespace ts {
|
||||
}
|
||||
|
||||
public getFirstToken(sourceFile?: SourceFile): Node {
|
||||
let children = this.getChildren();
|
||||
for (let child of children) {
|
||||
if (child.kind < SyntaxKind.FirstNode) {
|
||||
return child;
|
||||
}
|
||||
|
||||
return child.getFirstToken(sourceFile);
|
||||
let children = this.getChildren(sourceFile);
|
||||
if (!children.length) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let child = children[0];
|
||||
|
||||
return child.kind < SyntaxKind.FirstNode ? child : child.getFirstToken(sourceFile);
|
||||
}
|
||||
|
||||
public getLastToken(sourceFile?: SourceFile): Node {
|
||||
let children = this.getChildren(sourceFile);
|
||||
for (let i = children.length - 1; i >= 0; i--) {
|
||||
let child = children[i];
|
||||
if (child.kind < SyntaxKind.FirstNode) {
|
||||
return child;
|
||||
}
|
||||
|
||||
return child.getLastToken(sourceFile);
|
||||
let child = lastOrUndefined(children);
|
||||
if (!child) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return child.kind < SyntaxKind.FirstNode ? child : child.getLastToken(sourceFile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -682,6 +682,11 @@ namespace ts {
|
||||
getNumberIndexType(): Type {
|
||||
return this.checker.getIndexTypeOfType(this, IndexKind.Number);
|
||||
}
|
||||
getBaseTypes(): ObjectType[] {
|
||||
return this.flags & (TypeFlags.Class | TypeFlags.Interface)
|
||||
? this.checker.getBaseTypes(<TypeObject & InterfaceType>this)
|
||||
: undefined;
|
||||
}
|
||||
}
|
||||
|
||||
class SignatureObject implements Signature {
|
||||
@@ -1105,6 +1110,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export interface HighlightSpan {
|
||||
fileName?: string;
|
||||
textSpan: TextSpan;
|
||||
kind: string;
|
||||
}
|
||||
@@ -1411,7 +1417,9 @@ namespace ts {
|
||||
* @param fileName The name of the file to be released
|
||||
* @param compilationSettings The compilation settings used to acquire the file
|
||||
*/
|
||||
releaseDocument(fileName: string, compilationSettings: CompilerOptions): void
|
||||
releaseDocument(fileName: string, compilationSettings: CompilerOptions): void;
|
||||
|
||||
reportStats(): string;
|
||||
}
|
||||
|
||||
// TODO: move these to enums
|
||||
@@ -1751,18 +1759,31 @@ namespace ts {
|
||||
sourceFile.version = version;
|
||||
sourceFile.scriptSnapshot = scriptSnapshot;
|
||||
}
|
||||
|
||||
|
||||
export interface TranspileOptions {
|
||||
compilerOptions?: CompilerOptions;
|
||||
fileName?: string;
|
||||
reportDiagnostics?: boolean;
|
||||
moduleName?: string;
|
||||
}
|
||||
|
||||
export interface TranspileOutput {
|
||||
outputText: string;
|
||||
diagnostics?: Diagnostic[];
|
||||
sourceMapText?: string;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function will compile source text from 'input' argument using specified compiler options.
|
||||
* If not options are provided - it will use a set of default compiler options.
|
||||
* Extra compiler options that will unconditionally be used bu this function are:
|
||||
* Extra compiler options that will unconditionally be used by this function are:
|
||||
* - isolatedModules = true
|
||||
* - allowNonTsExtensions = true
|
||||
* - noLib = true
|
||||
* - noResolve = true
|
||||
*/
|
||||
export function transpile(input: string, compilerOptions?: CompilerOptions, fileName?: string, diagnostics?: Diagnostic[], moduleName?: string): string {
|
||||
let options = compilerOptions ? clone(compilerOptions) : getDefaultCompilerOptions();
|
||||
*/
|
||||
export function transpileModule(input: string, transpileOptions?: TranspileOptions): TranspileOutput {
|
||||
let options = transpileOptions.compilerOptions ? clone(transpileOptions.compilerOptions) : getDefaultCompilerOptions();
|
||||
|
||||
options.isolatedModules = true;
|
||||
|
||||
@@ -1778,23 +1799,30 @@ namespace ts {
|
||||
options.noResolve = true;
|
||||
|
||||
// Parse
|
||||
let inputFileName = fileName || "module.ts";
|
||||
let inputFileName = transpileOptions.fileName || "module.ts";
|
||||
let sourceFile = createSourceFile(inputFileName, input, options.target);
|
||||
if (moduleName) {
|
||||
sourceFile.moduleName = moduleName;
|
||||
if (transpileOptions.moduleName) {
|
||||
sourceFile.moduleName = transpileOptions.moduleName;
|
||||
}
|
||||
|
||||
let newLine = getNewLineCharacter(options);
|
||||
|
||||
// Output
|
||||
let outputText: string;
|
||||
let sourceMapText: string;
|
||||
|
||||
// Create a compilerHost object to allow the compiler to read and write files
|
||||
let compilerHost: CompilerHost = {
|
||||
getSourceFile: (fileName, target) => fileName === inputFileName ? sourceFile : undefined,
|
||||
writeFile: (name, text, writeByteOrderMark) => {
|
||||
Debug.assert(outputText === undefined, "Unexpected multiple outputs for the file: " + name);
|
||||
outputText = text;
|
||||
if (fileExtensionIs(name, ".map")) {
|
||||
Debug.assert(sourceMapText === undefined, `Unexpected multiple source map outputs for the file '${name}'`);
|
||||
sourceMapText = text;
|
||||
}
|
||||
else {
|
||||
Debug.assert(outputText === undefined, "Unexpected multiple outputs for the file: " + name);
|
||||
outputText = text;
|
||||
}
|
||||
},
|
||||
getDefaultLibFileName: () => "lib.d.ts",
|
||||
useCaseSensitiveFileNames: () => false,
|
||||
@@ -1804,16 +1832,29 @@ namespace ts {
|
||||
};
|
||||
|
||||
let program = createProgram([inputFileName], options, compilerHost);
|
||||
|
||||
addRange(/*to*/ diagnostics, /*from*/ program.getSyntacticDiagnostics(sourceFile));
|
||||
addRange(/*to*/ diagnostics, /*from*/ program.getOptionsDiagnostics());
|
||||
|
||||
|
||||
let diagnostics: Diagnostic[];
|
||||
if (transpileOptions.reportDiagnostics) {
|
||||
diagnostics = [];
|
||||
addRange(/*to*/ diagnostics, /*from*/ program.getSyntacticDiagnostics(sourceFile));
|
||||
addRange(/*to*/ diagnostics, /*from*/ program.getOptionsDiagnostics());
|
||||
}
|
||||
// Emit
|
||||
program.emit();
|
||||
|
||||
Debug.assert(outputText !== undefined, "Output generation failed");
|
||||
|
||||
return outputText;
|
||||
return { outputText, diagnostics, sourceMapText };
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a shortcut function for transpileModule - it accepts transpileOptions as parameters and returns only outputText part of the result.
|
||||
*/
|
||||
export function transpile(input: string, compilerOptions?: CompilerOptions, fileName?: string, diagnostics?: Diagnostic[], moduleName?: string): string {
|
||||
let output = transpileModule(input, { compilerOptions, fileName, reportDiagnostics: !!diagnostics, moduleName });
|
||||
// addRange correctly handles cases when wither 'from' or 'to' argument is missing
|
||||
addRange(diagnostics, output.diagnostics);
|
||||
return output.outputText;
|
||||
}
|
||||
|
||||
export function createLanguageServiceSourceFile(fileName: string, scriptSnapshot: IScriptSnapshot, scriptTarget: ScriptTarget, version: string, setNodeParents: boolean): SourceFile {
|
||||
|
||||
@@ -454,11 +454,11 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function realizeDiagnostics(diagnostics: Diagnostic[], newLine: string): { message: string; start: number; length: number; category: string; } []{
|
||||
export function realizeDiagnostics(diagnostics: Diagnostic[], newLine: string): { message: string; start: number; length: number; category: string; code: number; } []{
|
||||
return diagnostics.map(d => realizeDiagnostic(d, newLine));
|
||||
}
|
||||
|
||||
function realizeDiagnostic(diagnostic: Diagnostic, newLine: string): { message: string; start: number; length: number; category: string; } {
|
||||
function realizeDiagnostic(diagnostic: Diagnostic, newLine: string): { message: string; start: number; length: number; category: string; code: number; } {
|
||||
return {
|
||||
message: flattenDiagnosticMessageText(diagnostic.messageText, newLine),
|
||||
start: diagnostic.start,
|
||||
|
||||
Reference in New Issue
Block a user