mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into commentsNotPreserveForCallExp
This commit is contained in:
@@ -139,7 +139,7 @@ namespace ts {
|
||||
function getDeclarationName(node: Declaration): string {
|
||||
if (node.name) {
|
||||
if (node.kind === SyntaxKind.ModuleDeclaration && node.name.kind === SyntaxKind.StringLiteral) {
|
||||
return '"' + (<LiteralExpression>node.name).text + '"';
|
||||
return `"${(<LiteralExpression>node.name).text}"`;
|
||||
}
|
||||
if (node.name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
let nameExpression = (<ComputedPropertyName>node.name).expression;
|
||||
@@ -830,7 +830,7 @@ namespace ts {
|
||||
|
||||
// Note: the node text must be exactly "use strict" or 'use strict'. It is not ok for the
|
||||
// string to contain unicode escapes (as per ES5).
|
||||
return nodeText === '"use strict"' || nodeText === "'use strict'";
|
||||
return nodeText === "\"use strict\"" || nodeText === "'use strict'";
|
||||
}
|
||||
|
||||
function bindWorker(node: Node) {
|
||||
@@ -930,7 +930,7 @@ namespace ts {
|
||||
function bindSourceFileIfExternalModule() {
|
||||
setExportContextFlag(file);
|
||||
if (isExternalModule(file)) {
|
||||
bindAnonymousDeclaration(file, SymbolFlags.ValueModule, '"' + removeFileExtension(file.fileName) + '"');
|
||||
bindAnonymousDeclaration(file, SymbolFlags.ValueModule, `"${removeFileExtension(file.fileName)}"`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+228
-156
@@ -211,6 +211,9 @@ namespace ts {
|
||||
let assignableRelation: Map<RelationComparisonResult> = {};
|
||||
let identityRelation: Map<RelationComparisonResult> = {};
|
||||
|
||||
// This is for caching the result of getSymbolDisplayBuilder. Do not access directly.
|
||||
let _displayBuilder: SymbolDisplayBuilder;
|
||||
|
||||
type TypeSystemEntity = Symbol | Type | Signature;
|
||||
|
||||
const enum TypeSystemPropertyName {
|
||||
@@ -965,7 +968,7 @@ namespace ts {
|
||||
if (!moduleName) return;
|
||||
let isRelative = isExternalModuleNameRelative(moduleName);
|
||||
if (!isRelative) {
|
||||
let symbol = getSymbol(globals, '"' + moduleName + '"', SymbolFlags.ValueModule);
|
||||
let symbol = getSymbol(globals, "\"" + moduleName + "\"", SymbolFlags.ValueModule);
|
||||
if (symbol) {
|
||||
return symbol;
|
||||
}
|
||||
@@ -1490,8 +1493,6 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// This is for caching the result of getSymbolDisplayBuilder. Do not access directly.
|
||||
let _displayBuilder: SymbolDisplayBuilder;
|
||||
function getSymbolDisplayBuilder(): SymbolDisplayBuilder {
|
||||
|
||||
function getNameOfSymbol(symbol: Symbol): string {
|
||||
@@ -3448,7 +3449,7 @@ namespace ts {
|
||||
// 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);
|
||||
const resolved = resolveStructuredTypeMembers(type);
|
||||
return !!(resolved.properties.length === 0 ||
|
||||
resolved.stringIndexType ||
|
||||
resolved.numberIndexType ||
|
||||
@@ -3473,8 +3474,10 @@ namespace ts {
|
||||
return emptyArray;
|
||||
}
|
||||
|
||||
// Return the signatures of the given kind in the given type. Creates synthetic union signatures when necessary and
|
||||
// maps primitive types and type parameters are to their apparent types.
|
||||
/**
|
||||
* Return the signatures of the given kind in the given type. Creates synthetic union signatures when necessary and
|
||||
* maps primitive types and type parameters are to their apparent types.
|
||||
*/
|
||||
function getSignaturesOfType(type: Type, kind: SignatureKind): Signature[] {
|
||||
return getSignaturesOfStructuredType(getApparentType(type), kind);
|
||||
}
|
||||
@@ -4668,19 +4671,21 @@ namespace ts {
|
||||
let result: Ternary;
|
||||
// both types are the same - covers 'they are the same primitive type or both are Any' or the same type parameter cases
|
||||
if (source === target) return Ternary.True;
|
||||
if (relation !== identityRelation) {
|
||||
if (isTypeAny(target)) return Ternary.True;
|
||||
if (source === undefinedType) return Ternary.True;
|
||||
if (source === nullType && target !== undefinedType) return Ternary.True;
|
||||
if (source.flags & TypeFlags.Enum && target === numberType) return Ternary.True;
|
||||
if (source.flags & TypeFlags.StringLiteral && target === stringType) return Ternary.True;
|
||||
if (relation === assignableRelation) {
|
||||
if (isTypeAny(source)) return Ternary.True;
|
||||
if (source === numberType && target.flags & TypeFlags.Enum) return Ternary.True;
|
||||
}
|
||||
if (relation === identityRelation) {
|
||||
return isIdenticalTo(source, target);
|
||||
}
|
||||
|
||||
if (relation !== identityRelation && source.flags & TypeFlags.FreshObjectLiteral) {
|
||||
if (isTypeAny(target)) return Ternary.True;
|
||||
if (source === undefinedType) return Ternary.True;
|
||||
if (source === nullType && target !== undefinedType) return Ternary.True;
|
||||
if (source.flags & TypeFlags.Enum && target === numberType) return Ternary.True;
|
||||
if (source.flags & TypeFlags.StringLiteral && target === stringType) return Ternary.True;
|
||||
if (relation === assignableRelation) {
|
||||
if (isTypeAny(source)) return Ternary.True;
|
||||
if (source === numberType && target.flags & TypeFlags.Enum) return Ternary.True;
|
||||
}
|
||||
|
||||
if (source.flags & TypeFlags.FreshObjectLiteral) {
|
||||
if (hasExcessProperties(<FreshObjectLiteralType>source, target, reportErrors)) {
|
||||
if (reportErrors) {
|
||||
reportRelationError(headMessage, source, target);
|
||||
@@ -4696,78 +4701,66 @@ namespace ts {
|
||||
|
||||
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)) {
|
||||
// Note that the "each" checks must precede the "some" checks to produce the correct results
|
||||
if (source.flags & TypeFlags.Union) {
|
||||
if (result = eachTypeRelatedToType(<UnionType>source, target, reportErrors)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else if (source.flags & TypeFlags.TypeParameter && target.flags & TypeFlags.TypeParameter) {
|
||||
if (result = typeParameterRelatedTo(<TypeParameter>source, <TypeParameter>target, reportErrors)) {
|
||||
else if (target.flags & TypeFlags.Intersection) {
|
||||
if (result = typeRelatedToEachType(source, <IntersectionType>target, reportErrors)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else if (relation !== identityRelation) {
|
||||
// Note that the "each" checks must precede the "some" checks to produce the correct results
|
||||
if (source.flags & TypeFlags.Union) {
|
||||
if (result = eachTypeRelatedToType(<UnionType>source, target, reportErrors)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else if (target.flags & TypeFlags.Intersection) {
|
||||
if (result = typeRelatedToEachType(source, <IntersectionType>target, reportErrors)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// It is necessary to try "each" checks on both sides because there may be nested "some" checks
|
||||
// on either side that need to be prioritized. For example, A | B = (A | B) & (C | D) or
|
||||
// A & B = (A & B) | (C & D).
|
||||
if (source.flags & TypeFlags.Intersection) {
|
||||
// If target is a union type the following check will report errors so we suppress them here
|
||||
if (result = someTypeRelatedToType(<IntersectionType>source, target, reportErrors && !(target.flags & TypeFlags.Union))) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (target.flags & TypeFlags.Union) {
|
||||
if (result = typeRelatedToSomeType(source, <UnionType>target, reportErrors)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (source.flags & TypeFlags.Union && target.flags & TypeFlags.Union ||
|
||||
source.flags & TypeFlags.Intersection && target.flags & TypeFlags.Intersection) {
|
||||
if (result = eachTypeRelatedToSomeType(<UnionOrIntersectionType>source, <UnionOrIntersectionType>target)) {
|
||||
if (result &= eachTypeRelatedToSomeType(<UnionOrIntersectionType>target, <UnionOrIntersectionType>source)) {
|
||||
return result;
|
||||
}
|
||||
// It is necessary to try "some" checks on both sides because there may be nested "each" checks
|
||||
// on either side that need to be prioritized. For example, A | B = (A | B) & (C | D) or
|
||||
// A & B = (A & B) | (C & D).
|
||||
if (source.flags & TypeFlags.Intersection) {
|
||||
// If target is a union type the following check will report errors so we suppress them here
|
||||
if (result = someTypeRelatedToType(<IntersectionType>source, target, reportErrors && !(target.flags & TypeFlags.Union))) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (target.flags & TypeFlags.Union) {
|
||||
if (result = typeRelatedToSomeType(source, <UnionType>target, reportErrors)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Even if relationship doesn't hold for unions, type parameters, or generic type references,
|
||||
// it may hold in a structural comparison.
|
||||
// Report structural errors only if we haven't reported any errors yet
|
||||
let reportStructuralErrors = reportErrors && errorInfo === saveErrorInfo;
|
||||
// Identity relation does not use apparent type
|
||||
let sourceOrApparentType = relation === identityRelation ? source : getApparentType(source);
|
||||
// In a check of the form X = A & B, we will have previously checked if A relates to X or B relates
|
||||
// to X. Failing both of those we want to check if the aggregation of A and B's members structurally
|
||||
// relates to X. Thus, we include intersection types on the source side here.
|
||||
if (sourceOrApparentType.flags & (TypeFlags.ObjectType | TypeFlags.Intersection) && target.flags & TypeFlags.ObjectType) {
|
||||
if (result = objectTypeRelatedTo(sourceOrApparentType, <ObjectType>target, reportStructuralErrors)) {
|
||||
if (source.flags & TypeFlags.TypeParameter) {
|
||||
let constraint = getConstraintOfTypeParameter(<TypeParameter>source);
|
||||
if (!constraint || constraint.flags & TypeFlags.Any) {
|
||||
constraint = emptyObjectType;
|
||||
}
|
||||
// Report constraint errors only if the constraint is not the empty object type
|
||||
let reportConstraintErrors = reportErrors && constraint !== emptyObjectType;
|
||||
if (result = isRelatedTo(constraint, target, reportConstraintErrors)) {
|
||||
errorInfo = saveErrorInfo;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else if (source.flags & TypeFlags.TypeParameter && sourceOrApparentType.flags & TypeFlags.UnionOrIntersection) {
|
||||
// We clear the errors first because the following check often gives a better error than
|
||||
// the union or intersection comparison above if it is applicable.
|
||||
errorInfo = saveErrorInfo;
|
||||
if (result = isRelatedTo(sourceOrApparentType, target, reportErrors)) {
|
||||
return result;
|
||||
else {
|
||||
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)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// Even if relationship doesn't hold for unions, intersections, or generic type references,
|
||||
// it may hold in a structural comparison.
|
||||
let apparentType = getApparentType(source);
|
||||
// In a check of the form X = A & B, we will have previously checked if A relates to X or B relates
|
||||
// to X. Failing both of those we want to check if the aggregation of A and B's members structurally
|
||||
// relates to X. Thus, we include intersection types on the source side here.
|
||||
if (apparentType.flags & (TypeFlags.ObjectType | TypeFlags.Intersection) && target.flags & TypeFlags.ObjectType) {
|
||||
// Report structural errors only if we haven't reported any errors yet
|
||||
let reportStructuralErrors = reportErrors && errorInfo === saveErrorInfo;
|
||||
if (result = objectTypeRelatedTo(apparentType, <ObjectType>target, reportStructuralErrors)) {
|
||||
errorInfo = saveErrorInfo;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4777,6 +4770,31 @@ namespace ts {
|
||||
return Ternary.False;
|
||||
}
|
||||
|
||||
function isIdenticalTo(source: Type, target: Type): Ternary {
|
||||
let result: Ternary;
|
||||
if (source.flags & TypeFlags.ObjectType && target.flags & TypeFlags.ObjectType) {
|
||||
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 all type arguments are identical
|
||||
if (result = typesRelatedTo((<TypeReference>source).typeArguments, (<TypeReference>target).typeArguments, /*reportErrors*/ false)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return objectTypeRelatedTo(<ObjectType>source, <ObjectType>target, /*reportErrors*/ false);
|
||||
}
|
||||
if (source.flags & TypeFlags.TypeParameter && target.flags & TypeFlags.TypeParameter) {
|
||||
return typeParameterIdenticalTo(<TypeParameter>source, <TypeParameter>target);
|
||||
}
|
||||
if (source.flags & TypeFlags.Union && target.flags & TypeFlags.Union ||
|
||||
source.flags & TypeFlags.Intersection && target.flags & TypeFlags.Intersection) {
|
||||
if (result = eachTypeRelatedToSomeType(<UnionOrIntersectionType>source, <UnionOrIntersectionType>target)) {
|
||||
if (result &= eachTypeRelatedToSomeType(<UnionOrIntersectionType>target, <UnionOrIntersectionType>source)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Ternary.False;
|
||||
}
|
||||
|
||||
function hasExcessProperties(source: FreshObjectLiteralType, target: Type, reportErrors: boolean): boolean {
|
||||
for (let prop of getPropertiesOfObjectType(source)) {
|
||||
if (!isKnownProperty(target, prop.name)) {
|
||||
@@ -4861,29 +4879,18 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function typeParameterRelatedTo(source: TypeParameter, target: TypeParameter, reportErrors: boolean): Ternary {
|
||||
if (relation === identityRelation) {
|
||||
if (source.symbol.name !== target.symbol.name) {
|
||||
return Ternary.False;
|
||||
}
|
||||
// covers case when both type parameters does not have constraint (both equal to noConstraintType)
|
||||
if (source.constraint === target.constraint) {
|
||||
return Ternary.True;
|
||||
}
|
||||
if (source.constraint === noConstraintType || target.constraint === noConstraintType) {
|
||||
return Ternary.False;
|
||||
}
|
||||
return isRelatedTo(source.constraint, target.constraint, reportErrors);
|
||||
}
|
||||
else {
|
||||
while (true) {
|
||||
let constraint = getConstraintOfTypeParameter(source);
|
||||
if (constraint === target) return Ternary.True;
|
||||
if (!(constraint && constraint.flags & TypeFlags.TypeParameter)) break;
|
||||
source = <TypeParameter>constraint;
|
||||
}
|
||||
function typeParameterIdenticalTo(source: TypeParameter, target: TypeParameter): Ternary {
|
||||
if (source.symbol.name !== target.symbol.name) {
|
||||
return Ternary.False;
|
||||
}
|
||||
// covers case when both type parameters does not have constraint (both equal to noConstraintType)
|
||||
if (source.constraint === target.constraint) {
|
||||
return Ternary.True;
|
||||
}
|
||||
if (source.constraint === noConstraintType || target.constraint === noConstraintType) {
|
||||
return Ternary.False;
|
||||
}
|
||||
return isIdenticalTo(source.constraint, target.constraint);
|
||||
}
|
||||
|
||||
// Determine if two object types are related by structure. First, check if the result is already available in the global cache.
|
||||
@@ -5085,30 +5092,24 @@ namespace ts {
|
||||
let result = Ternary.True;
|
||||
let saveErrorInfo = errorInfo;
|
||||
|
||||
// Because the "abstractness" of a class is the same across all construct signatures
|
||||
// (internally we are checking the corresponding declaration), it is enough to perform
|
||||
// the check and report an error once over all pairs of source and target construct signatures.
|
||||
let sourceSig = sourceSignatures[0];
|
||||
// Note that in an extends-clause, targetSignatures is stripped, so the check never proceeds.
|
||||
let targetSig = targetSignatures[0];
|
||||
|
||||
if (sourceSig && targetSig) {
|
||||
let sourceErasedSignature = getErasedSignature(sourceSig);
|
||||
let targetErasedSignature = getErasedSignature(targetSig);
|
||||
|
||||
let sourceReturnType = sourceErasedSignature && getReturnTypeOfSignature(sourceErasedSignature);
|
||||
let targetReturnType = targetErasedSignature && getReturnTypeOfSignature(targetErasedSignature);
|
||||
if (kind === SignatureKind.Construct) {
|
||||
// Only want to compare the construct signatures for abstractness guarantees.
|
||||
|
||||
// Because the "abstractness" of a class is the same across all construct signatures
|
||||
// (internally we are checking the corresponding declaration), it is enough to perform
|
||||
// the check and report an error once over all pairs of source and target construct signatures.
|
||||
//
|
||||
// sourceSig and targetSig are (possibly) undefined.
|
||||
//
|
||||
// Note that in an extends-clause, targetSignatures is stripped, so the check never proceeds.
|
||||
let sourceSig = sourceSignatures[0];
|
||||
let targetSig = targetSignatures[0];
|
||||
|
||||
let sourceReturnDecl = sourceReturnType && sourceReturnType.symbol && getDeclarationOfKind(sourceReturnType.symbol, SyntaxKind.ClassDeclaration);
|
||||
let targetReturnDecl = targetReturnType && targetReturnType.symbol && getDeclarationOfKind(targetReturnType.symbol, SyntaxKind.ClassDeclaration);
|
||||
let sourceIsAbstract = sourceReturnDecl && sourceReturnDecl.flags & NodeFlags.Abstract;
|
||||
let targetIsAbstract = targetReturnDecl && targetReturnDecl.flags & NodeFlags.Abstract;
|
||||
|
||||
if (sourceIsAbstract && !targetIsAbstract) {
|
||||
if (reportErrors) {
|
||||
reportError(Diagnostics.Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type);
|
||||
}
|
||||
return Ternary.False;
|
||||
result &= abstractSignatureRelatedTo(source, sourceSig, target, targetSig);
|
||||
if (result !== Ternary.True) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5132,6 +5133,40 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
function abstractSignatureRelatedTo(source: Type, sourceSig: Signature, target: Type, targetSig: Signature) {
|
||||
if (sourceSig && targetSig) {
|
||||
|
||||
let sourceDecl = source.symbol && getDeclarationOfKind(source.symbol, SyntaxKind.ClassDeclaration);
|
||||
let targetDecl = target.symbol && getDeclarationOfKind(target.symbol, SyntaxKind.ClassDeclaration);
|
||||
|
||||
if (!sourceDecl) {
|
||||
// If the source object isn't itself a class declaration, it can be freely assigned, regardless
|
||||
// of whether the constructed object is abstract or not.
|
||||
return Ternary.True;
|
||||
}
|
||||
|
||||
let sourceErasedSignature = getErasedSignature(sourceSig);
|
||||
let targetErasedSignature = getErasedSignature(targetSig);
|
||||
|
||||
let sourceReturnType = sourceErasedSignature && getReturnTypeOfSignature(sourceErasedSignature);
|
||||
let targetReturnType = targetErasedSignature && getReturnTypeOfSignature(targetErasedSignature);
|
||||
|
||||
let sourceReturnDecl = sourceReturnType && sourceReturnType.symbol && getDeclarationOfKind(sourceReturnType.symbol, SyntaxKind.ClassDeclaration);
|
||||
let targetReturnDecl = targetReturnType && targetReturnType.symbol && getDeclarationOfKind(targetReturnType.symbol, SyntaxKind.ClassDeclaration);
|
||||
let sourceIsAbstract = sourceReturnDecl && sourceReturnDecl.flags & NodeFlags.Abstract;
|
||||
let targetIsAbstract = targetReturnDecl && targetReturnDecl.flags & NodeFlags.Abstract;
|
||||
|
||||
if (sourceIsAbstract && !(targetIsAbstract && targetDecl)) {
|
||||
// if target isn't a class-declaration type, then it can be new'd, so we forbid the assignment.
|
||||
if (reportErrors) {
|
||||
reportError(Diagnostics.Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type);
|
||||
}
|
||||
return Ternary.False;
|
||||
}
|
||||
}
|
||||
return Ternary.True;
|
||||
}
|
||||
}
|
||||
|
||||
function signatureRelatedTo(source: Signature, target: Signature, reportErrors: boolean): Ternary {
|
||||
@@ -5732,6 +5767,14 @@ namespace ts {
|
||||
inferFromTypes(sourceTypes[i], targetTypes[i]);
|
||||
}
|
||||
}
|
||||
else if (source.flags & TypeFlags.Tuple && target.flags & TypeFlags.Tuple && (<TupleType>source).elementTypes.length === (<TupleType>target).elementTypes.length) {
|
||||
// If source and target are tuples of the same size, infer from element types
|
||||
let sourceTypes = (<TupleType>source).elementTypes;
|
||||
let targetTypes = (<TupleType>target).elementTypes;
|
||||
for (let i = 0; i < sourceTypes.length; i++) {
|
||||
inferFromTypes(sourceTypes[i], targetTypes[i]);
|
||||
}
|
||||
}
|
||||
else if (target.flags & TypeFlags.UnionOrIntersection) {
|
||||
let targetTypes = (<UnionOrIntersectionType>target).types;
|
||||
let typeParameterCount = 0;
|
||||
@@ -6207,14 +6250,20 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getNarrowedType(originalType: Type, narrowedTypeCandidate: Type) {
|
||||
// Narrow to the target type if it's a subtype of the current type
|
||||
if (isTypeSubtypeOf(narrowedTypeCandidate, originalType)) {
|
||||
// If the current type is a union type, remove all constituents that aren't assignable to target. If that produces
|
||||
// 0 candidates, fall back to the assignability check
|
||||
if (originalType.flags & TypeFlags.Union) {
|
||||
let assignableConstituents = filter((<UnionType>originalType).types, t => isTypeAssignableTo(t, narrowedTypeCandidate));
|
||||
if (assignableConstituents.length) {
|
||||
return getUnionType(assignableConstituents);
|
||||
}
|
||||
}
|
||||
|
||||
if (isTypeAssignableTo(narrowedTypeCandidate, originalType)) {
|
||||
// Narrow to the target type if it's assignable to the current type
|
||||
return narrowedTypeCandidate;
|
||||
}
|
||||
// If the current type is a union type, remove all constituents that aren't subtypes of the target.
|
||||
if (originalType.flags & TypeFlags.Union) {
|
||||
return getUnionType(filter((<UnionType>originalType).types, t => isTypeSubtypeOf(t, narrowedTypeCandidate)));
|
||||
}
|
||||
|
||||
return originalType;
|
||||
}
|
||||
|
||||
@@ -7190,13 +7239,17 @@ namespace ts {
|
||||
}
|
||||
|
||||
function checkJsxElement(node: JsxElement) {
|
||||
// Check attributes
|
||||
checkJsxOpeningLikeElement(node.openingElement);
|
||||
|
||||
// Check that the closing tag matches
|
||||
if (!tagNamesAreEquivalent(node.openingElement.tagName, node.closingElement.tagName)) {
|
||||
error(node.closingElement, Diagnostics.Expected_corresponding_JSX_closing_tag_for_0, getTextOfNode(node.openingElement.tagName));
|
||||
}
|
||||
|
||||
// Check attributes
|
||||
checkJsxOpeningLikeElement(node.openingElement);
|
||||
else {
|
||||
// Perform resolution on the closing tag so that rename/go to definition/etc work
|
||||
getJsxElementTagSymbol(node.closingElement);
|
||||
}
|
||||
|
||||
// Check children
|
||||
for (let child of node.children) {
|
||||
@@ -7250,10 +7303,19 @@ namespace ts {
|
||||
else if (elementAttributesType && !isTypeAny(elementAttributesType)) {
|
||||
let correspondingPropSymbol = getPropertyOfType(elementAttributesType, node.name.text);
|
||||
correspondingPropType = correspondingPropSymbol && getTypeOfSymbol(correspondingPropSymbol);
|
||||
// If there's no corresponding property with this name, error
|
||||
if (!correspondingPropType && isUnhyphenatedJsxName(node.name.text)) {
|
||||
error(node.name, Diagnostics.Property_0_does_not_exist_on_type_1, node.name.text, typeToString(elementAttributesType));
|
||||
return unknownType;
|
||||
if (isUnhyphenatedJsxName(node.name.text)) {
|
||||
// Maybe there's a string indexer?
|
||||
let indexerType = getIndexTypeOfType(elementAttributesType, IndexKind.String);
|
||||
if (indexerType) {
|
||||
correspondingPropType = indexerType
|
||||
}
|
||||
else {
|
||||
// If there's no corresponding property with this name, error
|
||||
if (!correspondingPropType) {
|
||||
error(node.name, Diagnostics.Property_0_does_not_exist_on_type_1, node.name.text, typeToString(elementAttributesType));
|
||||
return unknownType;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7307,7 +7369,7 @@ namespace ts {
|
||||
/// If this is a class-based tag (otherwise returns undefined), returns the symbol of the class
|
||||
/// type or factory function.
|
||||
/// Otherwise, returns unknownSymbol.
|
||||
function getJsxElementTagSymbol(node: JsxOpeningLikeElement): Symbol {
|
||||
function getJsxElementTagSymbol(node: JsxOpeningLikeElement|JsxClosingElement): Symbol {
|
||||
let flags: JsxFlags = JsxFlags.UnknownElement;
|
||||
let links = getNodeLinks(node);
|
||||
if (!links.resolvedSymbol) {
|
||||
@@ -7319,7 +7381,7 @@ namespace ts {
|
||||
}
|
||||
return links.resolvedSymbol;
|
||||
|
||||
function lookupIntrinsicTag(node: JsxOpeningLikeElement): Symbol {
|
||||
function lookupIntrinsicTag(node: JsxOpeningLikeElement|JsxClosingElement): Symbol {
|
||||
let intrinsicElementsType = getJsxIntrinsicElementsType();
|
||||
if (intrinsicElementsType !== unknownType) {
|
||||
// Property case
|
||||
@@ -7337,7 +7399,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Wasn't found
|
||||
error(node, Diagnostics.Property_0_does_not_exist_on_type_1, (<Identifier>node.tagName).text, 'JSX.' + JsxNames.IntrinsicElements);
|
||||
error(node, Diagnostics.Property_0_does_not_exist_on_type_1, (<Identifier>node.tagName).text, "JSX." + JsxNames.IntrinsicElements);
|
||||
return unknownSymbol;
|
||||
}
|
||||
else {
|
||||
@@ -7347,19 +7409,10 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function lookupClassTag(node: JsxOpeningLikeElement): Symbol {
|
||||
let valueSymbol: Symbol;
|
||||
function lookupClassTag(node: JsxOpeningLikeElement|JsxClosingElement): Symbol {
|
||||
let valueSymbol: Symbol = resolveJsxTagName(node);
|
||||
|
||||
// Look up the value in the current scope
|
||||
if (node.tagName.kind === SyntaxKind.Identifier) {
|
||||
let tag = <Identifier>node.tagName;
|
||||
let sym = getResolvedSymbol(tag);
|
||||
valueSymbol = sym.exportSymbol || sym;
|
||||
}
|
||||
else {
|
||||
valueSymbol = checkQualifiedName(<QualifiedName>node.tagName).symbol;
|
||||
}
|
||||
|
||||
if (valueSymbol && valueSymbol !== unknownSymbol) {
|
||||
links.jsxFlags |= JsxFlags.ClassElement;
|
||||
getSymbolLinks(valueSymbol).referenced = true;
|
||||
@@ -7367,6 +7420,17 @@ namespace ts {
|
||||
|
||||
return valueSymbol || unknownSymbol;
|
||||
}
|
||||
|
||||
function resolveJsxTagName(node: JsxOpeningLikeElement|JsxClosingElement): Symbol {
|
||||
if (node.tagName.kind === SyntaxKind.Identifier) {
|
||||
let tag = <Identifier>node.tagName;
|
||||
let sym = getResolvedSymbol(tag);
|
||||
return sym.exportSymbol || sym;
|
||||
}
|
||||
else {
|
||||
return checkQualifiedName(<QualifiedName>node.tagName).symbol;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -7377,7 +7441,7 @@ namespace ts {
|
||||
function getJsxElementInstanceType(node: JsxOpeningLikeElement) {
|
||||
// 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');
|
||||
Debug.assert(!!(getNodeLinks(node).jsxFlags & JsxFlags.ClassElement), "Should not call getJsxElementInstanceType on non-class Element");
|
||||
|
||||
let classSymbol = getJsxElementTagSymbol(node);
|
||||
if (classSymbol === unknownSymbol) {
|
||||
@@ -7557,7 +7621,7 @@ namespace ts {
|
||||
// be marked as 'used' so we don't incorrectly elide its import. And if there
|
||||
// is no 'React' symbol in scope, we should issue an error.
|
||||
if (compilerOptions.jsx === JsxEmit.React) {
|
||||
let reactSym = resolveName(node.tagName, 'React', SymbolFlags.Value, Diagnostics.Cannot_find_name_0, 'React');
|
||||
let reactSym = resolveName(node.tagName, "React", SymbolFlags.Value, Diagnostics.Cannot_find_name_0, "React");
|
||||
if (reactSym) {
|
||||
getSymbolLinks(reactSym).referenced = true;
|
||||
}
|
||||
@@ -10451,17 +10515,21 @@ namespace ts {
|
||||
return n.kind === SyntaxKind.CallExpression && (<CallExpression>n).expression.kind === SyntaxKind.SuperKeyword;
|
||||
}
|
||||
|
||||
function containsSuperCallAsComputedPropertyName(n: Declaration): boolean {
|
||||
return n.name && containsSuperCall(n.name);
|
||||
}
|
||||
|
||||
function containsSuperCall(n: Node): boolean {
|
||||
if (isSuperCallExpression(n)) {
|
||||
return true;
|
||||
}
|
||||
switch (n.kind) {
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.ObjectLiteralExpression: return false;
|
||||
default: return forEachChild(n, containsSuperCall);
|
||||
else if (isFunctionLike(n)) {
|
||||
return false;
|
||||
}
|
||||
else if (isClassLike(n)) {
|
||||
return forEach((<ClassLikeDeclaration>n).members, containsSuperCallAsComputedPropertyName);
|
||||
}
|
||||
return forEachChild(n, containsSuperCall);
|
||||
}
|
||||
|
||||
function markThisReferencesAsErrors(n: Node): void {
|
||||
@@ -13889,7 +13957,9 @@ namespace ts {
|
||||
meaning |= SymbolFlags.Alias;
|
||||
return resolveEntityName(<EntityName>entityName, meaning);
|
||||
}
|
||||
else if ((entityName.parent.kind === SyntaxKind.JsxOpeningElement) || (entityName.parent.kind === SyntaxKind.JsxSelfClosingElement)) {
|
||||
else if ((entityName.parent.kind === SyntaxKind.JsxOpeningElement) ||
|
||||
(entityName.parent.kind === SyntaxKind.JsxSelfClosingElement) ||
|
||||
(entityName.parent.kind === SyntaxKind.JsxClosingElement)) {
|
||||
return getJsxElementTagSymbol(<JsxOpeningLikeElement>entityName.parent);
|
||||
}
|
||||
else if (isExpression(entityName)) {
|
||||
@@ -14311,15 +14381,17 @@ namespace ts {
|
||||
return type.flags & TypeFlags.ObjectType && getSignaturesOfType(type, SignatureKind.Call).length > 0;
|
||||
}
|
||||
|
||||
function getTypeReferenceSerializationKind(node: TypeReferenceNode): TypeReferenceSerializationKind {
|
||||
function getTypeReferenceSerializationKind(typeName: EntityName): TypeReferenceSerializationKind {
|
||||
// Resolve the symbol as a value to ensure the type can be reached at runtime during emit.
|
||||
let symbol = resolveEntityName(node.typeName, SymbolFlags.Value, /*ignoreErrors*/ true);
|
||||
let constructorType = symbol ? getTypeOfSymbol(symbol) : undefined;
|
||||
let valueSymbol = resolveEntityName(typeName, SymbolFlags.Value, /*ignoreErrors*/ true);
|
||||
let constructorType = valueSymbol ? getTypeOfSymbol(valueSymbol) : undefined;
|
||||
if (constructorType && isConstructorType(constructorType)) {
|
||||
return TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue;
|
||||
}
|
||||
|
||||
let type = getTypeFromTypeNode(node);
|
||||
// Resolve the symbol as a type so that we can provide a more useful hint for the type serializer.
|
||||
let typeSymbol = resolveEntityName(typeName, SymbolFlags.Type, /*ignoreErrors*/ true);
|
||||
let type = getDeclaredTypeOfSymbol(typeSymbol);
|
||||
if (type === unknownType) {
|
||||
return TypeReferenceSerializationKind.Unknown;
|
||||
}
|
||||
|
||||
@@ -335,7 +335,7 @@ namespace ts {
|
||||
* @param fileName The path to the config file
|
||||
*/
|
||||
export function readConfigFile(fileName: string): { config?: any; error?: Diagnostic } {
|
||||
let text = '';
|
||||
let text = "";
|
||||
try {
|
||||
text = sys.readFile(fileName);
|
||||
}
|
||||
@@ -423,7 +423,7 @@ namespace ts {
|
||||
fileNames = map(<string[]>json["files"], s => combinePaths(basePath, s));
|
||||
}
|
||||
else {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, 'files', 'Array'));
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "files", "Array"));
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -219,10 +219,10 @@ namespace ts {
|
||||
export function reduceLeft<T, U>(array: T[], f: (a: U, x: T) => U, initial: U): U;
|
||||
export function reduceLeft<T, U>(array: T[], f: (a: U, x: T) => U, initial?: U): U {
|
||||
if (array) {
|
||||
var count = array.length;
|
||||
const count = array.length;
|
||||
if (count > 0) {
|
||||
var pos = 0;
|
||||
var result = arguments.length <= 2 ? array[pos++] : initial;
|
||||
let pos = 0;
|
||||
let result = arguments.length <= 2 ? array[pos++] : initial;
|
||||
while (pos < count) {
|
||||
result = f(<U>result, array[pos++]);
|
||||
}
|
||||
@@ -236,9 +236,9 @@ namespace ts {
|
||||
export function reduceRight<T, U>(array: T[], f: (a: U, x: T) => U, initial: U): U;
|
||||
export function reduceRight<T, U>(array: T[], f: (a: U, x: T) => U, initial?: U): U {
|
||||
if (array) {
|
||||
var pos = array.length - 1;
|
||||
let pos = array.length - 1;
|
||||
if (pos >= 0) {
|
||||
var result = arguments.length <= 2 ? array[pos--] : initial;
|
||||
let result = arguments.length <= 2 ? array[pos--] : initial;
|
||||
while (pos >= 0) {
|
||||
result = f(<U>result, array[pos--]);
|
||||
}
|
||||
@@ -523,7 +523,7 @@ namespace ts {
|
||||
if (path.lastIndexOf("file:///", 0) === 0) {
|
||||
return "file:///".length;
|
||||
}
|
||||
let idx = path.indexOf('://');
|
||||
let idx = path.indexOf("://");
|
||||
if (idx !== -1) {
|
||||
return idx + "://".length;
|
||||
}
|
||||
@@ -805,4 +805,4 @@ namespace ts {
|
||||
Debug.assert(false, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -750,14 +750,18 @@ namespace ts {
|
||||
}
|
||||
|
||||
function writeTypeAliasDeclaration(node: TypeAliasDeclaration) {
|
||||
let prevEnclosingDeclaration = enclosingDeclaration;
|
||||
enclosingDeclaration = node;
|
||||
emitJsDocComments(node);
|
||||
emitModuleElementDeclarationFlags(node);
|
||||
write("type ");
|
||||
writeTextOfNode(currentSourceFile, node.name);
|
||||
emitTypeParameters(node.typeParameters);
|
||||
write(" = ");
|
||||
emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.type, getTypeAliasDeclarationVisibilityError);
|
||||
write(";");
|
||||
writeLine();
|
||||
enclosingDeclaration = prevEnclosingDeclaration;
|
||||
|
||||
function getTypeAliasDeclarationVisibilityError(symbolAccesibilityResult: SymbolAccessiblityResult): SymbolAccessibilityDiagnostic {
|
||||
return {
|
||||
@@ -1497,11 +1501,8 @@ namespace ts {
|
||||
// emit : declare function foo({y: [a, b, c]}: { y: [any, any, any] }) void;
|
||||
writeTextOfNode(currentSourceFile, bindingElement.propertyName);
|
||||
write(": ");
|
||||
|
||||
// If bindingElement has propertyName property, then its name must be another bindingPattern of SyntaxKind.ObjectBindingPattern
|
||||
emitBindingPattern(<BindingPattern>bindingElement.name);
|
||||
}
|
||||
else if (bindingElement.name) {
|
||||
if (bindingElement.name) {
|
||||
if (isBindingPattern(bindingElement.name)) {
|
||||
// If it is a nested binding pattern, we will recursively descend into each element and emit each one separately.
|
||||
// In the case of rest element, we will omit rest element.
|
||||
|
||||
+66
-41
@@ -380,7 +380,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
function base64VLQFormatEncode(inValue: number) {
|
||||
function base64FormatEncode(inValue: number) {
|
||||
if (inValue < 64) {
|
||||
return 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.charAt(inValue);
|
||||
return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(inValue);
|
||||
}
|
||||
throw TypeError(inValue + ": not a 64 based value");
|
||||
}
|
||||
@@ -902,7 +902,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
// Any template literal or string literal with an extended escape
|
||||
// (e.g. "\u{0067}") will need to be downleveled as a escaped string literal.
|
||||
if (languageVersion < ScriptTarget.ES6 && (isTemplateLiteralKind(node.kind) || node.hasExtendedUnicodeEscape)) {
|
||||
return getQuotedEscapedLiteralText('"', node.text, '"');
|
||||
return getQuotedEscapedLiteralText("\"", node.text, "\"");
|
||||
}
|
||||
|
||||
// If we don't need to downlevel and we can reach the original source text using
|
||||
@@ -915,15 +915,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
// or an escaped quoted form of the original text if it's string-like.
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.StringLiteral:
|
||||
return getQuotedEscapedLiteralText('"', node.text, '"');
|
||||
return getQuotedEscapedLiteralText("\"", node.text, "\"");
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
return getQuotedEscapedLiteralText('`', node.text, '`');
|
||||
return getQuotedEscapedLiteralText("`", node.text, "`");
|
||||
case SyntaxKind.TemplateHead:
|
||||
return getQuotedEscapedLiteralText('`', node.text, '${');
|
||||
return getQuotedEscapedLiteralText("`", node.text, "${");
|
||||
case SyntaxKind.TemplateMiddle:
|
||||
return getQuotedEscapedLiteralText('}', node.text, '${');
|
||||
return getQuotedEscapedLiteralText("}", node.text, "${");
|
||||
case SyntaxKind.TemplateTail:
|
||||
return getQuotedEscapedLiteralText('}', node.text, '`');
|
||||
return getQuotedEscapedLiteralText("}", node.text, "`");
|
||||
case SyntaxKind.NumericLiteral:
|
||||
return node.text;
|
||||
}
|
||||
@@ -954,7 +954,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
text = text.replace(/\r\n?/g, "\n");
|
||||
text = escapeString(text);
|
||||
|
||||
write('"' + text + '"');
|
||||
write(`"${text}"`);
|
||||
}
|
||||
|
||||
function emitDownlevelTaggedTemplateArray(node: TaggedTemplateExpression, literalEmitter: (literal: LiteralExpression) => void) {
|
||||
@@ -1141,9 +1141,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
/// 'Div' for upper-cased or dotted names
|
||||
function emitTagName(name: Identifier|QualifiedName) {
|
||||
if (name.kind === SyntaxKind.Identifier && isIntrinsicJsxName((<Identifier>name).text)) {
|
||||
write('"');
|
||||
write("\"");
|
||||
emit(name);
|
||||
write('"');
|
||||
write("\"");
|
||||
}
|
||||
else {
|
||||
emit(name);
|
||||
@@ -1155,9 +1155,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
/// about keywords, just non-identifier characters
|
||||
function emitAttributeName(name: Identifier) {
|
||||
if (/[A-Za-z_]+[\w*]/.test(name.text)) {
|
||||
write('"');
|
||||
write("\"");
|
||||
emit(name);
|
||||
write('"');
|
||||
write("\"");
|
||||
}
|
||||
else {
|
||||
emit(name);
|
||||
@@ -1255,10 +1255,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
// Don't emit empty strings
|
||||
if (children[i].kind === SyntaxKind.JsxText) {
|
||||
let text = getTextToEmit(<JsxText>children[i]);
|
||||
if(text !== undefined) {
|
||||
write(', "');
|
||||
if (text !== undefined) {
|
||||
write(", \"");
|
||||
write(text);
|
||||
write('"');
|
||||
write("\"");
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1498,7 +1498,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
if (declaration.kind === SyntaxKind.ImportClause) {
|
||||
// Identifier references default import
|
||||
write(getGeneratedNameForNode(<ImportDeclaration>declaration.parent));
|
||||
write(languageVersion === ScriptTarget.ES3 ? '["default"]' : ".default");
|
||||
write(languageVersion === ScriptTarget.ES3 ? "[\"default\"]" : ".default");
|
||||
return;
|
||||
}
|
||||
else if (declaration.kind === SyntaxKind.ImportSpecifier) {
|
||||
@@ -2021,12 +2021,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
}
|
||||
|
||||
function tryEmitConstantValue(node: PropertyAccessExpression | ElementAccessExpression): boolean {
|
||||
if (compilerOptions.isolatedModules) {
|
||||
// do not inline enum values in separate compilation mode
|
||||
return false;
|
||||
}
|
||||
|
||||
let constantValue = resolver.getConstantValue(node);
|
||||
let constantValue = tryGetConstEnumValue(node);
|
||||
if (constantValue !== undefined) {
|
||||
write(constantValue.toString());
|
||||
if (!compilerOptions.removeComments) {
|
||||
@@ -2037,6 +2032,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function tryGetConstEnumValue(node: Node): number {
|
||||
if (compilerOptions.isolatedModules) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return node.kind === SyntaxKind.PropertyAccessExpression || node.kind === SyntaxKind.ElementAccessExpression
|
||||
? resolver.getConstantValue(<PropertyAccessExpression | ElementAccessExpression>node)
|
||||
: undefined
|
||||
}
|
||||
|
||||
// Returns 'true' if the code was actually indented, false otherwise.
|
||||
// If the code is not indented, an optional valueToWriteWhenNotIndenting will be
|
||||
@@ -2069,10 +2074,20 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
let indentedBeforeDot = indentIfOnDifferentLines(node, node.expression, node.dotToken);
|
||||
|
||||
// 1 .toString is a valid property access, emit a space after the literal
|
||||
// Also emit a space if expression is a integer const enum value - it will appear in generated code as numeric literal
|
||||
let shouldEmitSpace: boolean;
|
||||
if (!indentedBeforeDot && node.expression.kind === SyntaxKind.NumericLiteral) {
|
||||
let text = getSourceTextOfNodeFromSourceFile(currentSourceFile, node.expression);
|
||||
shouldEmitSpace = text.indexOf(tokenToString(SyntaxKind.DotToken)) < 0;
|
||||
if (!indentedBeforeDot) {
|
||||
if (node.expression.kind === SyntaxKind.NumericLiteral) {
|
||||
// check if numeric literal was originally written with a dot
|
||||
let text = getSourceTextOfNodeFromSourceFile(currentSourceFile, node.expression);
|
||||
shouldEmitSpace = text.indexOf(tokenToString(SyntaxKind.DotToken)) < 0;
|
||||
}
|
||||
else {
|
||||
// check if constant enum value is integer
|
||||
let constantValue = tryGetConstEnumValue(node.expression);
|
||||
// isFinite handles cases when constantValue is undefined
|
||||
shouldEmitSpace = isFinite(constantValue) && Math.floor(constantValue) === constantValue;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldEmitSpace) {
|
||||
@@ -4286,11 +4301,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
emitDetachedComments(ctor.body.statements);
|
||||
}
|
||||
emitCaptureThisForNodeIfNecessary(node);
|
||||
let superCall: ExpressionStatement;
|
||||
if (ctor) {
|
||||
emitDefaultValueAssignments(ctor);
|
||||
emitRestParameter(ctor);
|
||||
if (baseTypeElement) {
|
||||
var superCall = findInitialSuperCall(ctor);
|
||||
superCall = findInitialSuperCall(ctor);
|
||||
if (superCall) {
|
||||
writeLine();
|
||||
emit(superCall);
|
||||
@@ -4960,14 +4976,22 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
|
||||
/** Serializes a TypeReferenceNode to an appropriate JS constructor value. Used by the __metadata decorator. */
|
||||
function emitSerializedTypeReferenceNode(node: TypeReferenceNode) {
|
||||
let typeName = node.typeName;
|
||||
let result = resolver.getTypeReferenceSerializationKind(node);
|
||||
let location: Node = node.parent;
|
||||
while (isDeclaration(location) || isTypeNode(location)) {
|
||||
location = location.parent;
|
||||
}
|
||||
|
||||
// Clone the type name and parent it to a location outside of the current declaration.
|
||||
let typeName = cloneEntityName(node.typeName);
|
||||
typeName.parent = location;
|
||||
|
||||
let result = resolver.getTypeReferenceSerializationKind(typeName);
|
||||
switch (result) {
|
||||
case TypeReferenceSerializationKind.Unknown:
|
||||
let temp = createAndRecordTempVariable(TempFlags.Auto);
|
||||
write("(typeof (");
|
||||
emitNodeWithoutSourceMap(temp);
|
||||
write(" = ")
|
||||
write(" = ");
|
||||
emitEntityNameAsExpression(typeName, /*useFallback*/ true);
|
||||
write(") === 'function' && ");
|
||||
emitNodeWithoutSourceMap(temp);
|
||||
@@ -5026,7 +5050,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
//
|
||||
// For the rules on serializing the type of each parameter declaration, see `serializeTypeOfDeclaration`.
|
||||
if (node) {
|
||||
var valueDeclaration: FunctionLikeDeclaration;
|
||||
let valueDeclaration: FunctionLikeDeclaration;
|
||||
if (node.kind === SyntaxKind.ClassDeclaration) {
|
||||
valueDeclaration = getFirstConstructorWithBody(<ClassDeclaration>node);
|
||||
}
|
||||
@@ -5035,8 +5059,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
}
|
||||
|
||||
if (valueDeclaration) {
|
||||
var parameters = valueDeclaration.parameters;
|
||||
var parameterCount = parameters.length;
|
||||
const parameters = valueDeclaration.parameters;
|
||||
const parameterCount = parameters.length;
|
||||
if (parameterCount > 0) {
|
||||
for (var i = 0; i < parameterCount; i++) {
|
||||
if (i > 0) {
|
||||
@@ -5044,7 +5068,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
}
|
||||
|
||||
if (parameters[i].dotDotDotToken) {
|
||||
var parameterType = parameters[i].type;
|
||||
let parameterType = parameters[i].type;
|
||||
if (parameterType.kind === SyntaxKind.ArrayType) {
|
||||
parameterType = (<ArrayTypeNode>parameterType).elementType;
|
||||
}
|
||||
@@ -5093,6 +5117,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
argumentsWritten++;
|
||||
}
|
||||
if (shouldEmitParamTypesMetadata(node)) {
|
||||
debugger;
|
||||
if (writeComma || argumentsWritten) {
|
||||
write(", ");
|
||||
}
|
||||
@@ -5856,7 +5881,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
writeLine();
|
||||
write("}");
|
||||
writeLine();
|
||||
write(`${exportFunctionForFile}(exports);`)
|
||||
write(`${exportFunctionForFile}(exports);`);
|
||||
decreaseIndent();
|
||||
writeLine();
|
||||
write("}");
|
||||
@@ -6204,7 +6229,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
// exports_(reexports);
|
||||
let reexportsVariableName = makeUniqueName("reexports");
|
||||
writeLine();
|
||||
write(`var ${reexportsVariableName} = {};`)
|
||||
write(`var ${reexportsVariableName} = {};`);
|
||||
writeLine();
|
||||
for (let e of (<ExportDeclaration>importNode).exportClause.elements) {
|
||||
write(`${reexportsVariableName}["`);
|
||||
@@ -6470,7 +6495,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
if (isLineBreak(c)) {
|
||||
if (firstNonWhitespace !== -1 && (lastNonWhitespace - firstNonWhitespace + 1 > 0)) {
|
||||
let part = text.substr(firstNonWhitespace, lastNonWhitespace - firstNonWhitespace + 1);
|
||||
result = (result ? result + '" + \' \' + "' : '') + part;
|
||||
result = (result ? result + "\" + ' ' + \"" : "") + part;
|
||||
}
|
||||
firstNonWhitespace = -1;
|
||||
}
|
||||
@@ -6483,7 +6508,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
}
|
||||
if (firstNonWhitespace !== -1) {
|
||||
let part = text.substr(firstNonWhitespace);
|
||||
result = (result ? result + '" + \' \' + "' : '') + part;
|
||||
result = (result ? result + "\" + ' ' + \"" : "") + part;
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -6508,9 +6533,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
function emitJsxText(node: JsxText) {
|
||||
switch (compilerOptions.jsx) {
|
||||
case JsxEmit.React:
|
||||
write('"');
|
||||
write("\"");
|
||||
write(trimReactWhitespace(node));
|
||||
write('"');
|
||||
write("\"");
|
||||
break;
|
||||
|
||||
case JsxEmit.Preserve:
|
||||
@@ -6525,9 +6550,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
switch (compilerOptions.jsx) {
|
||||
case JsxEmit.Preserve:
|
||||
default:
|
||||
write('{');
|
||||
write("{");
|
||||
emit(node.expression);
|
||||
write('}');
|
||||
write("}");
|
||||
break;
|
||||
case JsxEmit.React:
|
||||
emit(node.expression);
|
||||
|
||||
@@ -3148,7 +3148,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function parseAwaitExpression() {
|
||||
var node = <AwaitExpression>createNode(SyntaxKind.AwaitExpression);
|
||||
const node = <AwaitExpression>createNode(SyntaxKind.AwaitExpression);
|
||||
nextToken();
|
||||
node.expression = parseUnaryExpressionOrHigher();
|
||||
return finishNode(node);
|
||||
@@ -3340,7 +3340,7 @@ namespace ts {
|
||||
case SyntaxKind.LessThanToken:
|
||||
return parseJsxElementOrSelfClosingElement();
|
||||
}
|
||||
Debug.fail('Unknown JSX child kind ' + token);
|
||||
Debug.fail("Unknown JSX child kind " + token);
|
||||
}
|
||||
|
||||
function parseJsxChildren(openingTagName: EntityName): NodeArray<JsxChild> {
|
||||
@@ -5140,7 +5140,7 @@ namespace ts {
|
||||
// the 'from' keyword can be parsed as a named export when the export clause is unterminated (i.e. `export { from "moduleName";`)
|
||||
// If we don't have a 'from' keyword, see if we have a string literal such that ASI won't take effect.
|
||||
if (token === SyntaxKind.FromKeyword || (token === SyntaxKind.StringLiteral && !scanner.hasPrecedingLineBreak())) {
|
||||
parseExpected(SyntaxKind.FromKeyword)
|
||||
parseExpected(SyntaxKind.FromKeyword);
|
||||
node.moduleSpecifier = parseModuleSpecifier();
|
||||
}
|
||||
}
|
||||
@@ -6011,7 +6011,7 @@ namespace ts {
|
||||
return;
|
||||
|
||||
function visitNode(node: IncrementalNode) {
|
||||
let text = '';
|
||||
let text = "";
|
||||
if (aggressiveChecks && shouldCheckNode(node)) {
|
||||
text = oldText.substring(node.pos, node.end);
|
||||
}
|
||||
|
||||
@@ -660,9 +660,9 @@ namespace ts {
|
||||
ch >= CharacterCodes._0 && ch <= CharacterCodes._9 || ch === CharacterCodes.$ || ch === CharacterCodes._ ||
|
||||
ch > CharacterCodes.maxAsciiCharacter && isUnicodeIdentifierPart(ch, languageVersion);
|
||||
}
|
||||
|
||||
|
||||
/* @internal */
|
||||
// Creates a scanner over a (possibly unspecified) range of a piece of text.
|
||||
// Creates a scanner over a (possibly unspecified) range of a piece of text.
|
||||
export function createScanner(languageVersion: ScriptTarget,
|
||||
skipTrivia: boolean,
|
||||
languageVariant = LanguageVariant.Standard,
|
||||
@@ -1121,7 +1121,7 @@ namespace ts {
|
||||
|
||||
// Special handling for shebang
|
||||
if (ch === CharacterCodes.hash && pos === 0 && isShebangTrivia(text, pos)) {
|
||||
pos = scanShebangTrivia(text ,pos);
|
||||
pos = scanShebangTrivia(text, pos);
|
||||
if (skipTrivia) {
|
||||
continue;
|
||||
}
|
||||
|
||||
+13
-13
@@ -30,8 +30,8 @@ namespace ts {
|
||||
declare var global: any;
|
||||
declare var __filename: string;
|
||||
declare var Buffer: {
|
||||
new (str: string, encoding ?: string): any;
|
||||
}
|
||||
new (str: string, encoding?: string): any;
|
||||
};
|
||||
|
||||
declare class Enumerator {
|
||||
public atEnd(): boolean;
|
||||
@@ -188,13 +188,13 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
function getNodeSystem(): System {
|
||||
var _fs = require("fs");
|
||||
var _path = require("path");
|
||||
var _os = require('os');
|
||||
const _fs = require("fs");
|
||||
const _path = require("path");
|
||||
const _os = require("os");
|
||||
|
||||
var platform: string = _os.platform();
|
||||
const platform: string = _os.platform();
|
||||
// win32\win64 are case insensitive platforms, MacOS (darwin) by default is also case insensitive
|
||||
var useCaseSensitiveFileNames = platform !== "win32" && platform !== "win64" && platform !== "darwin";
|
||||
const useCaseSensitiveFileNames = platform !== "win32" && platform !== "win64" && platform !== "darwin";
|
||||
|
||||
function readFile(fileName: string, encoding?: string): string {
|
||||
if (!_fs.existsSync(fileName)) {
|
||||
@@ -228,7 +228,7 @@ namespace ts {
|
||||
function writeFile(fileName: string, data: string, writeByteOrderMark?: boolean): void {
|
||||
// If a BOM is required, emit one
|
||||
if (writeByteOrderMark) {
|
||||
data = '\uFEFF' + data;
|
||||
data = "\uFEFF" + data;
|
||||
}
|
||||
|
||||
_fs.writeFileSync(fileName, data, "utf8");
|
||||
@@ -271,10 +271,10 @@ namespace ts {
|
||||
newLine: _os.EOL,
|
||||
useCaseSensitiveFileNames: useCaseSensitiveFileNames,
|
||||
write(s: string): void {
|
||||
var buffer = new Buffer(s, 'utf8');
|
||||
var offset: number = 0;
|
||||
var toWrite: number = buffer.length;
|
||||
var written = 0;
|
||||
const buffer = new Buffer(s, "utf8");
|
||||
let offset: number = 0;
|
||||
let toWrite: number = buffer.length;
|
||||
let written = 0;
|
||||
// 1 is a standard descriptor for stdout
|
||||
while ((written = _fs.writeSync(1, buffer, offset, toWrite)) < toWrite) {
|
||||
offset += written;
|
||||
@@ -297,7 +297,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
callback(fileName);
|
||||
};
|
||||
}
|
||||
},
|
||||
resolvePath: function (path: string): string {
|
||||
return _path.resolve(path);
|
||||
|
||||
+2
-2
@@ -245,7 +245,7 @@ namespace ts {
|
||||
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Compilation_complete_Watching_for_file_changes));
|
||||
}
|
||||
|
||||
function getSourceFile(fileName: string, languageVersion: ScriptTarget, onError ?: (message: string) => void) {
|
||||
function getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void) {
|
||||
// Return existing SourceFile object if one is available
|
||||
if (cachedProgram) {
|
||||
let sourceFile = cachedProgram.getSourceFile(fileName);
|
||||
@@ -363,7 +363,7 @@ namespace ts {
|
||||
// If we didn't have any syntactic errors, then also try getting the global and
|
||||
// semantic errors.
|
||||
if (diagnostics.length === 0) {
|
||||
diagnostics = program.getGlobalDiagnostics();
|
||||
diagnostics = program.getOptionsDiagnostics().concat(program.getGlobalDiagnostics());
|
||||
|
||||
if (diagnostics.length === 0) {
|
||||
diagnostics = program.getSemanticDiagnostics();
|
||||
|
||||
@@ -1578,7 +1578,7 @@ namespace ts {
|
||||
getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number;
|
||||
getBlockScopedVariableId(node: Identifier): number;
|
||||
getReferencedValueDeclaration(reference: Identifier): Declaration;
|
||||
getTypeReferenceSerializationKind(node: TypeReferenceNode): TypeReferenceSerializationKind;
|
||||
getTypeReferenceSerializationKind(typeName: EntityName): TypeReferenceSerializationKind;
|
||||
isOptionalParameter(node: ParameterDeclaration): boolean;
|
||||
}
|
||||
|
||||
@@ -1786,10 +1786,10 @@ namespace ts {
|
||||
ObjectType = Class | Interface | Reference | Tuple | Anonymous,
|
||||
UnionOrIntersection = Union | Intersection,
|
||||
StructuredType = ObjectType | Union | Intersection,
|
||||
/* @internal */
|
||||
/* @internal */
|
||||
RequiresWidening = ContainsUndefinedOrNull | ContainsObjectLiteral,
|
||||
/* @internal */
|
||||
PropagatingFlags = ContainsUndefinedOrNull | ContainsObjectLiteral | ContainsAnyFunctionType
|
||||
PropagatingFlags = ContainsUndefinedOrNull | ContainsObjectLiteral | ContainsAnyFunctionType
|
||||
}
|
||||
|
||||
// Properties common to all types
|
||||
|
||||
@@ -1410,6 +1410,22 @@ namespace ts {
|
||||
return isFunctionLike(n) || n.kind === SyntaxKind.ModuleDeclaration || n.kind === SyntaxKind.SourceFile;
|
||||
}
|
||||
|
||||
export function cloneEntityName(node: EntityName): EntityName {
|
||||
if (node.kind === SyntaxKind.Identifier) {
|
||||
let clone = <Identifier>createSynthesizedNode(SyntaxKind.Identifier);
|
||||
clone.text = (<Identifier>node).text;
|
||||
return clone;
|
||||
}
|
||||
else {
|
||||
let clone = <QualifiedName>createSynthesizedNode(SyntaxKind.QualifiedName);
|
||||
clone.left = cloneEntityName((<QualifiedName>node).left);
|
||||
clone.left.parent = clone;
|
||||
clone.right = <Identifier>cloneEntityName((<QualifiedName>node).right);
|
||||
clone.right.parent = clone;
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
|
||||
export function nodeIsSynthesized(node: Node): boolean {
|
||||
return node.pos === -1;
|
||||
}
|
||||
@@ -1854,7 +1870,7 @@ namespace ts {
|
||||
|
||||
function writeTrimmedCurrentLine(pos: number, nextLineStart: number) {
|
||||
let end = Math.min(comment.end, nextLineStart - 1);
|
||||
let currentLineText = currentSourceFile.text.substring(pos, end).replace(/^\s+|\s+$/g, '');
|
||||
let currentLineText = currentSourceFile.text.substring(pos, end).replace(/^\s+|\s+$/g, "");
|
||||
if (currentLineText) {
|
||||
// trimmed forward and ending spaces text
|
||||
writer.write(currentLineText);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/// <reference path='harness.ts' />
|
||||
/// <reference path='runnerbase.ts' />
|
||||
/// <reference path='typeWriter.ts' />
|
||||
/// <reference path="harness.ts" />
|
||||
/// <reference path="runnerbase.ts" />
|
||||
/// <reference path="typeWriter.ts" />
|
||||
|
||||
const enum CompilerTestType {
|
||||
Conformance,
|
||||
@@ -9,7 +9,7 @@ const enum CompilerTestType {
|
||||
}
|
||||
|
||||
class CompilerBaselineRunner extends RunnerBase {
|
||||
private basePath = 'tests/cases';
|
||||
private basePath = "tests/cases";
|
||||
private testSuiteName: string;
|
||||
private errors: boolean;
|
||||
private emit: boolean;
|
||||
@@ -25,21 +25,21 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
this.decl = true;
|
||||
this.output = true;
|
||||
if (testType === CompilerTestType.Conformance) {
|
||||
this.testSuiteName = 'conformance';
|
||||
this.testSuiteName = "conformance";
|
||||
}
|
||||
else if (testType === CompilerTestType.Regressions) {
|
||||
this.testSuiteName = 'compiler';
|
||||
this.testSuiteName = "compiler";
|
||||
}
|
||||
else if (testType === CompilerTestType.Test262) {
|
||||
this.testSuiteName = 'test262';
|
||||
this.testSuiteName = "test262";
|
||||
} else {
|
||||
this.testSuiteName = 'compiler'; // default to this for historical reasons
|
||||
this.testSuiteName = "compiler"; // default to this for historical reasons
|
||||
}
|
||||
this.basePath += '/' + this.testSuiteName;
|
||||
this.basePath += "/" + this.testSuiteName;
|
||||
}
|
||||
|
||||
public checkTestCodeOutput(fileName: string) {
|
||||
describe('compiler tests for ' + fileName, () => {
|
||||
describe("compiler tests for " + fileName, () => {
|
||||
// Mocha holds onto the closure environment of the describe callback even after the test is done.
|
||||
// Everything declared here should be cleared out in the "after" callback.
|
||||
let justName: string;
|
||||
@@ -64,14 +64,14 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
let createNewInstance = false;
|
||||
|
||||
before(() => {
|
||||
justName = fileName.replace(/^.*[\\\/]/, ''); // strips the fileName from the path.
|
||||
justName = fileName.replace(/^.*[\\\/]/, ""); // strips the fileName from the path.
|
||||
content = Harness.IO.readFile(fileName);
|
||||
testCaseContent = Harness.TestCaseParser.makeUnitsFromTest(content, fileName);
|
||||
units = testCaseContent.testUnitData;
|
||||
tcSettings = testCaseContent.settings;
|
||||
createNewInstance = false;
|
||||
lastUnit = units[units.length - 1];
|
||||
rootDir = lastUnit.originalFilePath.indexOf('conformance') === -1 ? 'tests/cases/compiler/' : lastUnit.originalFilePath.substring(0, lastUnit.originalFilePath.lastIndexOf('/')) + '/';
|
||||
rootDir = lastUnit.originalFilePath.indexOf("conformance") === -1 ? "tests/cases/compiler/" : lastUnit.originalFilePath.substring(0, lastUnit.originalFilePath.lastIndexOf("/")) + "/";
|
||||
harnessCompiler = Harness.Compiler.getCompiler();
|
||||
// We need to assemble the list of input files for the compiler and other related files on the 'filesystem' (ie in a multi-file test)
|
||||
// If the last file in a test uses require or a triple slash reference we'll assume all other files will be brought in via references,
|
||||
@@ -106,7 +106,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
eventually to remove this limitation. */
|
||||
for (let i = 0; i < tcSettings.length; ++i) {
|
||||
// noImplicitAny is passed to getCompiler, but target is just passed in the settings blob to setCompilerSettings
|
||||
if (!createNewInstance && (tcSettings[i].flag == "noimplicitany" || tcSettings[i].flag === 'target')) {
|
||||
if (!createNewInstance && (tcSettings[i].flag == "noimplicitany" || tcSettings[i].flag === "target")) {
|
||||
harnessCompiler = Harness.Compiler.getCompiler();
|
||||
harnessCompiler.setCompilerSettings(tcSettings);
|
||||
createNewInstance = true;
|
||||
@@ -148,9 +148,9 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
}
|
||||
|
||||
// check errors
|
||||
it('Correct errors for ' + fileName, () => {
|
||||
it("Correct errors for " + fileName, () => {
|
||||
if (this.errors) {
|
||||
Harness.Baseline.runBaseline('Correct errors for ' + fileName, justName.replace(/\.tsx?$/, '.errors.txt'), (): string => {
|
||||
Harness.Baseline.runBaseline("Correct errors for " + fileName, justName.replace(/\.tsx?$/, ".errors.txt"), (): string => {
|
||||
if (result.errors.length === 0) return null;
|
||||
return getErrorBaseline(toBeCompiled, otherFiles, result);
|
||||
});
|
||||
@@ -158,12 +158,12 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
});
|
||||
|
||||
// Source maps?
|
||||
it('Correct sourcemap content for ' + fileName, () => {
|
||||
it("Correct sourcemap content for " + fileName, () => {
|
||||
if (options.sourceMap || options.inlineSourceMap) {
|
||||
Harness.Baseline.runBaseline('Correct sourcemap content for ' + fileName, justName.replace(/\.tsx?$/, '.sourcemap.txt'), () => {
|
||||
Harness.Baseline.runBaseline("Correct sourcemap content for " + fileName, justName.replace(/\.tsx?$/, ".sourcemap.txt"), () => {
|
||||
let record = result.getSourceMapRecord();
|
||||
if (options.noEmitOnError && result.errors.length !== 0 && record === undefined) {
|
||||
// Because of the noEmitOnError option no files are created. We need to return null because baselining isn't required.
|
||||
// Because of the noEmitOnError option no files are created. We need to return null because baselining isn"t required.
|
||||
return null;
|
||||
}
|
||||
return record;
|
||||
@@ -171,35 +171,35 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
}
|
||||
});
|
||||
|
||||
it('Correct JS output for ' + fileName, () => {
|
||||
if (!ts.fileExtensionIs(lastUnit.name, '.d.ts') && this.emit) {
|
||||
it("Correct JS output for " + fileName, () => {
|
||||
if (!ts.fileExtensionIs(lastUnit.name, ".d.ts") && this.emit) {
|
||||
if (result.files.length === 0 && result.errors.length === 0) {
|
||||
throw new Error('Expected at least one js file to be emitted or at least one error to be created.');
|
||||
throw new Error("Expected at least one js file to be emitted or at least one error to be created.");
|
||||
}
|
||||
|
||||
// check js output
|
||||
Harness.Baseline.runBaseline('Correct JS output for ' + fileName, justName.replace(/\.tsx?/, '.js'), () => {
|
||||
let tsCode = '';
|
||||
Harness.Baseline.runBaseline("Correct JS output for " + fileName, justName.replace(/\.tsx?/, ".js"), () => {
|
||||
let tsCode = "";
|
||||
let tsSources = otherFiles.concat(toBeCompiled);
|
||||
if (tsSources.length > 1) {
|
||||
tsCode += '//// [' + fileName + '] ////\r\n\r\n';
|
||||
tsCode += "//// [" + fileName + "] ////\r\n\r\n";
|
||||
}
|
||||
for (let i = 0; i < tsSources.length; i++) {
|
||||
tsCode += '//// [' + Harness.Path.getFileName(tsSources[i].unitName) + ']\r\n';
|
||||
tsCode += tsSources[i].content + (i < (tsSources.length - 1) ? '\r\n' : '');
|
||||
tsCode += "//// [" + Harness.Path.getFileName(tsSources[i].unitName) + "]\r\n";
|
||||
tsCode += tsSources[i].content + (i < (tsSources.length - 1) ? "\r\n" : "");
|
||||
}
|
||||
|
||||
let jsCode = '';
|
||||
let jsCode = "";
|
||||
for (let i = 0; i < result.files.length; i++) {
|
||||
jsCode += '//// [' + Harness.Path.getFileName(result.files[i].fileName) + ']\r\n';
|
||||
jsCode += "//// [" + Harness.Path.getFileName(result.files[i].fileName) + "]\r\n";
|
||||
jsCode += getByteOrderMarkText(result.files[i]);
|
||||
jsCode += result.files[i].code;
|
||||
}
|
||||
|
||||
if (result.declFilesCode.length > 0) {
|
||||
jsCode += '\r\n\r\n';
|
||||
jsCode += "\r\n\r\n";
|
||||
for (let i = 0; i < result.declFilesCode.length; i++) {
|
||||
jsCode += '//// [' + Harness.Path.getFileName(result.declFilesCode[i].fileName) + ']\r\n';
|
||||
jsCode += "//// [" + Harness.Path.getFileName(result.declFilesCode[i].fileName) + "]\r\n";
|
||||
jsCode += getByteOrderMarkText(result.declFilesCode[i]);
|
||||
jsCode += result.declFilesCode[i].code;
|
||||
}
|
||||
@@ -210,13 +210,13 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
}, options);
|
||||
|
||||
if (declFileCompilationResult && declFileCompilationResult.declResult.errors.length) {
|
||||
jsCode += '\r\n\r\n//// [DtsFileErrors]\r\n';
|
||||
jsCode += '\r\n\r\n';
|
||||
jsCode += "\r\n\r\n//// [DtsFileErrors]\r\n";
|
||||
jsCode += "\r\n\r\n";
|
||||
jsCode += getErrorBaseline(declFileCompilationResult.declInputFiles, declFileCompilationResult.declOtherFiles, declFileCompilationResult.declResult);
|
||||
}
|
||||
|
||||
if (jsCode.length > 0) {
|
||||
return tsCode + '\r\n\r\n' + jsCode;
|
||||
return tsCode + "\r\n\r\n" + jsCode;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
@@ -224,28 +224,28 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
}
|
||||
});
|
||||
|
||||
it('Correct Sourcemap output for ' + fileName, () => {
|
||||
it("Correct Sourcemap output for " + fileName, () => {
|
||||
if (options.inlineSourceMap) {
|
||||
if (result.sourceMaps.length > 0) {
|
||||
throw new Error('No sourcemap files should be generated if inlineSourceMaps was set.');
|
||||
throw new Error("No sourcemap files should be generated if inlineSourceMaps was set.");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
else if (options.sourceMap) {
|
||||
if (result.sourceMaps.length !== result.files.length) {
|
||||
throw new Error('Number of sourcemap files should be same as js files.');
|
||||
throw new Error("Number of sourcemap files should be same as js files.");
|
||||
}
|
||||
|
||||
Harness.Baseline.runBaseline('Correct Sourcemap output for ' + fileName, justName.replace(/\.tsx?/, '.js.map'), () => {
|
||||
Harness.Baseline.runBaseline("Correct Sourcemap output for " + fileName, justName.replace(/\.tsx?/, ".js.map"), () => {
|
||||
if (options.noEmitOnError && result.errors.length !== 0 && result.sourceMaps.length === 0) {
|
||||
// We need to return null here or the runBaseLine will actually create a empty file.
|
||||
// Baselining isn't required here because there is no output.
|
||||
return null;
|
||||
}
|
||||
|
||||
let sourceMapCode = '';
|
||||
let sourceMapCode = "";
|
||||
for (let i = 0; i < result.sourceMaps.length; i++) {
|
||||
sourceMapCode += '//// [' + Harness.Path.getFileName(result.sourceMaps[i].fileName) + ']\r\n';
|
||||
sourceMapCode += "//// [" + Harness.Path.getFileName(result.sourceMaps[i].fileName) + "]\r\n";
|
||||
sourceMapCode += getByteOrderMarkText(result.sourceMaps[i]);
|
||||
sourceMapCode += result.sourceMaps[i].code;
|
||||
}
|
||||
@@ -255,7 +255,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
}
|
||||
});
|
||||
|
||||
it('Correct type/symbol baselines for ' + fileName, () => {
|
||||
it("Correct type/symbol baselines for " + fileName, () => {
|
||||
if (fileName.indexOf("APISample") >= 0) {
|
||||
return;
|
||||
}
|
||||
@@ -317,15 +317,15 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
let fullBaseLine = generateBaseLine(fullResults, isSymbolBaseLine);
|
||||
let pullBaseLine = generateBaseLine(pullResults, isSymbolBaseLine);
|
||||
|
||||
let fullExtension = isSymbolBaseLine ? '.symbols' : '.types';
|
||||
let pullExtension = isSymbolBaseLine ? '.symbols.pull' : '.types.pull';
|
||||
let fullExtension = isSymbolBaseLine ? ".symbols" : ".types";
|
||||
let pullExtension = isSymbolBaseLine ? ".symbols.pull" : ".types.pull";
|
||||
|
||||
if (fullBaseLine !== pullBaseLine) {
|
||||
Harness.Baseline.runBaseline('Correct full information for ' + fileName, justName.replace(/\.tsx?/, fullExtension), () => fullBaseLine);
|
||||
Harness.Baseline.runBaseline('Correct pull information for ' + fileName, justName.replace(/\.tsx?/, pullExtension), () => pullBaseLine);
|
||||
Harness.Baseline.runBaseline("Correct full information for " + fileName, justName.replace(/\.tsx?/, fullExtension), () => fullBaseLine);
|
||||
Harness.Baseline.runBaseline("Correct pull information for " + fileName, justName.replace(/\.tsx?/, pullExtension), () => pullBaseLine);
|
||||
}
|
||||
else {
|
||||
Harness.Baseline.runBaseline('Correct information for ' + fileName, justName.replace(/\.tsx?/, fullExtension), () => fullBaseLine);
|
||||
Harness.Baseline.runBaseline("Correct information for " + fileName, justName.replace(/\.tsx?/, fullExtension), () => fullBaseLine);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,7 +334,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
let typeMap: { [fileName: string]: { [lineNum: number]: string[]; } } = {};
|
||||
|
||||
allFiles.forEach(file => {
|
||||
let codeLines = file.content.split('\n');
|
||||
let codeLines = file.content.split("\n");
|
||||
typeWriterResults[file.unitName].forEach(result => {
|
||||
if (isSymbolBaseline && !result.symbol) {
|
||||
return;
|
||||
@@ -354,30 +354,30 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
typeMap[file.unitName][result.line] = typeInfo;
|
||||
});
|
||||
|
||||
typeLines.push('=== ' + file.unitName + ' ===\r\n');
|
||||
typeLines.push("=== " + file.unitName + " ===\r\n");
|
||||
for (let i = 0; i < codeLines.length; i++) {
|
||||
let currentCodeLine = codeLines[i];
|
||||
typeLines.push(currentCodeLine + '\r\n');
|
||||
typeLines.push(currentCodeLine + "\r\n");
|
||||
if (typeMap[file.unitName]) {
|
||||
let typeInfo = typeMap[file.unitName][i];
|
||||
if (typeInfo) {
|
||||
typeInfo.forEach(ty => {
|
||||
typeLines.push('>' + ty + '\r\n');
|
||||
typeLines.push(">" + ty + "\r\n");
|
||||
});
|
||||
if (i + 1 < codeLines.length && (codeLines[i + 1].match(/^\s*[{|}]\s*$/) || codeLines[i + 1].trim() === '')) {
|
||||
if (i + 1 < codeLines.length && (codeLines[i + 1].match(/^\s*[{|}]\s*$/) || codeLines[i + 1].trim() === "")) {
|
||||
}
|
||||
else {
|
||||
typeLines.push('\r\n');
|
||||
typeLines.push("\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
typeLines.push('No type information for this code.');
|
||||
typeLines.push("No type information for this code.");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return typeLines.join('');
|
||||
return typeLines.join("");
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -385,7 +385,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
}
|
||||
|
||||
public initializeTests() {
|
||||
describe(this.testSuiteName + ' tests', () => {
|
||||
describe(this.testSuiteName + " tests", () => {
|
||||
describe("Setup compiler for compiler baselines", () => {
|
||||
let harnessCompiler = Harness.Compiler.getCompiler();
|
||||
this.parseOptions();
|
||||
@@ -416,23 +416,23 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
this.decl = false;
|
||||
this.output = false;
|
||||
|
||||
let opts = this.options.split(',');
|
||||
let opts = this.options.split(",");
|
||||
for (let i = 0; i < opts.length; i++) {
|
||||
switch (opts[i]) {
|
||||
case 'error':
|
||||
case "error":
|
||||
this.errors = true;
|
||||
break;
|
||||
case 'emit':
|
||||
case "emit":
|
||||
this.emit = true;
|
||||
break;
|
||||
case 'decl':
|
||||
case "decl":
|
||||
this.decl = true;
|
||||
break;
|
||||
case 'output':
|
||||
case "output":
|
||||
this.output = true;
|
||||
break;
|
||||
default:
|
||||
throw new Error('unsupported flag');
|
||||
throw new Error("unsupported flag");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+273
-228
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
///<reference path='fourslash.ts' />
|
||||
///<reference path='harness.ts'/>
|
||||
///<reference path='runnerbase.ts' />
|
||||
///<reference path="fourslash.ts" />
|
||||
///<reference path="harness.ts"/>
|
||||
///<reference path="runnerbase.ts" />
|
||||
|
||||
const enum FourSlashTestType {
|
||||
Native,
|
||||
@@ -16,16 +16,16 @@ class FourSlashRunner extends RunnerBase {
|
||||
super();
|
||||
switch (testType) {
|
||||
case FourSlashTestType.Native:
|
||||
this.basePath = 'tests/cases/fourslash';
|
||||
this.testSuiteName = 'fourslash';
|
||||
this.basePath = "tests/cases/fourslash";
|
||||
this.testSuiteName = "fourslash";
|
||||
break;
|
||||
case FourSlashTestType.Shims:
|
||||
this.basePath = 'tests/cases/fourslash/shims';
|
||||
this.testSuiteName = 'fourslash-shims';
|
||||
this.basePath = "tests/cases/fourslash/shims";
|
||||
this.testSuiteName = "fourslash-shims";
|
||||
break;
|
||||
case FourSlashTestType.Server:
|
||||
this.basePath = 'tests/cases/fourslash/server';
|
||||
this.testSuiteName = 'fourslash-server';
|
||||
this.basePath = "tests/cases/fourslash/server";
|
||||
this.testSuiteName = "fourslash-server";
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -35,25 +35,25 @@ class FourSlashRunner extends RunnerBase {
|
||||
this.tests = this.enumerateFiles(this.basePath, /\.ts/i, { recursive: false });
|
||||
}
|
||||
|
||||
describe(this.testSuiteName + ' tests', () => {
|
||||
describe(this.testSuiteName + " tests", () => {
|
||||
this.tests.forEach((fn: string) => {
|
||||
describe(fn, () => {
|
||||
fn = ts.normalizeSlashes(fn);
|
||||
let justName = fn.replace(/^.*[\\\/]/, '');
|
||||
let justName = fn.replace(/^.*[\\\/]/, "");
|
||||
|
||||
// Convert to relative path
|
||||
let testIndex = fn.indexOf('tests/');
|
||||
let testIndex = fn.indexOf("tests/");
|
||||
if (testIndex >= 0) fn = fn.substr(testIndex);
|
||||
|
||||
if (justName && !justName.match(/fourslash\.ts$/i) && !justName.match(/\.d\.ts$/i)) {
|
||||
it(this.testSuiteName + ' test ' + justName + ' runs correctly', () => {
|
||||
it(this.testSuiteName + " test " + justName + " runs correctly", () => {
|
||||
FourSlash.runFourSlashTest(this.basePath, this.testType, fn);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('Generate Tao XML', () => {
|
||||
describe("Generate Tao XML", () => {
|
||||
let invalidReasons: any = {};
|
||||
FourSlash.xmlData.forEach(xml => {
|
||||
if (xml.invalidReason !== null) {
|
||||
@@ -69,37 +69,37 @@ class FourSlashRunner extends RunnerBase {
|
||||
invalidReport.sort((lhs, rhs) => lhs.count > rhs.count ? -1 : lhs.count === rhs.count ? 0 : 1);
|
||||
|
||||
let lines: string[] = [];
|
||||
lines.push('<!-- Blocked Test Report');
|
||||
lines.push("<!-- Blocked Test Report");
|
||||
invalidReport.forEach((reasonAndCount) => {
|
||||
lines.push(reasonAndCount.count + ' tests blocked by ' + reasonAndCount.reason);
|
||||
lines.push(reasonAndCount.count + " tests blocked by " + reasonAndCount.reason);
|
||||
});
|
||||
lines.push('-->');
|
||||
lines.push('<TaoTest xmlns="http://microsoft.com/schemas/VSLanguages/TAO">');
|
||||
lines.push(' <InitTest>');
|
||||
lines.push(' <StartTarget />');
|
||||
lines.push(' </InitTest>');
|
||||
lines.push(' <ScenarioList>');
|
||||
lines.push("-->");
|
||||
lines.push("<TaoTest xmlns=\"http://microsoft.com/schemas/VSLanguages/TAO\">");
|
||||
lines.push(" <InitTest>");
|
||||
lines.push(" <StartTarget />");
|
||||
lines.push(" </InitTest>");
|
||||
lines.push(" <ScenarioList>");
|
||||
FourSlash.xmlData.forEach(xml => {
|
||||
if (xml.invalidReason !== null) {
|
||||
lines.push('<!-- Skipped ' + xml.originalName + ', reason: ' + xml.invalidReason + ' -->');
|
||||
lines.push("<!-- Skipped " + xml.originalName + ", reason: " + xml.invalidReason + " -->");
|
||||
} else {
|
||||
lines.push(' <Scenario Name="' + xml.originalName + '">');
|
||||
lines.push(" <Scenario Name=\"" + xml.originalName + "\">");
|
||||
xml.actions.forEach(action => {
|
||||
lines.push(' ' + action);
|
||||
lines.push(" " + action);
|
||||
});
|
||||
lines.push(' </Scenario>');
|
||||
lines.push(" </Scenario>");
|
||||
}
|
||||
});
|
||||
lines.push(' </ScenarioList>');
|
||||
lines.push(' <CleanupScenario>');
|
||||
lines.push(' <CloseAllDocuments />');
|
||||
lines.push(' <CleanupCreatedFiles />');
|
||||
lines.push(' </CleanupScenario>');
|
||||
lines.push(' <CleanupTest>');
|
||||
lines.push(' <CloseTarget />');
|
||||
lines.push(' </CleanupTest>');
|
||||
lines.push('</TaoTest>');
|
||||
Harness.IO.writeFile('built/local/fourslash.xml', lines.join('\r\n'));
|
||||
lines.push(" </ScenarioList>");
|
||||
lines.push(" <CleanupScenario>");
|
||||
lines.push(" <CloseAllDocuments />");
|
||||
lines.push(" <CleanupCreatedFiles />");
|
||||
lines.push(" </CleanupScenario>");
|
||||
lines.push(" <CleanupTest>");
|
||||
lines.push(" <CloseTarget />");
|
||||
lines.push(" </CleanupTest>");
|
||||
lines.push("</TaoTest>");
|
||||
Harness.IO.writeFile("built/local/fourslash.xml", lines.join("\r\n"));
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -108,6 +108,6 @@ class FourSlashRunner extends RunnerBase {
|
||||
class GeneratedFourslashRunner extends FourSlashRunner {
|
||||
constructor(testType: FourSlashTestType) {
|
||||
super(testType);
|
||||
this.basePath += '/generated/';
|
||||
this.basePath += "/generated/";
|
||||
}
|
||||
}
|
||||
|
||||
+156
-153
@@ -14,24 +14,27 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
/// <reference path='..\services\services.ts' />
|
||||
/// <reference path='..\services\shims.ts' />
|
||||
/// <reference path='..\server\session.ts' />
|
||||
/// <reference path='..\server\client.ts' />
|
||||
/// <reference path='..\server\node.d.ts' />
|
||||
/// <reference path='external\mocha.d.ts'/>
|
||||
/// <reference path='external\chai.d.ts'/>
|
||||
/// <reference path='sourceMapRecorder.ts'/>
|
||||
/// <reference path='runnerbase.ts'/>
|
||||
/// <reference path="..\services\services.ts" />
|
||||
/// <reference path="..\services\shims.ts" />
|
||||
/// <reference path="..\server\session.ts" />
|
||||
/// <reference path="..\server\client.ts" />
|
||||
/// <reference path="..\server\node.d.ts" />
|
||||
/// <reference path="external\mocha.d.ts"/>
|
||||
/// <reference path="external\chai.d.ts"/>
|
||||
/// <reference path="sourceMapRecorder.ts"/>
|
||||
/// <reference path="runnerbase.ts"/>
|
||||
|
||||
var Buffer: BufferConstructor = require('buffer').Buffer;
|
||||
// Block scoped definitions work poorly for global variables, temporarily enable var
|
||||
/* tslint:disable:no-var-keyword */
|
||||
var Buffer: BufferConstructor = require("buffer").Buffer;
|
||||
|
||||
// this will work in the browser via browserify
|
||||
var _chai: typeof chai = require('chai');
|
||||
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);
|
||||
/* tslint:enable:no-var-keyword */
|
||||
|
||||
module Utils {
|
||||
// Setup some globals based on the current environment
|
||||
@@ -63,7 +66,7 @@ module Utils {
|
||||
eval(fileContents);
|
||||
break;
|
||||
case ExecutionEnvironment.Node:
|
||||
let vm = require('vm');
|
||||
let vm = require("vm");
|
||||
if (nodeContext) {
|
||||
vm.runInNewContext(fileContents, nodeContext, fileName);
|
||||
} else {
|
||||
@@ -71,7 +74,7 @@ module Utils {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new Error('Unknown context');
|
||||
throw new Error("Unknown context");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,9 +83,9 @@ module Utils {
|
||||
// Split up the input file by line
|
||||
// Note: IE JS engine incorrectly handles consecutive delimiters here when using RegExp split, so
|
||||
// we have to use string-based splitting instead and try to figure out the delimiting chars
|
||||
let lines = content.split('\r\n');
|
||||
let lines = content.split("\r\n");
|
||||
if (lines.length === 1) {
|
||||
lines = content.split('\n');
|
||||
lines = content.split("\n");
|
||||
|
||||
if (lines.length === 1) {
|
||||
lines = content.split("\r");
|
||||
@@ -93,7 +96,7 @@ module Utils {
|
||||
|
||||
/** Reads a file under /tests */
|
||||
export function readTestFile(path: string) {
|
||||
if (path.indexOf('tests') < 0) {
|
||||
if (path.indexOf("tests") < 0) {
|
||||
path = "tests/" + path;
|
||||
}
|
||||
|
||||
@@ -388,7 +391,7 @@ module Utils {
|
||||
|
||||
module Harness.Path {
|
||||
export function getFileName(fullPath: string) {
|
||||
return fullPath.replace(/^.*[\\\/]/, '');
|
||||
return fullPath.replace(/^.*[\\\/]/, "");
|
||||
}
|
||||
|
||||
export function filePath(fullPath: string) {
|
||||
@@ -412,6 +415,7 @@ module Harness {
|
||||
log(text: string): void;
|
||||
getMemoryUsage?(): number;
|
||||
}
|
||||
export var IO: IO;
|
||||
|
||||
module IOImpl {
|
||||
declare class Enumerator {
|
||||
@@ -484,8 +488,8 @@ module Harness {
|
||||
declare let require: any;
|
||||
let fs: any, pathModule: any;
|
||||
if (require) {
|
||||
fs = require('fs');
|
||||
pathModule = require('path');
|
||||
fs = require("fs");
|
||||
pathModule = require("path");
|
||||
} else {
|
||||
fs = pathModule = {};
|
||||
}
|
||||
@@ -559,8 +563,8 @@ module Harness {
|
||||
let serverRoot = "http://localhost:8888/";
|
||||
|
||||
// Unused?
|
||||
let newLine = '\r\n';
|
||||
let currentDirectory = () => '';
|
||||
let newLine = "\r\n";
|
||||
let currentDirectory = () => "";
|
||||
let supportsCodePage = () => false;
|
||||
|
||||
module Http {
|
||||
@@ -606,9 +610,9 @@ module Harness {
|
||||
export function writeToServerSync(url: string, action: string, contents?: string): XHRResponse {
|
||||
let xhr = new XMLHttpRequest();
|
||||
try {
|
||||
let actionMsg = '?action=' + action;
|
||||
xhr.open('POST', url + actionMsg, false);
|
||||
xhr.setRequestHeader('Access-Control-Allow-Origin', '*');
|
||||
let actionMsg = "?action=" + action;
|
||||
xhr.open("POST", url + actionMsg, false);
|
||||
xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
|
||||
xhr.send(contents);
|
||||
}
|
||||
catch (e) {
|
||||
@@ -624,7 +628,7 @@ module Harness {
|
||||
}
|
||||
|
||||
export function deleteFile(path: string) {
|
||||
Http.writeToServerSync(serverRoot + path, 'DELETE', null);
|
||||
Http.writeToServerSync(serverRoot + path, "DELETE", null);
|
||||
}
|
||||
|
||||
export function directoryExists(path: string): boolean {
|
||||
@@ -637,15 +641,15 @@ module Harness {
|
||||
if (dirPath.match(/localhost:\d+$/) || dirPath.match(/localhost:\d+\/$/)) {
|
||||
dirPath = null;
|
||||
// path + fileName
|
||||
} else if (dirPath.indexOf('.') === -1) {
|
||||
dirPath = dirPath.substring(0, dirPath.lastIndexOf('/'));
|
||||
} else if (dirPath.indexOf(".") === -1) {
|
||||
dirPath = dirPath.substring(0, dirPath.lastIndexOf("/"));
|
||||
// path
|
||||
} else {
|
||||
// strip any trailing slash
|
||||
if (dirPath.match(/.*\/$/)) {
|
||||
dirPath = dirPath.substring(0, dirPath.length - 2);
|
||||
}
|
||||
dirPath = dirPath.substring(0, dirPath.lastIndexOf('/'));
|
||||
dirPath = dirPath.substring(0, dirPath.lastIndexOf("/"));
|
||||
}
|
||||
|
||||
return dirPath;
|
||||
@@ -660,7 +664,7 @@ module Harness {
|
||||
export function _listFilesImpl(path: string, spec?: RegExp, options?: any) {
|
||||
let response = Http.getFileFromServerSync(serverRoot + path);
|
||||
if (response.status === 200) {
|
||||
let results = response.responseText.split(',');
|
||||
let results = response.responseText.split(",");
|
||||
if (spec) {
|
||||
return results.filter(file => spec.test(file));
|
||||
} else {
|
||||
@@ -668,7 +672,7 @@ module Harness {
|
||||
}
|
||||
}
|
||||
else {
|
||||
return [''];
|
||||
return [""];
|
||||
}
|
||||
};
|
||||
export let listFiles = Utils.memoize(_listFilesImpl);
|
||||
@@ -685,12 +689,11 @@ module Harness {
|
||||
}
|
||||
|
||||
export function writeFile(path: string, contents: string) {
|
||||
Http.writeToServerSync(serverRoot + path, 'WRITE', contents);
|
||||
Http.writeToServerSync(serverRoot + path, "WRITE", contents);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export var IO: IO;
|
||||
switch (Utils.getExecutionEnvironment()) {
|
||||
case Utils.ExecutionEnvironment.CScript:
|
||||
IO = IOImpl.CScript;
|
||||
@@ -722,7 +725,7 @@ module Harness {
|
||||
tcServicesFileName = "built/local/typescriptServices.js";
|
||||
break;
|
||||
default:
|
||||
throw new Error('Unknown context');
|
||||
throw new Error("Unknown context");
|
||||
}
|
||||
export let tcServicesFile = IO.readFile(tcServicesFileName);
|
||||
|
||||
@@ -745,12 +748,12 @@ module Harness {
|
||||
|
||||
public Write(str: string) {
|
||||
// out of memory usage concerns avoid using + or += if we're going to do any manipulation of this string later
|
||||
this.currentLine = [(this.currentLine || ''), str].join('');
|
||||
this.currentLine = [(this.currentLine || ""), str].join("");
|
||||
}
|
||||
|
||||
public WriteLine(str: string) {
|
||||
// out of memory usage concerns avoid using + or += if we're going to do any manipulation of this string later
|
||||
this.lines.push([(this.currentLine || ''), str].join(''));
|
||||
this.lines.push([(this.currentLine || ""), str].join(""));
|
||||
this.currentLine = undefined;
|
||||
}
|
||||
|
||||
@@ -799,7 +802,7 @@ module Harness {
|
||||
if (this.fileCollection.hasOwnProperty(p)) {
|
||||
let current = <Harness.Compiler.WriterAggregator>this.fileCollection[p];
|
||||
if (current.lines.length > 0) {
|
||||
if (p.indexOf('.d.ts') !== -1) { current.lines.unshift(['////[', Path.getFileName(p), ']'].join('')); }
|
||||
if (p.indexOf(".d.ts") !== -1) { current.lines.unshift(["////[", Path.getFileName(p), "]"].join("")); }
|
||||
result.push({ fileName: p, file: this.fileCollection[p] });
|
||||
}
|
||||
}
|
||||
@@ -828,12 +831,12 @@ module Harness {
|
||||
const carriageReturnLineFeed = "\r\n";
|
||||
const lineFeed = "\n";
|
||||
|
||||
export let defaultLibFileName = 'lib.d.ts';
|
||||
export let defaultLibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + 'lib.core.d.ts'), /*languageVersion*/ ts.ScriptTarget.Latest);
|
||||
export let defaultES6LibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + 'lib.core.es6.d.ts'), /*languageVersion*/ ts.ScriptTarget.Latest);
|
||||
export let defaultLibFileName = "lib.d.ts";
|
||||
export let defaultLibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + "lib.core.d.ts"), /*languageVersion*/ ts.ScriptTarget.Latest);
|
||||
export let defaultES6LibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + "lib.core.es6.d.ts"), /*languageVersion*/ ts.ScriptTarget.Latest);
|
||||
|
||||
// Cache these between executions so we don't have to re-parse them for every test
|
||||
export let fourslashFileName = 'fourslash.ts';
|
||||
export let fourslashFileName = "fourslash.ts";
|
||||
export let fourslashSourceFile: ts.SourceFile;
|
||||
|
||||
export function getCanonicalFileName(fileName: string): string {
|
||||
@@ -883,7 +886,7 @@ module Harness {
|
||||
return Object.prototype.hasOwnProperty.call(filemap, getCanonicalFileName(canonicalAbsolutePath)) ? filemap[canonicalAbsolutePath] : undefined;
|
||||
}
|
||||
else if (fn === fourslashFileName) {
|
||||
let tsFn = 'tests/cases/fourslash/' + fourslashFileName;
|
||||
let tsFn = "tests/cases/fourslash/" + fourslashFileName;
|
||||
fourslashSourceFile = fourslashSourceFile || createSourceFileAndAssertInvariants(tsFn, Harness.IO.readFile(tsFn), scriptTarget);
|
||||
return fourslashSourceFile;
|
||||
}
|
||||
@@ -974,7 +977,7 @@ module Harness {
|
||||
settingsCallback(null);
|
||||
}
|
||||
|
||||
let newLine = '\r\n';
|
||||
let newLine = "\r\n";
|
||||
options.skipDefaultLibCheck = true;
|
||||
|
||||
// Files from built\local that are requested by test "@includeBuiltFiles" to be in the context.
|
||||
@@ -1011,19 +1014,19 @@ module Harness {
|
||||
// "fileName", "comments", "declaration", "module", "nolib", "sourcemap", "target", "out", "outdir", "noimplicitany", "noresolve"
|
||||
case "module":
|
||||
case "modulegentarget":
|
||||
if (typeof setting.value === 'string') {
|
||||
if (setting.value.toLowerCase() === 'amd') {
|
||||
if (typeof setting.value === "string") {
|
||||
if (setting.value.toLowerCase() === "amd") {
|
||||
options.module = ts.ModuleKind.AMD;
|
||||
} else if (setting.value.toLowerCase() === 'umd') {
|
||||
} else if (setting.value.toLowerCase() === "umd") {
|
||||
options.module = ts.ModuleKind.UMD;
|
||||
} else if (setting.value.toLowerCase() === 'commonjs') {
|
||||
} else if (setting.value.toLowerCase() === "commonjs") {
|
||||
options.module = ts.ModuleKind.CommonJS;
|
||||
} else if (setting.value.toLowerCase() === 'system') {
|
||||
} else if (setting.value.toLowerCase() === "system") {
|
||||
options.module = ts.ModuleKind.System;
|
||||
} else if (setting.value.toLowerCase() === 'unspecified') {
|
||||
} else if (setting.value.toLowerCase() === "unspecified") {
|
||||
options.module = ts.ModuleKind.None;
|
||||
} else {
|
||||
throw new Error('Unknown module type ' + setting.value);
|
||||
throw new Error("Unknown module type " + setting.value);
|
||||
}
|
||||
} else {
|
||||
options.module = <any>setting.value;
|
||||
@@ -1031,152 +1034,152 @@ module Harness {
|
||||
break;
|
||||
|
||||
case "target":
|
||||
case 'codegentarget':
|
||||
if (typeof setting.value === 'string') {
|
||||
if (setting.value.toLowerCase() === 'es3') {
|
||||
case "codegentarget":
|
||||
if (typeof setting.value === "string") {
|
||||
if (setting.value.toLowerCase() === "es3") {
|
||||
options.target = ts.ScriptTarget.ES3;
|
||||
} else if (setting.value.toLowerCase() === 'es5') {
|
||||
} else if (setting.value.toLowerCase() === "es5") {
|
||||
options.target = ts.ScriptTarget.ES5;
|
||||
} else if (setting.value.toLowerCase() === 'es6') {
|
||||
} else if (setting.value.toLowerCase() === "es6") {
|
||||
options.target = ts.ScriptTarget.ES6;
|
||||
} else {
|
||||
throw new Error('Unknown compile target ' + setting.value);
|
||||
throw new Error("Unknown compile target " + setting.value);
|
||||
}
|
||||
} else {
|
||||
options.target = <any>setting.value;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'experimentaldecorators':
|
||||
options.experimentalDecorators = setting.value === 'true';
|
||||
case "experimentaldecorators":
|
||||
options.experimentalDecorators = setting.value === "true";
|
||||
break;
|
||||
|
||||
case 'emitdecoratormetadata':
|
||||
options.emitDecoratorMetadata = setting.value === 'true';
|
||||
case "emitdecoratormetadata":
|
||||
options.emitDecoratorMetadata = setting.value === "true";
|
||||
break;
|
||||
|
||||
case 'experimentalasyncfunctions':
|
||||
options.experimentalAsyncFunctions = setting.value === 'true';
|
||||
case "experimentalasyncfunctions":
|
||||
options.experimentalAsyncFunctions = setting.value === "true";
|
||||
break;
|
||||
|
||||
case 'noemithelpers':
|
||||
options.noEmitHelpers = setting.value === 'true';
|
||||
case "noemithelpers":
|
||||
options.noEmitHelpers = setting.value === "true";
|
||||
break;
|
||||
|
||||
case 'noemitonerror':
|
||||
options.noEmitOnError = setting.value === 'true';
|
||||
case "noemitonerror":
|
||||
options.noEmitOnError = setting.value === "true";
|
||||
break;
|
||||
|
||||
case 'noresolve':
|
||||
options.noResolve = setting.value === 'true';
|
||||
case "noresolve":
|
||||
options.noResolve = setting.value === "true";
|
||||
break;
|
||||
|
||||
case 'noimplicitany':
|
||||
options.noImplicitAny = setting.value === 'true';
|
||||
case "noimplicitany":
|
||||
options.noImplicitAny = setting.value === "true";
|
||||
break;
|
||||
|
||||
case 'nolib':
|
||||
options.noLib = setting.value === 'true';
|
||||
case "nolib":
|
||||
options.noLib = setting.value === "true";
|
||||
break;
|
||||
|
||||
case 'out':
|
||||
case 'outfileoption':
|
||||
case "out":
|
||||
case "outfileoption":
|
||||
options.out = setting.value;
|
||||
break;
|
||||
|
||||
case 'outdiroption':
|
||||
case 'outdir':
|
||||
case "outdiroption":
|
||||
case "outdir":
|
||||
options.outDir = setting.value;
|
||||
break;
|
||||
|
||||
case 'skipdefaultlibcheck':
|
||||
case "skipdefaultlibcheck":
|
||||
options.skipDefaultLibCheck = setting.value === "true";
|
||||
break;
|
||||
|
||||
case 'sourceroot':
|
||||
case "sourceroot":
|
||||
options.sourceRoot = setting.value;
|
||||
break;
|
||||
|
||||
case 'maproot':
|
||||
case "maproot":
|
||||
options.mapRoot = setting.value;
|
||||
break;
|
||||
|
||||
case 'sourcemap':
|
||||
options.sourceMap = setting.value === 'true';
|
||||
case "sourcemap":
|
||||
options.sourceMap = setting.value === "true";
|
||||
break;
|
||||
|
||||
case 'declaration':
|
||||
options.declaration = setting.value === 'true';
|
||||
case "declaration":
|
||||
options.declaration = setting.value === "true";
|
||||
break;
|
||||
|
||||
case 'newline':
|
||||
if (setting.value.toLowerCase() === 'crlf') {
|
||||
case "newline":
|
||||
if (setting.value.toLowerCase() === "crlf") {
|
||||
options.newLine = ts.NewLineKind.CarriageReturnLineFeed;
|
||||
}
|
||||
else if (setting.value.toLowerCase() === 'lf') {
|
||||
else if (setting.value.toLowerCase() === "lf") {
|
||||
options.newLine = ts.NewLineKind.LineFeed;
|
||||
}
|
||||
else {
|
||||
throw new Error('Unknown option for newLine: ' + setting.value);
|
||||
throw new Error("Unknown option for newLine: " + setting.value);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'comments':
|
||||
options.removeComments = setting.value === 'false';
|
||||
case "comments":
|
||||
options.removeComments = setting.value === "false";
|
||||
break;
|
||||
|
||||
case 'stripinternal':
|
||||
options.stripInternal = setting.value === 'true';
|
||||
case "stripinternal":
|
||||
options.stripInternal = setting.value === "true";
|
||||
|
||||
case 'usecasesensitivefilenames':
|
||||
useCaseSensitiveFileNames = setting.value === 'true';
|
||||
case "usecasesensitivefilenames":
|
||||
useCaseSensitiveFileNames = setting.value === "true";
|
||||
break;
|
||||
|
||||
case 'filename':
|
||||
case "filename":
|
||||
// Not supported yet
|
||||
break;
|
||||
|
||||
case 'emitbom':
|
||||
options.emitBOM = setting.value === 'true';
|
||||
case "emitbom":
|
||||
options.emitBOM = setting.value === "true";
|
||||
break;
|
||||
|
||||
case 'errortruncation':
|
||||
options.noErrorTruncation = setting.value === 'false';
|
||||
case "errortruncation":
|
||||
options.noErrorTruncation = setting.value === "false";
|
||||
break;
|
||||
|
||||
case 'preserveconstenums':
|
||||
options.preserveConstEnums = setting.value === 'true';
|
||||
case "preserveconstenums":
|
||||
options.preserveConstEnums = setting.value === "true";
|
||||
break;
|
||||
|
||||
case 'isolatedmodules':
|
||||
options.isolatedModules = setting.value === 'true';
|
||||
case "isolatedmodules":
|
||||
options.isolatedModules = setting.value === "true";
|
||||
break;
|
||||
|
||||
case 'suppressimplicitanyindexerrors':
|
||||
options.suppressImplicitAnyIndexErrors = setting.value === 'true';
|
||||
case "suppressimplicitanyindexerrors":
|
||||
options.suppressImplicitAnyIndexErrors = setting.value === "true";
|
||||
break;
|
||||
|
||||
case 'includebuiltfile':
|
||||
case "includebuiltfile":
|
||||
let builtFileName = libFolder + setting.value;
|
||||
includeBuiltFiles.push({ unitName: builtFileName, content: normalizeLineEndings(IO.readFile(builtFileName), newLine) });
|
||||
break;
|
||||
|
||||
case 'inlinesourcemap':
|
||||
options.inlineSourceMap = setting.value === 'true';
|
||||
case "inlinesourcemap":
|
||||
options.inlineSourceMap = setting.value === "true";
|
||||
break;
|
||||
|
||||
case 'inlinesources':
|
||||
options.inlineSources = setting.value === 'true';
|
||||
case "inlinesources":
|
||||
options.inlineSources = setting.value === "true";
|
||||
break;
|
||||
|
||||
case 'jsx':
|
||||
options.jsx = setting.value.toLowerCase() === 'react' ? ts.JsxEmit.React :
|
||||
setting.value.toLowerCase() === 'preserve' ? ts.JsxEmit.Preserve :
|
||||
case "jsx":
|
||||
options.jsx = setting.value.toLowerCase() === "react" ? ts.JsxEmit.React :
|
||||
setting.value.toLowerCase() === "preserve" ? ts.JsxEmit.Preserve :
|
||||
ts.JsxEmit.None;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error('Unsupported compiler setting ' + setting.flag);
|
||||
throw new Error("Unsupported compiler setting " + setting.flag);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1189,7 +1192,7 @@ module Harness {
|
||||
// Current directory is needed for rwcRunner to be able to use currentDirectory defined in json file
|
||||
currentDirectory?: string) {
|
||||
if (options.declaration && result.errors.length === 0 && result.declFilesCode.length !== result.files.length) {
|
||||
throw new Error('There were no errors and declFiles generated did not match number of js files generated');
|
||||
throw new Error("There were no errors and declFiles generated did not match number of js files generated");
|
||||
}
|
||||
|
||||
let declInputFiles: { unitName: string; content: string }[] = [];
|
||||
@@ -1250,8 +1253,8 @@ module Harness {
|
||||
}
|
||||
|
||||
function normalizeLineEndings(text: string, lineEnding: string): string {
|
||||
let normalized = text.replace(/\r\n?/g, '\n');
|
||||
if (lineEnding !== '\n') {
|
||||
let normalized = text.replace(/\r\n?/g, "\n");
|
||||
if (lineEnding !== "\n") {
|
||||
normalized = normalized.replace(/\n/g, lineEnding);
|
||||
}
|
||||
return normalized;
|
||||
@@ -1282,10 +1285,10 @@ module Harness {
|
||||
let message = ts.flattenDiagnosticMessageText(error.messageText, ts.sys.newLine);
|
||||
|
||||
let errLines = RunnerBase.removeFullPaths(message)
|
||||
.split('\n')
|
||||
.map(s => s.length > 0 && s.charAt(s.length - 1) === '\r' ? s.substr(0, s.length - 1) : s)
|
||||
.split("\n")
|
||||
.map(s => s.length > 0 && s.charAt(s.length - 1) === "\r" ? s.substr(0, s.length - 1) : s)
|
||||
.filter(s => s.length > 0)
|
||||
.map(s => '!!! ' + ts.DiagnosticCategory[error.category].toLowerCase() + " TS" + error.code + ": " + s);
|
||||
.map(s => "!!! " + ts.DiagnosticCategory[error.category].toLowerCase() + " TS" + error.code + ": " + s);
|
||||
errLines.forEach(e => outputLines.push(e));
|
||||
|
||||
totalErrorsReported++;
|
||||
@@ -1305,7 +1308,7 @@ module Harness {
|
||||
|
||||
|
||||
// Header
|
||||
outputLines.push('==== ' + inputFile.unitName + ' (' + fileErrors.length + ' errors) ====');
|
||||
outputLines.push("==== " + inputFile.unitName + " (" + fileErrors.length + " errors) ====");
|
||||
|
||||
// Make sure we emit something for every error
|
||||
let markedErrorCount = 0;
|
||||
@@ -1314,13 +1317,13 @@ module Harness {
|
||||
// we have to string-based splitting instead and try to figure out the delimiting chars
|
||||
|
||||
let lineStarts = ts.computeLineStarts(inputFile.content);
|
||||
let lines = inputFile.content.split('\n');
|
||||
let lines = inputFile.content.split("\n");
|
||||
if (lines.length === 1) {
|
||||
lines = lines[0].split("\r");
|
||||
}
|
||||
|
||||
lines.forEach((line, lineIndex) => {
|
||||
if (line.length > 0 && line.charAt(line.length - 1) === '\r') {
|
||||
if (line.length > 0 && line.charAt(line.length - 1) === "\r") {
|
||||
line = line.substr(0, line.length - 1);
|
||||
}
|
||||
|
||||
@@ -1333,7 +1336,7 @@ module Harness {
|
||||
nextLineStart = lineStarts[lineIndex + 1];
|
||||
}
|
||||
// Emit this line from the original file
|
||||
outputLines.push(' ' + line);
|
||||
outputLines.push(" " + line);
|
||||
fileErrors.forEach(err => {
|
||||
// Does any error start or continue on to this line? Emit squiggles
|
||||
let end = ts.textSpanEnd(err);
|
||||
@@ -1345,7 +1348,7 @@ module Harness {
|
||||
// Calculate the start of the squiggle
|
||||
let squiggleStart = Math.max(0, relativeOffset);
|
||||
// TODO/REVIEW: this doesn't work quite right in the browser if a multi file test has files whose names are just the right length relative to one another
|
||||
outputLines.push(' ' + line.substr(0, squiggleStart).replace(/[^\s]/g, ' ') + new Array(Math.min(length, line.length - squiggleStart) + 1).join('~'));
|
||||
outputLines.push(" " + line.substr(0, squiggleStart).replace(/[^\s]/g, " ") + new Array(Math.min(length, line.length - squiggleStart) + 1).join("~"));
|
||||
|
||||
// If the error ended here, or we're at the end of the file, emit its message
|
||||
if ((lineIndex === lines.length - 1) || nextLineStart > end) {
|
||||
@@ -1360,7 +1363,7 @@ module Harness {
|
||||
});
|
||||
|
||||
// Verify we didn't miss any errors in this file
|
||||
assert.equal(markedErrorCount, fileErrors.length, 'count of errors in ' + inputFile.unitName);
|
||||
assert.equal(markedErrorCount, fileErrors.length, "count of errors in " + inputFile.unitName);
|
||||
});
|
||||
|
||||
let numLibraryDiagnostics = ts.countWhere(diagnostics, diagnostic => {
|
||||
@@ -1373,10 +1376,10 @@ module Harness {
|
||||
});
|
||||
|
||||
// Verify we didn't miss any errors in total
|
||||
assert.equal(totalErrorsReported + numLibraryDiagnostics + numTest262HarnessDiagnostics, diagnostics.length, 'total number of errors');
|
||||
assert.equal(totalErrorsReported + numLibraryDiagnostics + numTest262HarnessDiagnostics, diagnostics.length, "total number of errors");
|
||||
|
||||
return minimalDiagnosticsToString(diagnostics) +
|
||||
ts.sys.newLine + ts.sys.newLine + outputLines.join('\r\n');
|
||||
ts.sys.newLine + ts.sys.newLine + outputLines.join("\r\n");
|
||||
}
|
||||
|
||||
export function collateOutputs(outputFiles: Harness.Compiler.GeneratedFile[]): string {
|
||||
@@ -1384,15 +1387,15 @@ module Harness {
|
||||
outputFiles.sort((a, b) => cleanName(a.fileName).localeCompare(cleanName(b.fileName)));
|
||||
|
||||
// Emit them
|
||||
let result = '';
|
||||
let result = "";
|
||||
for (let outputFile of outputFiles) {
|
||||
// Some extra spacing if this isn't the first file
|
||||
if (result.length) {
|
||||
result += '\r\n\r\n';
|
||||
result += "\r\n\r\n";
|
||||
}
|
||||
|
||||
// FileName header + content
|
||||
result += '/*====== ' + outputFile.fileName + ' ======*/\r\n';
|
||||
result += "/*====== " + outputFile.fileName + " ======*/\r\n";
|
||||
|
||||
result += outputFile.code;
|
||||
}
|
||||
@@ -1400,7 +1403,7 @@ module Harness {
|
||||
return result;
|
||||
|
||||
function cleanName(fn: string) {
|
||||
let lastSlash = ts.normalizeSlashes(fn).lastIndexOf('/');
|
||||
let lastSlash = ts.normalizeSlashes(fn).lastIndexOf("/");
|
||||
return fn.substr(lastSlash + 1).toLowerCase();
|
||||
}
|
||||
}
|
||||
@@ -1418,7 +1421,7 @@ module Harness {
|
||||
// This does not need to exist strictly speaking, but many tests will need to be updated if it's removed
|
||||
export function compileString(code: string, unitName: string, callback: (result: CompilerResult) => void) {
|
||||
// NEWTODO: Re-implement 'compileString'
|
||||
throw new Error('compileString NYI');
|
||||
throw new Error("compileString NYI");
|
||||
}
|
||||
|
||||
export interface GeneratedFile {
|
||||
@@ -1432,26 +1435,26 @@ module Harness {
|
||||
}
|
||||
|
||||
export function isTS(fileName: string) {
|
||||
return stringEndsWith(fileName, '.ts');
|
||||
return stringEndsWith(fileName, ".ts");
|
||||
}
|
||||
|
||||
export function isTSX(fileName: string) {
|
||||
return stringEndsWith(fileName, '.tsx');
|
||||
return stringEndsWith(fileName, ".tsx");
|
||||
}
|
||||
|
||||
export function isDTS(fileName: string) {
|
||||
return stringEndsWith(fileName, '.d.ts');
|
||||
return stringEndsWith(fileName, ".d.ts");
|
||||
}
|
||||
|
||||
export function isJS(fileName: string) {
|
||||
return stringEndsWith(fileName, '.js');
|
||||
return stringEndsWith(fileName, ".js");
|
||||
}
|
||||
export function isJSX(fileName: string) {
|
||||
return stringEndsWith(fileName, '.jsx');
|
||||
return stringEndsWith(fileName, ".jsx");
|
||||
}
|
||||
|
||||
export function isJSMap(fileName: string) {
|
||||
return stringEndsWith(fileName, '.js.map') || stringEndsWith(fileName, '.jsx.map');
|
||||
return stringEndsWith(fileName, ".js.map") || stringEndsWith(fileName, ".jsx.map");
|
||||
}
|
||||
|
||||
/** Contains the code and errors of a compilation and some helper methods to check its status. */
|
||||
@@ -1478,7 +1481,7 @@ module Harness {
|
||||
this.sourceMaps.push(emittedFile);
|
||||
}
|
||||
else {
|
||||
throw new Error('Unrecognized file extension for file ' + emittedFile.fileName);
|
||||
throw new Error("Unrecognized file extension for file " + emittedFile.fileName);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1587,10 +1590,10 @@ module Harness {
|
||||
// Subfile content line
|
||||
// Append to the current subfile content, inserting a newline needed
|
||||
if (currentFileContent === null) {
|
||||
currentFileContent = '';
|
||||
currentFileContent = "";
|
||||
} else {
|
||||
// End-of-line
|
||||
currentFileContent = currentFileContent + '\n';
|
||||
currentFileContent = currentFileContent + "\n";
|
||||
}
|
||||
currentFileContent = currentFileContent + line;
|
||||
}
|
||||
@@ -1601,7 +1604,7 @@ module Harness {
|
||||
|
||||
// EOF, push whatever remains
|
||||
let newTestFile2 = {
|
||||
content: currentFileContent || '',
|
||||
content: currentFileContent || "",
|
||||
name: currentFileName,
|
||||
fileOptions: currentFileOptions,
|
||||
originalFilePath: fileName,
|
||||
@@ -1623,27 +1626,27 @@ module Harness {
|
||||
|
||||
export function localPath(fileName: string, baselineFolder?: string, subfolder?: string) {
|
||||
if (baselineFolder === undefined) {
|
||||
return baselinePath(fileName, 'local', 'tests/baselines', subfolder);
|
||||
return baselinePath(fileName, "local", "tests/baselines", subfolder);
|
||||
}
|
||||
else {
|
||||
return baselinePath(fileName, 'local', baselineFolder, subfolder);
|
||||
return baselinePath(fileName, "local", baselineFolder, subfolder);
|
||||
}
|
||||
}
|
||||
|
||||
function referencePath(fileName: string, baselineFolder?: string, subfolder?: string) {
|
||||
if (baselineFolder === undefined) {
|
||||
return baselinePath(fileName, 'reference', 'tests/baselines', subfolder);
|
||||
return baselinePath(fileName, "reference", "tests/baselines", subfolder);
|
||||
}
|
||||
else {
|
||||
return baselinePath(fileName, 'reference', baselineFolder, subfolder);
|
||||
return baselinePath(fileName, "reference", baselineFolder, subfolder);
|
||||
}
|
||||
}
|
||||
|
||||
function baselinePath(fileName: string, type: string, baselineFolder: string, subfolder?: string) {
|
||||
if (subfolder !== undefined) {
|
||||
return Harness.userSpecifiedRoot + baselineFolder + '/' + subfolder + '/' + type + '/' + fileName;
|
||||
return Harness.userSpecifiedRoot + baselineFolder + "/" + subfolder + "/" + type + "/" + fileName;
|
||||
} else {
|
||||
return Harness.userSpecifiedRoot + baselineFolder + '/' + type + '/' + fileName;
|
||||
return Harness.userSpecifiedRoot + baselineFolder + "/" + type + "/" + fileName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1677,7 +1680,7 @@ module Harness {
|
||||
let actual = generateContent();
|
||||
|
||||
if (actual === undefined) {
|
||||
throw new Error('The generated content was "undefined". Return "null" if no baselining is required."');
|
||||
throw new Error("The generated content was \"undefined\". Return \"null\" if no baselining is required.\"");
|
||||
}
|
||||
|
||||
// Store the content in the 'local' folder so we
|
||||
@@ -1700,10 +1703,10 @@ module Harness {
|
||||
let refFileName = referencePath(relativeFileName, opts && opts.Baselinefolder, opts && opts.Subfolder);
|
||||
|
||||
if (actual === null) {
|
||||
actual = '<no content>';
|
||||
actual = "<no content>";
|
||||
}
|
||||
|
||||
let expected = '<no content>';
|
||||
let expected = "<no content>";
|
||||
if (IO.fileExists(refFileName)) {
|
||||
expected = IO.readFile(refFileName);
|
||||
}
|
||||
@@ -1712,10 +1715,10 @@ module Harness {
|
||||
}
|
||||
|
||||
function writeComparison(expected: string, actual: string, relativeFileName: string, actualFileName: string, descriptionForDescribe: string) {
|
||||
let encoded_actual = (new Buffer(actual)).toString('utf8');
|
||||
let encoded_actual = (new Buffer(actual)).toString("utf8");
|
||||
if (expected != encoded_actual) {
|
||||
// Overwrite & issue error
|
||||
let errMsg = 'The baseline file ' + relativeFileName + ' has changed';
|
||||
let errMsg = "The baseline file " + relativeFileName + " has changed";
|
||||
throw new Error(errMsg);
|
||||
}
|
||||
}
|
||||
@@ -1744,7 +1747,7 @@ module Harness {
|
||||
}
|
||||
|
||||
export function isLibraryFile(filePath: string): boolean {
|
||||
return (Path.getFileName(filePath) === 'lib.d.ts') || (Path.getFileName(filePath) === 'lib.core.d.ts');
|
||||
return (Path.getFileName(filePath) === "lib.d.ts") || (Path.getFileName(filePath) === "lib.core.d.ts");
|
||||
}
|
||||
|
||||
export function isBuiltFile(filePath: string): boolean {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/// <reference path='..\services\services.ts' />
|
||||
/// <reference path='..\services\shims.ts' />
|
||||
/// <reference path='..\server\client.ts' />
|
||||
/// <reference path='harness.ts' />
|
||||
/// <reference path="..\services\services.ts" />
|
||||
/// <reference path="..\services\shims.ts" />
|
||||
/// <reference path="..\server\client.ts" />
|
||||
/// <reference path="harness.ts" />
|
||||
|
||||
module Harness.LanguageService {
|
||||
export class ScriptInfo {
|
||||
@@ -242,7 +242,7 @@ module Harness.LanguageService {
|
||||
throw new Error("NYI");
|
||||
}
|
||||
getClassificationsForLine(text: string, lexState: ts.EndOfLineState, classifyKeywordsInGenerics?: boolean): ts.ClassificationResult {
|
||||
let result = this.shim.getClassificationsForLine(text, lexState, classifyKeywordsInGenerics).split('\n');
|
||||
let result = this.shim.getClassificationsForLine(text, lexState, classifyKeywordsInGenerics).split("\n");
|
||||
let entries: ts.ClassificationInfo[] = [];
|
||||
let i = 0;
|
||||
let position = 0;
|
||||
|
||||
+11
-11
@@ -73,7 +73,7 @@ interface PlaybackControl {
|
||||
module Playback {
|
||||
let recordLog: IOLog = undefined;
|
||||
let replayLog: IOLog = undefined;
|
||||
let recordLogFileNameBase = '';
|
||||
let recordLogFileNameBase = "";
|
||||
|
||||
interface Memoized<T> {
|
||||
(s: string): T;
|
||||
@@ -99,7 +99,7 @@ module Playback {
|
||||
return {
|
||||
timestamp: (new Date()).toString(),
|
||||
arguments: [],
|
||||
currentDirectory: '',
|
||||
currentDirectory: "",
|
||||
filesRead: [],
|
||||
filesWritten: [],
|
||||
filesDeleted: [],
|
||||
@@ -110,7 +110,7 @@ module Playback {
|
||||
dirExists: [],
|
||||
dirsCreated: [],
|
||||
pathsResolved: [],
|
||||
executingPath: ''
|
||||
executingPath: ""
|
||||
};
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ module Playback {
|
||||
if (defaultValue !== undefined) {
|
||||
return defaultValue;
|
||||
} else {
|
||||
throw new Error('No matching result in log array for: ' + JSON.stringify(expectedFields));
|
||||
throw new Error("No matching result in log array for: " + JSON.stringify(expectedFields));
|
||||
}
|
||||
}
|
||||
return results[0].result;
|
||||
@@ -195,7 +195,7 @@ module Playback {
|
||||
}
|
||||
// If we got here, we didn't find a match
|
||||
if (defaultValue === undefined) {
|
||||
throw new Error('No matching result in log array for path: ' + expectedPath);
|
||||
throw new Error("No matching result in log array for path: " + expectedPath);
|
||||
} else {
|
||||
return defaultValue;
|
||||
}
|
||||
@@ -203,7 +203,7 @@ module Playback {
|
||||
|
||||
let pathEquivCache: any = {};
|
||||
function pathsAreEquivalent(left: string, right: string, wrapper: { resolvePath(s: string): string }) {
|
||||
let key = left + '-~~-' + right;
|
||||
let key = left + "-~~-" + right;
|
||||
function areSame(a: string, b: string) {
|
||||
return ts.normalizeSlashes(a).toLowerCase() === ts.normalizeSlashes(b).toLowerCase();
|
||||
}
|
||||
@@ -233,14 +233,14 @@ module Playback {
|
||||
wrapper.endRecord = () => {
|
||||
if (recordLog !== undefined) {
|
||||
let i = 0;
|
||||
let fn = () => recordLogFileNameBase + i + '.json';
|
||||
let fn = () => recordLogFileNameBase + i + ".json";
|
||||
while (underlying.fileExists(fn())) i++;
|
||||
underlying.writeFile(fn(), JSON.stringify(recordLog));
|
||||
recordLog = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
Object.defineProperty(wrapper, 'args', {
|
||||
Object.defineProperty(wrapper, "args", {
|
||||
get() {
|
||||
if (replayLog !== undefined) {
|
||||
return replayLog.arguments;
|
||||
@@ -276,7 +276,7 @@ module Playback {
|
||||
|
||||
wrapper.getCurrentDirectory = () => {
|
||||
if (replayLog !== undefined) {
|
||||
return replayLog.currentDirectory || '';
|
||||
return replayLog.currentDirectory || "";
|
||||
} else if (recordLog !== undefined) {
|
||||
return recordLog.currentDirectory = underlying.getCurrentDirectory();
|
||||
} else {
|
||||
@@ -286,7 +286,7 @@ module Playback {
|
||||
|
||||
wrapper.resolvePath = recordReplay(wrapper.resolvePath, underlying)(
|
||||
(path) => callAndRecord(underlying.resolvePath(path), recordLog.pathsResolved, { path: path }),
|
||||
memoize((path) => findResultByFields(replayLog.pathsResolved, { path: path }, !ts.isRootedDiskPath(ts.normalizeSlashes(path)) && replayLog.currentDirectory ? replayLog.currentDirectory + '/' + path : ts.normalizeSlashes(path))));
|
||||
memoize((path) => findResultByFields(replayLog.pathsResolved, { path: path }, !ts.isRootedDiskPath(ts.normalizeSlashes(path)) && replayLog.currentDirectory ? replayLog.currentDirectory + "/" + path : ts.normalizeSlashes(path))));
|
||||
|
||||
wrapper.readFile = recordReplay(wrapper.readFile, underlying)(
|
||||
(path) => {
|
||||
@@ -299,7 +299,7 @@ module Playback {
|
||||
|
||||
wrapper.writeFile = recordReplay(wrapper.writeFile, underlying)(
|
||||
(path, contents) => callAndRecord(underlying.writeFile(path, contents), recordLog.filesWritten, { path: path, contents: contents, bom: false }),
|
||||
(path, contents) => noOpReplay('writeFile'));
|
||||
(path, contents) => noOpReplay("writeFile"));
|
||||
|
||||
wrapper.exit = (exitCode) => {
|
||||
if (recordLog !== undefined) {
|
||||
|
||||
@@ -74,7 +74,7 @@ class ProjectRunner extends RunnerBase {
|
||||
catch (e) {
|
||||
assert(false, "Testcase: " + testCaseFileName + " does not contain valid json format: " + e.message);
|
||||
}
|
||||
let testCaseJustName = testCaseFileName.replace(/^.*[\\\/]/, '').replace(/\.json/, "");
|
||||
let testCaseJustName = testCaseFileName.replace(/^.*[\\\/]/, "").replace(/\.json/, "");
|
||||
|
||||
function moduleNameToString(moduleKind: ts.ModuleKind) {
|
||||
return moduleKind === ts.ModuleKind.AMD
|
||||
@@ -331,9 +331,9 @@ class ProjectRunner extends RunnerBase {
|
||||
return Harness.Compiler.getErrorBaseline(inputFiles, compilerResult.errors);
|
||||
}
|
||||
|
||||
let name = 'Compiling project for ' + testCase.scenario + ': testcase ' + testCaseFileName;
|
||||
let name = "Compiling project for " + testCase.scenario + ": testcase " + testCaseFileName;
|
||||
|
||||
describe('Projects tests', () => {
|
||||
describe("Projects tests", () => {
|
||||
describe(name, () => {
|
||||
function verifyCompilerResults(moduleKind: ts.ModuleKind) {
|
||||
let compilerResult: BatchCompileProjectTestCaseResult;
|
||||
@@ -367,27 +367,27 @@ class ProjectRunner extends RunnerBase {
|
||||
compilerResult = batchCompilerProjectTestCase(moduleKind);
|
||||
});
|
||||
|
||||
it('Resolution information of (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => {
|
||||
Harness.Baseline.runBaseline('Resolution information of (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.json', () => {
|
||||
it("Resolution information of (" + moduleNameToString(moduleKind) + "): " + testCaseFileName, () => {
|
||||
Harness.Baseline.runBaseline("Resolution information of (" + moduleNameToString(compilerResult.moduleKind) + "): " + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + ".json", () => {
|
||||
return JSON.stringify(getCompilerResolutionInfo(), undefined, " ");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('Errors for (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => {
|
||||
it("Errors for (" + moduleNameToString(moduleKind) + "): " + testCaseFileName, () => {
|
||||
if (compilerResult.errors.length) {
|
||||
Harness.Baseline.runBaseline('Errors for (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.errors.txt', () => {
|
||||
Harness.Baseline.runBaseline("Errors for (" + moduleNameToString(compilerResult.moduleKind) + "): " + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + ".errors.txt", () => {
|
||||
return getErrorsBaseline(compilerResult);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
it('Baseline of emitted result (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => {
|
||||
it("Baseline of emitted result (" + moduleNameToString(moduleKind) + "): " + testCaseFileName, () => {
|
||||
if (testCase.baselineCheck) {
|
||||
ts.forEach(compilerResult.outputFiles, outputFile => {
|
||||
|
||||
Harness.Baseline.runBaseline('Baseline of emitted result (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + outputFile.fileName, () => {
|
||||
Harness.Baseline.runBaseline("Baseline of emitted result (" + moduleNameToString(compilerResult.moduleKind) + "): " + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + outputFile.fileName, () => {
|
||||
try {
|
||||
return ts.sys.readFile(getProjectOutputFolder(outputFile.fileName, compilerResult.moduleKind));
|
||||
}
|
||||
@@ -400,9 +400,9 @@ class ProjectRunner extends RunnerBase {
|
||||
});
|
||||
|
||||
|
||||
it('SourceMapRecord for (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => {
|
||||
it("SourceMapRecord for (" + moduleNameToString(moduleKind) + "): " + testCaseFileName, () => {
|
||||
if (compilerResult.sourceMapData) {
|
||||
Harness.Baseline.runBaseline('SourceMapRecord for (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.sourcemap.txt', () => {
|
||||
Harness.Baseline.runBaseline("SourceMapRecord for (" + moduleNameToString(compilerResult.moduleKind) + "): " + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + ".sourcemap.txt", () => {
|
||||
return Harness.SourceMapRecoder.getSourceMapRecord(compilerResult.sourceMapData, compilerResult.program,
|
||||
ts.filter(compilerResult.outputFiles, outputFile => Harness.Compiler.isJS(outputFile.emittedFileName)));
|
||||
});
|
||||
@@ -411,11 +411,11 @@ class ProjectRunner extends RunnerBase {
|
||||
|
||||
// Verify that all the generated .d.ts files compile
|
||||
|
||||
it('Errors in generated Dts files for (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => {
|
||||
it("Errors in generated Dts files for (" + moduleNameToString(moduleKind) + "): " + testCaseFileName, () => {
|
||||
if (!compilerResult.errors.length && testCase.declaration) {
|
||||
let dTsCompileResult = compileCompileDTsFiles(compilerResult);
|
||||
if (dTsCompileResult.errors.length) {
|
||||
Harness.Baseline.runBaseline('Errors in generated Dts files for (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.dts.errors.txt', () => {
|
||||
Harness.Baseline.runBaseline("Errors in generated Dts files for (" + moduleNameToString(compilerResult.moduleKind) + "): " + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + ".dts.errors.txt", () => {
|
||||
return getErrorsBaseline(dTsCompileResult);
|
||||
});
|
||||
}
|
||||
|
||||
+20
-20
@@ -13,12 +13,12 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
/// <reference path='test262Runner.ts' />
|
||||
/// <reference path='compilerRunner.ts' />
|
||||
/// <reference path='fourslashRunner.ts' />
|
||||
/// <reference path='projectsRunner.ts' />
|
||||
/// <reference path='rwcRunner.ts' />
|
||||
/// <reference path='harness.ts' />
|
||||
/// <reference path="test262Runner.ts" />
|
||||
/// <reference path="compilerRunner.ts" />
|
||||
/// <reference path="fourslashRunner.ts" />
|
||||
/// <reference path="projectsRunner.ts" />
|
||||
/// <reference path="rwcRunner.ts" />
|
||||
/// <reference path="harness.ts" />
|
||||
|
||||
let runners: RunnerBase[] = [];
|
||||
let iterations: number = 1;
|
||||
@@ -32,13 +32,13 @@ function runTests(runners: RunnerBase[]) {
|
||||
}
|
||||
|
||||
// users can define tests to run in mytest.config that will override cmd line args, otherwise use cmd line args (test.config), otherwise no options
|
||||
let mytestconfig = 'mytest.config';
|
||||
let testconfig = 'test.config';
|
||||
let mytestconfig = "mytest.config";
|
||||
let testconfig = "test.config";
|
||||
let testConfigFile =
|
||||
Harness.IO.fileExists(mytestconfig) ? Harness.IO.readFile(mytestconfig) :
|
||||
(Harness.IO.fileExists(testconfig) ? Harness.IO.readFile(testconfig) : '');
|
||||
(Harness.IO.fileExists(testconfig) ? Harness.IO.readFile(testconfig) : "");
|
||||
|
||||
if (testConfigFile !== '') {
|
||||
if (testConfigFile !== "") {
|
||||
let testConfig = JSON.parse(testConfigFile);
|
||||
if (testConfig.light) {
|
||||
Harness.lightMode = true;
|
||||
@@ -51,33 +51,33 @@ if (testConfigFile !== '') {
|
||||
}
|
||||
|
||||
switch (option) {
|
||||
case 'compiler':
|
||||
case "compiler":
|
||||
runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance));
|
||||
runners.push(new CompilerBaselineRunner(CompilerTestType.Regressions));
|
||||
runners.push(new ProjectRunner());
|
||||
break;
|
||||
case 'conformance':
|
||||
case "conformance":
|
||||
runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance));
|
||||
break;
|
||||
case 'project':
|
||||
case "project":
|
||||
runners.push(new ProjectRunner());
|
||||
break;
|
||||
case 'fourslash':
|
||||
case "fourslash":
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Native));
|
||||
break;
|
||||
case 'fourslash-shims':
|
||||
case "fourslash-shims":
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Shims));
|
||||
break;
|
||||
case 'fourslash-server':
|
||||
case "fourslash-server":
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Server));
|
||||
break;
|
||||
case 'fourslash-generated':
|
||||
case "fourslash-generated":
|
||||
runners.push(new GeneratedFourslashRunner(FourSlashTestType.Native));
|
||||
break;
|
||||
case 'rwc':
|
||||
case "rwc":
|
||||
runners.push(new RWCRunner());
|
||||
break;
|
||||
case 'test262':
|
||||
case "test262":
|
||||
runners.push(new Test262BaselineRunner());
|
||||
break;
|
||||
}
|
||||
@@ -102,6 +102,6 @@ if (runners.length === 0) {
|
||||
// runners.push(new GeneratedFourslashRunner());
|
||||
}
|
||||
|
||||
ts.sys.newLine = '\r\n';
|
||||
ts.sys.newLine = "\r\n";
|
||||
|
||||
runTests(runners);
|
||||
|
||||
@@ -33,7 +33,7 @@ abstract class RunnerBase {
|
||||
|
||||
// when running in the browser the 'full path' is the host name, shows up in error baselines
|
||||
let localHost = /http:\/localhost:\d+/g;
|
||||
fixedPath = fixedPath.replace(localHost, '');
|
||||
fixedPath = fixedPath.replace(localHost, "");
|
||||
return fixedPath;
|
||||
}
|
||||
}
|
||||
+22
-21
@@ -1,7 +1,7 @@
|
||||
/// <reference path='harness.ts'/>
|
||||
/// <reference path='runnerbase.ts' />
|
||||
/// <reference path='loggedIO.ts' />
|
||||
/// <reference path='..\compiler\commandLineParser.ts'/>
|
||||
/// <reference path="harness.ts"/>
|
||||
/// <reference path="runnerbase.ts" />
|
||||
/// <reference path="loggedIO.ts" />
|
||||
/// <reference path="..\compiler\commandLineParser.ts"/>
|
||||
|
||||
module RWC {
|
||||
function runWithIOLog(ioLog: IOLog, fn: () => void) {
|
||||
@@ -26,8 +26,8 @@ module RWC {
|
||||
let compilerResult: Harness.Compiler.CompilerResult;
|
||||
let compilerOptions: ts.CompilerOptions;
|
||||
let baselineOpts: Harness.Baseline.BaselineOptions = {
|
||||
Subfolder: 'rwc',
|
||||
Baselinefolder: 'internal/baselines'
|
||||
Subfolder: "rwc",
|
||||
Baselinefolder: "internal/baselines"
|
||||
};
|
||||
let baseName = /(.*)\/(.*).json/.exec(ts.normalizeSlashes(jsonPath))[2];
|
||||
let currentDirectory: string;
|
||||
@@ -49,7 +49,7 @@ module RWC {
|
||||
useCustomLibraryFile = undefined;
|
||||
});
|
||||
|
||||
it('can compile', () => {
|
||||
it("can compile", () => {
|
||||
let harnessCompiler = Harness.Compiler.getCompiler();
|
||||
let opts: ts.ParsedCommandLine;
|
||||
|
||||
@@ -74,10 +74,11 @@ module RWC {
|
||||
});
|
||||
|
||||
// Add files to compilation
|
||||
let isInInputList = (resolvedPath: string) => (inputFile: { unitName: string; content: string; }) => inputFile.unitName === resolvedPath;
|
||||
for (let fileRead of ioLog.filesRead) {
|
||||
// Check if the file is already added into the set of input files.
|
||||
var resolvedPath = ts.normalizeSlashes(ts.sys.resolvePath(fileRead.path));
|
||||
let inInputList = ts.forEach(inputFiles, inputFile => inputFile.unitName === resolvedPath);
|
||||
const resolvedPath = ts.normalizeSlashes(ts.sys.resolvePath(fileRead.path));
|
||||
let inInputList = ts.forEach(inputFiles, isInInputList(resolvedPath));
|
||||
|
||||
if (!Harness.isLibraryFile(fileRead.path)) {
|
||||
if (inInputList) {
|
||||
@@ -130,14 +131,14 @@ module RWC {
|
||||
});
|
||||
|
||||
|
||||
it('has the expected emitted code', () => {
|
||||
Harness.Baseline.runBaseline('has the expected emitted code', baseName + '.output.js', () => {
|
||||
it("has the expected emitted code", () => {
|
||||
Harness.Baseline.runBaseline("has the expected emitted code", baseName + ".output.js", () => {
|
||||
return Harness.Compiler.collateOutputs(compilerResult.files);
|
||||
}, false, baselineOpts);
|
||||
});
|
||||
|
||||
it('has the expected declaration file content', () => {
|
||||
Harness.Baseline.runBaseline('has the expected declaration file content', baseName + '.d.ts', () => {
|
||||
it("has the expected declaration file content", () => {
|
||||
Harness.Baseline.runBaseline("has the expected declaration file content", baseName + ".d.ts", () => {
|
||||
if (!compilerResult.declFilesCode.length) {
|
||||
return null;
|
||||
}
|
||||
@@ -146,8 +147,8 @@ module RWC {
|
||||
}, false, baselineOpts);
|
||||
});
|
||||
|
||||
it('has the expected source maps', () => {
|
||||
Harness.Baseline.runBaseline('has the expected source maps', baseName + '.map', () => {
|
||||
it("has the expected source maps", () => {
|
||||
Harness.Baseline.runBaseline("has the expected source maps", baseName + ".map", () => {
|
||||
if (!compilerResult.sourceMaps.length) {
|
||||
return null;
|
||||
}
|
||||
@@ -156,16 +157,16 @@ module RWC {
|
||||
}, false, baselineOpts);
|
||||
});
|
||||
|
||||
/*it('has correct source map record', () => {
|
||||
/*it("has correct source map record", () => {
|
||||
if (compilerOptions.sourceMap) {
|
||||
Harness.Baseline.runBaseline('has correct source map record', baseName + '.sourcemap.txt', () => {
|
||||
Harness.Baseline.runBaseline("has correct source map record", baseName + ".sourcemap.txt", () => {
|
||||
return compilerResult.getSourceMapRecord();
|
||||
}, false, baselineOpts);
|
||||
}
|
||||
});*/
|
||||
|
||||
it('has the expected errors', () => {
|
||||
Harness.Baseline.runBaseline('has the expected errors', baseName + '.errors.txt', () => {
|
||||
it("has the expected errors", () => {
|
||||
Harness.Baseline.runBaseline("has the expected errors", baseName + ".errors.txt", () => {
|
||||
if (compilerResult.errors.length === 0) {
|
||||
return null;
|
||||
}
|
||||
@@ -176,9 +177,9 @@ module RWC {
|
||||
|
||||
// Ideally, a generated declaration file will have no errors. But we allow generated
|
||||
// declaration file errors as part of the baseline.
|
||||
it('has the expected errors in generated declaration files', () => {
|
||||
it("has the expected errors in generated declaration files", () => {
|
||||
if (compilerOptions.declaration && !compilerResult.errors.length) {
|
||||
Harness.Baseline.runBaseline('has the expected errors in generated declaration files', baseName + '.dts.errors.txt', () => {
|
||||
Harness.Baseline.runBaseline("has the expected errors in generated declaration files", baseName + ".dts.errors.txt", () => {
|
||||
let declFileCompilationResult = Harness.Compiler.getCompiler().compileDeclarationFiles(inputFiles, otherFiles, compilerResult,
|
||||
/*settingscallback*/ undefined, compilerOptions, currentDirectory);
|
||||
if (declFileCompilationResult.declResult.errors.length === 0) {
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
///<reference path='harness.ts'/>
|
||||
///<reference path="harness.ts"/>
|
||||
|
||||
module Harness.SourceMapRecoder {
|
||||
|
||||
@@ -50,11 +50,11 @@ module Harness.SourceMapRecoder {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (sourceMapMappings.charAt(decodingIndex) == ',') {
|
||||
if (sourceMapMappings.charAt(decodingIndex) == ",") {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (sourceMapMappings.charAt(decodingIndex) == ';') {
|
||||
if (sourceMapMappings.charAt(decodingIndex) == ";") {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ module Harness.SourceMapRecoder {
|
||||
}
|
||||
|
||||
while (decodingIndex < sourceMapMappings.length) {
|
||||
if (sourceMapMappings.charAt(decodingIndex) == ';') {
|
||||
if (sourceMapMappings.charAt(decodingIndex) == ";") {
|
||||
// New line
|
||||
decodeOfEncodedMapping.emittedLine++;
|
||||
decodeOfEncodedMapping.emittedColumn = 1;
|
||||
@@ -125,7 +125,7 @@ module Harness.SourceMapRecoder {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sourceMapMappings.charAt(decodingIndex) == ',') {
|
||||
if (sourceMapMappings.charAt(decodingIndex) == ",") {
|
||||
// Next entry is on same line - no action needed
|
||||
decodingIndex++;
|
||||
continue;
|
||||
@@ -459,6 +459,6 @@ module Harness.SourceMapRecoder {
|
||||
SourceMapSpanWriter.close(); // If the last spans werent emitted, emit them
|
||||
}
|
||||
sourceMapRecoder.Close();
|
||||
return sourceMapRecoder.lines.join('\r\n');
|
||||
return sourceMapRecoder.lines.join("\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/// <reference path='harness.ts' />
|
||||
/// <reference path='runnerbase.ts' />
|
||||
/// <reference path="harness.ts" />
|
||||
/// <reference path="runnerbase.ts" />
|
||||
|
||||
class Test262BaselineRunner extends RunnerBase {
|
||||
private static basePath = 'internal/cases/test262';
|
||||
private static helpersFilePath = 'tests/cases/test262-harness/helpers.d.ts';
|
||||
private static basePath = "internal/cases/test262";
|
||||
private static helpersFilePath = "tests/cases/test262-harness/helpers.d.ts";
|
||||
private static helperFile = {
|
||||
unitName: Test262BaselineRunner.helpersFilePath,
|
||||
content: Harness.IO.readFile(Test262BaselineRunner.helpersFilePath)
|
||||
@@ -15,8 +15,8 @@ class Test262BaselineRunner extends RunnerBase {
|
||||
module: ts.ModuleKind.CommonJS
|
||||
};
|
||||
private static baselineOptions: Harness.Baseline.BaselineOptions = {
|
||||
Subfolder: 'test262',
|
||||
Baselinefolder: 'internal/baselines'
|
||||
Subfolder: "test262",
|
||||
Baselinefolder: "internal/baselines"
|
||||
};
|
||||
|
||||
private static getTestFilePath(filename: string): string {
|
||||
@@ -24,7 +24,7 @@ class Test262BaselineRunner extends RunnerBase {
|
||||
}
|
||||
|
||||
private runTest(filePath: string) {
|
||||
describe('test262 test for ' + filePath, () => {
|
||||
describe("test262 test for " + filePath, () => {
|
||||
// Mocha holds onto the closure environment of the describe callback even after the test is done.
|
||||
// Everything declared here should be cleared out in the "after" callback.
|
||||
let testState: {
|
||||
@@ -36,7 +36,7 @@ class Test262BaselineRunner extends RunnerBase {
|
||||
|
||||
before(() => {
|
||||
let content = Harness.IO.readFile(filePath);
|
||||
let testFilename = ts.removeFileExtension(filePath).replace(/\//g, '_') + ".test";
|
||||
let testFilename = ts.removeFileExtension(filePath).replace(/\//g, "_") + ".test";
|
||||
let testCaseContent = Harness.TestCaseParser.makeUnitsFromTest(content, testFilename);
|
||||
|
||||
let inputFiles = testCaseContent.testUnitData.map(unit => {
|
||||
@@ -61,15 +61,15 @@ class Test262BaselineRunner extends RunnerBase {
|
||||
testState = undefined;
|
||||
});
|
||||
|
||||
it('has the expected emitted code', () => {
|
||||
Harness.Baseline.runBaseline('has the expected emitted code', testState.filename + '.output.js', () => {
|
||||
it("has the expected emitted code", () => {
|
||||
Harness.Baseline.runBaseline("has the expected emitted code", testState.filename + ".output.js", () => {
|
||||
let files = testState.compilerResult.files.filter(f => f.fileName !== Test262BaselineRunner.helpersFilePath);
|
||||
return Harness.Compiler.collateOutputs(files);
|
||||
}, false, Test262BaselineRunner.baselineOptions);
|
||||
});
|
||||
|
||||
it('has the expected errors', () => {
|
||||
Harness.Baseline.runBaseline('has the expected errors', testState.filename + '.errors.txt', () => {
|
||||
it("has the expected errors", () => {
|
||||
Harness.Baseline.runBaseline("has the expected errors", testState.filename + ".errors.txt", () => {
|
||||
let errors = testState.compilerResult.errors;
|
||||
if (errors.length === 0) {
|
||||
return null;
|
||||
@@ -79,13 +79,13 @@ class Test262BaselineRunner extends RunnerBase {
|
||||
}, false, Test262BaselineRunner.baselineOptions);
|
||||
});
|
||||
|
||||
it('satisfies inletiants', () => {
|
||||
it("satisfies inletiants", () => {
|
||||
let sourceFile = testState.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
|
||||
Utils.assertInvariants(sourceFile, /*parent:*/ undefined);
|
||||
});
|
||||
|
||||
it('has the expected AST', () => {
|
||||
Harness.Baseline.runBaseline('has the expected AST', testState.filename + '.AST.txt', () => {
|
||||
it("has the expected AST", () => {
|
||||
Harness.Baseline.runBaseline("has the expected AST", testState.filename + ".AST.txt", () => {
|
||||
let sourceFile = testState.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
|
||||
return Utils.sourceFileToJSON(sourceFile);
|
||||
}, false, Test262BaselineRunner.baselineOptions);
|
||||
|
||||
+28
-3
@@ -183,7 +183,7 @@ namespace ts.server {
|
||||
|
||||
return {
|
||||
configFileName: response.body.configFileName,
|
||||
fileNameList: response.body.fileNameList
|
||||
fileNames: response.body.fileNames
|
||||
};
|
||||
}
|
||||
|
||||
@@ -527,8 +527,33 @@ namespace ts.server {
|
||||
});
|
||||
}
|
||||
|
||||
getDocumentHighlights(fileName: string, position: number): DocumentHighlights[] {
|
||||
throw new Error("Not Implemented Yet.");
|
||||
getDocumentHighlights(fileName: string, position: number, filesToSearch: string[]): DocumentHighlights[] {
|
||||
let { line, offset } = this.positionToOneBasedLineOffset(fileName, position);
|
||||
let args: protocol.DocumentHighlightsRequestArgs = { file: fileName, line, offset, filesToSearch };
|
||||
|
||||
let request = this.processRequest<protocol.DocumentHighlightsRequest>(CommandNames.DocumentHighlights, args);
|
||||
let response = this.processResponse<protocol.DocumentHighlightsResponse>(request);
|
||||
|
||||
let self = this;
|
||||
return response.body.map(convertToDocumentHighlights);
|
||||
|
||||
function convertToDocumentHighlights(item: ts.server.protocol.DocumentHighlightsItem): ts.DocumentHighlights {
|
||||
let { file, highlightSpans } = item;
|
||||
|
||||
return {
|
||||
fileName: file,
|
||||
highlightSpans: highlightSpans.map(convertHighlightSpan)
|
||||
};
|
||||
|
||||
function convertHighlightSpan(span: ts.server.protocol.HighlightSpan): ts.HighlightSpan {
|
||||
let start = self.lineOffsetToPosition(file, span.start);
|
||||
let end = self.lineOffsetToPosition(file, span.end);
|
||||
return {
|
||||
textSpan: ts.createTextSpanFromBounds(start, end),
|
||||
kind: span.kind
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getOutliningSpans(fileName: string): OutliningSpan[] {
|
||||
|
||||
@@ -304,7 +304,7 @@ namespace ts.server {
|
||||
return this.projectService.openFile(filename, false);
|
||||
}
|
||||
|
||||
getFileNameList() {
|
||||
getFileNames() {
|
||||
let sourceFiles = this.program.getSourceFiles();
|
||||
return sourceFiles.map(sourceFile => sourceFile.fileName);
|
||||
}
|
||||
|
||||
Vendored
+7
-2
@@ -123,9 +123,14 @@ declare module NodeJS {
|
||||
|
||||
export interface ReadWriteStream extends ReadableStream, WritableStream { }
|
||||
|
||||
interface WindowSize {
|
||||
columns: number;
|
||||
rows: number;
|
||||
}
|
||||
|
||||
export interface Process extends EventEmitter {
|
||||
stdout: WritableStream;
|
||||
stderr: WritableStream;
|
||||
stdout: WritableStream & WindowSize;
|
||||
stderr: WritableStream & WindowSize;
|
||||
stdin: ReadableStream;
|
||||
argv: string[];
|
||||
execPath: string;
|
||||
|
||||
Vendored
+66
-1
@@ -116,7 +116,7 @@ declare namespace ts.server.protocol {
|
||||
/**
|
||||
* The list of normalized file name in the project, including 'lib.d.ts'
|
||||
*/
|
||||
fileNameList?: string[];
|
||||
fileNames?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -156,6 +156,17 @@ declare namespace ts.server.protocol {
|
||||
arguments: FileLocationRequestArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Arguments in document highlight request; include: filesToSearch, file,
|
||||
* line, offset.
|
||||
*/
|
||||
export interface DocumentHighlightsRequestArgs extends FileLocationRequestArgs {
|
||||
/**
|
||||
* List of files to search for document highlights.
|
||||
*/
|
||||
filesToSearch: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Go to definition request; value of command field is
|
||||
* "definition". Return response giving the file locations that
|
||||
@@ -238,6 +249,35 @@ declare namespace ts.server.protocol {
|
||||
body?: OccurrencesResponseItem[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get document highlights request; value of command field is
|
||||
* "documentHighlights". Return response giving spans that are relevant
|
||||
* in the file at a given line and column.
|
||||
*/
|
||||
export interface DocumentHighlightsRequest extends FileLocationRequest {
|
||||
arguments: DocumentHighlightsRequestArgs
|
||||
}
|
||||
|
||||
export interface HighlightSpan extends TextSpan {
|
||||
kind: string
|
||||
}
|
||||
|
||||
export interface DocumentHighlightsItem {
|
||||
/**
|
||||
* File containing highlight spans.
|
||||
*/
|
||||
file: string,
|
||||
|
||||
/**
|
||||
* Spans to highlight in file.
|
||||
*/
|
||||
highlightSpans: HighlightSpan[];
|
||||
}
|
||||
|
||||
export interface DocumentHighlightsResponse extends Response {
|
||||
body?: DocumentHighlightsItem[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Find references request; value of command field is
|
||||
* "references". Return response giving the file locations that
|
||||
@@ -854,6 +894,31 @@ declare namespace ts.server.protocol {
|
||||
export interface SignatureHelpResponse extends Response {
|
||||
body?: SignatureHelpItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Arguments for GeterrForProject request.
|
||||
*/
|
||||
export interface GeterrForProjectRequestArgs {
|
||||
/**
|
||||
* the file requesting project error list
|
||||
*/
|
||||
file: string;
|
||||
|
||||
/**
|
||||
* Delay in milliseconds to wait before starting to compute
|
||||
* errors for the files in the file list
|
||||
*/
|
||||
delay: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* GeterrForProjectRequest request; value of command field is
|
||||
* "geterrForProject". It works similarly with 'Geterr', only
|
||||
* it request for every file in this project.
|
||||
*/
|
||||
export interface GeterrForProjectRequest extends Request {
|
||||
arguments: GeterrForProjectRequestArgs
|
||||
}
|
||||
|
||||
/**
|
||||
* Arguments for geterr messages.
|
||||
|
||||
+97
-5
@@ -86,9 +86,11 @@ namespace ts.server {
|
||||
export const Format = "format";
|
||||
export const Formatonkey = "formatonkey";
|
||||
export const Geterr = "geterr";
|
||||
export const GeterrForProject = "geterrForProject";
|
||||
export const NavBar = "navbar";
|
||||
export const Navto = "navto";
|
||||
export const Occurrences = "occurrences";
|
||||
export const DocumentHighlights = "documentHighlights";
|
||||
export const Open = "open";
|
||||
export const Quickinfo = "quickinfo";
|
||||
export const References = "references";
|
||||
@@ -234,7 +236,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private updateErrorCheck(checkList: PendingErrorCheck[], seq: number,
|
||||
matchSeq: (seq: number) => boolean, ms = 1500, followMs = 200) {
|
||||
matchSeq: (seq: number) => boolean, ms = 1500, followMs = 200, requireOpen = true) {
|
||||
if (followMs > ms) {
|
||||
followMs = ms;
|
||||
}
|
||||
@@ -249,7 +251,7 @@ namespace ts.server {
|
||||
var checkOne = () => {
|
||||
if (matchSeq(seq)) {
|
||||
var checkSpec = checkList[index++];
|
||||
if (checkSpec.project.getSourceFileFromName(checkSpec.fileName, true)) {
|
||||
if (checkSpec.project.getSourceFileFromName(checkSpec.fileName, requireOpen)) {
|
||||
this.syntacticCheck(checkSpec.fileName, checkSpec.project);
|
||||
this.immediateId = setImmediate(() => {
|
||||
this.semanticCheck(checkSpec.fileName, checkSpec.project);
|
||||
@@ -313,7 +315,7 @@ namespace ts.server {
|
||||
}));
|
||||
}
|
||||
|
||||
private 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,6 +345,42 @@ namespace ts.server {
|
||||
});
|
||||
}
|
||||
|
||||
private getDocumentHighlights(line: number, offset: number, fileName: string, filesToSearch: string[]): protocol.DocumentHighlightsItem[] {
|
||||
fileName = ts.normalizePath(fileName);
|
||||
let project = this.projectService.getProjectForFile(fileName);
|
||||
|
||||
if (!project) {
|
||||
throw Errors.NoProject;
|
||||
}
|
||||
|
||||
let { compilerService } = project;
|
||||
let position = compilerService.host.lineOffsetToPosition(fileName, line, offset);
|
||||
|
||||
let documentHighlights = compilerService.languageService.getDocumentHighlights(fileName, position, filesToSearch);
|
||||
|
||||
if (!documentHighlights) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return documentHighlights.map(convertToDocumentHighlightsItem);
|
||||
|
||||
function convertToDocumentHighlightsItem(documentHighlights: ts.DocumentHighlights): ts.server.protocol.DocumentHighlightsItem {
|
||||
let { fileName, highlightSpans } = documentHighlights;
|
||||
|
||||
return {
|
||||
file: fileName,
|
||||
highlightSpans: highlightSpans.map(convertHighlightSpan)
|
||||
};
|
||||
|
||||
function convertHighlightSpan(highlightSpan: ts.HighlightSpan): ts.server.protocol.HighlightSpan {
|
||||
let { textSpan, kind } = highlightSpan;
|
||||
let start = compilerService.host.positionToLineOffset(fileName, textSpan.start);
|
||||
let end = compilerService.host.positionToLineOffset(fileName, ts.textSpanEnd(textSpan));
|
||||
return { start, end, kind };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private getProjectInfo(fileName: string, needFileNameList: boolean): protocol.ProjectInfo {
|
||||
fileName = ts.normalizePath(fileName)
|
||||
let project = this.projectService.getProjectForFile(fileName)
|
||||
@@ -352,7 +390,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
if (needFileNameList) {
|
||||
projectInfo.fileNameList = project.getFileNameList();
|
||||
projectInfo.fileNames = project.getFileNames();
|
||||
}
|
||||
|
||||
return projectInfo;
|
||||
@@ -836,7 +874,53 @@ namespace ts.server {
|
||||
}));
|
||||
}
|
||||
|
||||
public exit() {
|
||||
getDiagnosticsForProject(delay: number, fileName: string) {
|
||||
let { configFileName, fileNames: fileNamesInProject } = this.getProjectInfo(fileName, true);
|
||||
// No need to analyze lib.d.ts
|
||||
fileNamesInProject = fileNamesInProject.filter((value, index, array) => value.indexOf("lib.d.ts") < 0);
|
||||
|
||||
// Sort the file name list to make the recently touched files come first
|
||||
let highPriorityFiles: string[] = [];
|
||||
let mediumPriorityFiles: string[] = [];
|
||||
let lowPriorityFiles: string[] = [];
|
||||
let veryLowPriorityFiles: string[] = [];
|
||||
let normalizedFileName = ts.normalizePath(fileName);
|
||||
let project = this.projectService.getProjectForFile(normalizedFileName);
|
||||
for (let fileNameInProject of fileNamesInProject) {
|
||||
if (this.getCanonicalFileName(fileNameInProject) == this.getCanonicalFileName(fileName))
|
||||
highPriorityFiles.push(fileNameInProject);
|
||||
else {
|
||||
let info = this.projectService.getScriptInfo(fileNameInProject);
|
||||
if (!info.isOpen) {
|
||||
if (fileNameInProject.indexOf(".d.ts") > 0)
|
||||
veryLowPriorityFiles.push(fileNameInProject);
|
||||
else
|
||||
lowPriorityFiles.push(fileNameInProject);
|
||||
}
|
||||
else
|
||||
mediumPriorityFiles.push(fileNameInProject);
|
||||
}
|
||||
}
|
||||
|
||||
fileNamesInProject = highPriorityFiles.concat(mediumPriorityFiles).concat(lowPriorityFiles).concat(veryLowPriorityFiles);
|
||||
|
||||
if (fileNamesInProject.length > 0) {
|
||||
let checkList = fileNamesInProject.map<PendingErrorCheck>((fileName: string) => {
|
||||
let normalizedFileName = ts.normalizePath(fileName);
|
||||
return { fileName: normalizedFileName, project };
|
||||
});
|
||||
// Project level error analysis runs on background files too, therefore
|
||||
// doesn't require the file to be opened
|
||||
this.updateErrorCheck(checkList, this.changeSeq, (n) => n == this.changeSeq, delay, 200, /*requireOpen*/ false);
|
||||
}
|
||||
}
|
||||
|
||||
getCanonicalFileName(fileName: string) {
|
||||
let name = this.host.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
|
||||
return ts.normalizePath(name);
|
||||
}
|
||||
|
||||
exit() {
|
||||
}
|
||||
|
||||
private handlers : Map<(request: protocol.Request) => {response?: any, responseRequired?: boolean}> = {
|
||||
@@ -894,6 +978,10 @@ namespace ts.server {
|
||||
var geterrArgs = <protocol.GeterrRequestArgs>request.arguments;
|
||||
return {response: this.getDiagnostics(geterrArgs.delay, geterrArgs.files), responseRequired: false};
|
||||
},
|
||||
[CommandNames.GeterrForProject]: (request: protocol.Request) => {
|
||||
let { file, delay } = <protocol.GeterrForProjectRequestArgs>request.arguments;
|
||||
return {response: this.getDiagnosticsForProject(delay, file), responseRequired: false};
|
||||
},
|
||||
[CommandNames.Change]: (request: protocol.Request) => {
|
||||
var changeArgs = <protocol.ChangeRequestArgs>request.arguments;
|
||||
this.change(changeArgs.line, changeArgs.offset, changeArgs.endLine, changeArgs.endOffset,
|
||||
@@ -937,6 +1025,10 @@ namespace ts.server {
|
||||
var { line, offset, file: fileName } = <protocol.FileLocationRequestArgs>request.arguments;
|
||||
return {response: this.getOccurrences(line, offset, fileName), responseRequired: true};
|
||||
},
|
||||
[CommandNames.DocumentHighlights]: (request: protocol.Request) => {
|
||||
var { line, offset, file: fileName, filesToSearch } = <protocol.DocumentHighlightsRequestArgs>request.arguments;
|
||||
return {response: this.getDocumentHighlights(line, offset, fileName, filesToSearch), responseRequired: true};
|
||||
},
|
||||
[CommandNames.ProjectInfo]: (request: protocol.Request) => {
|
||||
var { file, needFileNameList } = <protocol.ProjectInfoRequestArgs>request.arguments;
|
||||
return {response: this.getProjectInfo(file, needFileNameList), responseRequired: true};
|
||||
|
||||
@@ -418,6 +418,7 @@ namespace ts.formatting {
|
||||
case SyntaxKind.DefaultClause:
|
||||
case SyntaxKind.CaseClause:
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
case SyntaxKind.CallExpression:
|
||||
case SyntaxKind.NewExpression:
|
||||
case SyntaxKind.VariableStatement:
|
||||
|
||||
@@ -3392,23 +3392,36 @@ namespace ts {
|
||||
case SyntaxKind.LessThanSlashToken:
|
||||
case SyntaxKind.SlashToken:
|
||||
case SyntaxKind.Identifier:
|
||||
if(parent && (parent.kind === SyntaxKind.JsxSelfClosingElement || parent.kind === SyntaxKind.JsxOpeningElement)) {
|
||||
case SyntaxKind.JsxAttribute:
|
||||
case SyntaxKind.JsxSpreadAttribute:
|
||||
if (parent && (parent.kind === SyntaxKind.JsxSelfClosingElement || parent.kind === SyntaxKind.JsxOpeningElement)) {
|
||||
return <JsxOpeningLikeElement>parent;
|
||||
}
|
||||
break;
|
||||
|
||||
// The context token is the closing } or " of an attribute, which means
|
||||
// its parent is a JsxExpression, whose parent is a JsxAttribute,
|
||||
// whose parent is a JsxOpeningLikeElement
|
||||
case SyntaxKind.StringLiteral:
|
||||
if (parent && ((parent.kind === SyntaxKind.JsxAttribute) || (parent.kind === SyntaxKind.JsxSpreadAttribute))) {
|
||||
return <JsxOpeningLikeElement>parent.parent;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SyntaxKind.CloseBraceToken:
|
||||
// The context token is the closing } of an attribute, which means
|
||||
// its parent is a JsxExpression, whose parent is a JsxAttribute,
|
||||
// whose parent is a JsxOpeningLikeElement
|
||||
if(parent &&
|
||||
if (parent &&
|
||||
parent.kind === SyntaxKind.JsxExpression &&
|
||||
parent.parent &&
|
||||
parent.parent.kind === SyntaxKind.JsxAttribute) {
|
||||
(parent.parent.kind === SyntaxKind.JsxAttribute)) {
|
||||
|
||||
return <JsxOpeningLikeElement>parent.parent.parent;
|
||||
}
|
||||
|
||||
if (parent && parent.kind === SyntaxKind.JsxSpreadAttribute) {
|
||||
return <JsxOpeningLikeElement>parent.parent;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -4607,7 +4620,7 @@ namespace ts {
|
||||
case SyntaxKind.BreakKeyword:
|
||||
case SyntaxKind.ContinueKeyword:
|
||||
if (hasKind(node.parent, SyntaxKind.BreakStatement) || hasKind(node.parent, SyntaxKind.ContinueStatement)) {
|
||||
return getBreakOrContinueStatementOccurences(<BreakOrContinueStatement>node.parent);
|
||||
return getBreakOrContinueStatementOccurrences(<BreakOrContinueStatement>node.parent);
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.ForKeyword:
|
||||
@@ -4933,7 +4946,7 @@ namespace ts {
|
||||
return map(keywords, getHighlightSpanForNode);
|
||||
}
|
||||
|
||||
function getBreakOrContinueStatementOccurences(breakOrContinueStatement: BreakOrContinueStatement): HighlightSpan[] {
|
||||
function getBreakOrContinueStatementOccurrences(breakOrContinueStatement: BreakOrContinueStatement): HighlightSpan[] {
|
||||
let owner = getBreakOrContinueOwner(breakOrContinueStatement);
|
||||
|
||||
if (owner) {
|
||||
|
||||
Reference in New Issue
Block a user