Merge branch 'master' into errorForUseSuperInNullExtension

Conflicts:
	src/compiler/checker.ts
This commit is contained in:
Yui T
2015-07-27 15:37:02 -07:00
302 changed files with 5923 additions and 6348 deletions
+14 -8
View File
@@ -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);
}
}
}
}
+255 -120
View File
@@ -68,6 +68,7 @@ namespace ts {
getPropertyOfType,
getSignaturesOfType,
getIndexTypeOfType,
getBaseTypes,
getReturnTypeOfSignature,
getSymbolsInScope,
getSymbolAtLocation,
@@ -1993,15 +1994,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
@@ -3115,44 +3113,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) {
@@ -3310,9 +3321,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);
@@ -3417,6 +3425,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);
@@ -4026,26 +4057,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;
@@ -4064,30 +4148,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];
@@ -4097,38 +4177,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
@@ -4303,11 +4364,11 @@ namespace ts {
return getInferredType(context, i);
}
}
return t;
return t;
};
mapper.context = context;
return mapper;
return mapper;
}
function identityMapper(type: Type): Type {
@@ -4409,7 +4470,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));
@@ -4554,6 +4615,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
@@ -4573,7 +4644,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)) {
@@ -4650,18 +4737,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;
@@ -5358,6 +5449,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 = {};
@@ -6984,7 +7093,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) {
@@ -7215,10 +7324,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) {
@@ -7241,16 +7349,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();
@@ -7311,7 +7414,7 @@ namespace ts {
let elemInstanceType = getJsxElementInstanceType(node);
if (isTypeAny(elemInstanceType)) {
return links.resolvedJsxType = anyType;
return links.resolvedJsxType = elemInstanceType;
}
let propsName = getJsxElementPropertiesName();
@@ -8867,7 +8970,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);
@@ -9692,7 +9795,7 @@ namespace ts {
return getUnionType([leftType, rightType]);
case SyntaxKind.EqualsToken:
checkAssignmentOperator(rightType);
return rightType;
return getRegularTypeOfObjectLiteral(rightType);
case SyntaxKind.CommaToken:
return rightType;
}
@@ -10339,7 +10442,8 @@ namespace ts {
error(node, Diagnostics.A_constructor_cannot_contain_a_super_call_when_its_class_extends_null);
}
// The first statement in the body of a constructor must be a super call if both of the following are true:
// 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.
@@ -10347,14 +10451,26 @@ 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);
}
}
}
@@ -10749,9 +10865,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) {
@@ -10771,27 +10884,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 {
@@ -14045,7 +14176,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,7 @@ 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" },
Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration_instead: { code: 2651, 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 +510,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'." },
+9 -5
View File
@@ -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,10 @@
"category": "Error",
"code": 2650
},
"Merged declaration '{0}' cannot include a default export declaration. Consider adding a separate 'export default {0}' declaration instead.": {
"category": "Error",
"code": 2651
},
"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",
"code": 4000
@@ -2021,10 +2029,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
+70 -15
View File
@@ -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:
@@ -5429,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);
@@ -5779,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();
@@ -5786,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("}");
@@ -5961,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);
@@ -6122,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();
@@ -6158,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);
@@ -6791,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.
+3 -7
View File
@@ -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
View File
@@ -3,7 +3,7 @@
namespace ts {
export interface SourceFile {
fileWatcher: FileWatcher;
fileWatcher?: FileWatcher;
}
/**
+17 -3
View File
@@ -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,
@@ -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;
+1 -1
View File
@@ -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;
}
+6 -10
View File
@@ -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
};
}
}
}
+1
View File
@@ -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);
+1
View File
@@ -12,6 +12,7 @@ interface FindFileResult {
}
interface IOLog {
timestamp: string;
arguments: string[];
executingPath: string;
currentDirectory: string;
+2 -4
View File
@@ -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) {
+1 -3
View File
@@ -202,9 +202,7 @@ namespace ts.server {
return {
isMemberCompletion: false,
isNewIdentifierLocation: false,
entries: response.body,
fileName: fileName,
position: position
entries: response.body
};
}
+45 -45
View File
@@ -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
View File
@@ -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 {
+2 -2
View File
@@ -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,