mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into report-multiple-overload-errors
This commit is contained in:
+72
-26
@@ -3265,7 +3265,7 @@ namespace ts {
|
||||
|
||||
function hasVisibleDeclarations(symbol: Symbol, shouldComputeAliasToMakeVisible: boolean): SymbolVisibilityResult | undefined {
|
||||
let aliasesToMakeVisible: LateVisibilityPaintedStatement[] | undefined;
|
||||
if (!every(symbol.declarations, getIsDeclarationVisible)) {
|
||||
if (!every(filter(symbol.declarations, d => d.kind !== SyntaxKind.Identifier), getIsDeclarationVisible)) {
|
||||
return undefined;
|
||||
}
|
||||
return { accessibility: SymbolAccessibility.Accessible, aliasesToMakeVisible };
|
||||
@@ -5481,7 +5481,7 @@ namespace ts {
|
||||
function getTypeFromObjectBindingPattern(pattern: ObjectBindingPattern, includePatternInType: boolean, reportErrors: boolean): Type {
|
||||
const members = createSymbolTable();
|
||||
let stringIndexInfo: IndexInfo | undefined;
|
||||
let objectFlags = ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectLiteral;
|
||||
let objectFlags = ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectOrArrayLiteral;
|
||||
forEach(pattern.elements, e => {
|
||||
const name = e.propertyName || <Identifier>e.name;
|
||||
if (e.dotDotDotToken) {
|
||||
@@ -10097,9 +10097,9 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
function getPropertyTypeForIndexType(originalObjectType: Type, objectType: Type, indexType: Type, fullIndexType: Type, suppressNoImplicitAnyError: boolean, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression | undefined, accessFlags: AccessFlags) {
|
||||
function getPropertyNameFromIndex(indexType: Type, accessNode: StringLiteral | Identifier | ObjectBindingPattern | ArrayBindingPattern | ComputedPropertyName | NumericLiteral | IndexedAccessTypeNode | ElementAccessExpression | SyntheticExpression | undefined) {
|
||||
const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode : undefined;
|
||||
const propName = isTypeUsableAsPropertyName(indexType) ?
|
||||
return isTypeUsableAsPropertyName(indexType) ?
|
||||
getPropertyNameFromType(indexType) :
|
||||
accessExpression && checkThatExpressionIsProperSymbolReference(accessExpression.argumentExpression, indexType, /*reportError*/ false) ?
|
||||
getPropertyNameForKnownSymbolName(idText((<PropertyAccessExpression>accessExpression.argumentExpression).name)) :
|
||||
@@ -10107,6 +10107,11 @@ namespace ts {
|
||||
// late bound names are handled in the first branch, so here we only need to handle normal names
|
||||
getPropertyNameForPropertyNameNode(accessNode) :
|
||||
undefined;
|
||||
}
|
||||
|
||||
function getPropertyTypeForIndexType(originalObjectType: Type, objectType: Type, indexType: Type, fullIndexType: Type, suppressNoImplicitAnyError: boolean, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression | undefined, accessFlags: AccessFlags) {
|
||||
const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode : undefined;
|
||||
const propName = getPropertyNameFromIndex(indexType, accessNode);
|
||||
if (propName !== undefined) {
|
||||
const prop = getPropertyOfType(objectType, propName);
|
||||
if (prop) {
|
||||
@@ -10803,7 +10808,7 @@ namespace ts {
|
||||
emptyArray,
|
||||
getIndexInfoWithReadonly(stringIndexInfo, readonly),
|
||||
getIndexInfoWithReadonly(numberIndexInfo, readonly));
|
||||
spread.objectFlags |= ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectLiteral | ObjectFlags.ContainsSpread | objectFlags;
|
||||
spread.objectFlags |= ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectOrArrayLiteral | ObjectFlags.ContainsSpread | objectFlags;
|
||||
return spread;
|
||||
}
|
||||
|
||||
@@ -14519,7 +14524,7 @@ namespace ts {
|
||||
if (propType) {
|
||||
return propType;
|
||||
}
|
||||
if (everyType(type, isTupleType) && !everyType(type, t => !(<TupleTypeReference>t).target.hasRestElement)) {
|
||||
if (everyType(type, isTupleType)) {
|
||||
return mapType(type, t => getRestTypeOfTupleType(<TupleTypeReference>t) || undefinedType);
|
||||
}
|
||||
return undefined;
|
||||
@@ -15723,12 +15728,16 @@ namespace ts {
|
||||
return !!(getObjectFlags(type) & ObjectFlags.ObjectLiteral);
|
||||
}
|
||||
|
||||
function widenObjectLiteralCandidates(candidates: Type[]): Type[] {
|
||||
function isObjectOrArrayLiteralType(type: Type) {
|
||||
return !!(getObjectFlags(type) & (ObjectFlags.ObjectLiteral | ObjectFlags.ArrayLiteral));
|
||||
}
|
||||
|
||||
function unionObjectAndArrayLiteralCandidates(candidates: Type[]): Type[] {
|
||||
if (candidates.length > 1) {
|
||||
const objectLiterals = filter(candidates, isObjectLiteralType);
|
||||
const objectLiterals = filter(candidates, isObjectOrArrayLiteralType);
|
||||
if (objectLiterals.length) {
|
||||
const objectLiteralsType = getWidenedType(getUnionType(objectLiterals, UnionReduction.Subtype));
|
||||
return concatenate(filter(candidates, t => !isObjectLiteralType(t)), [objectLiteralsType]);
|
||||
const literalsType = getUnionType(objectLiterals, UnionReduction.Subtype);
|
||||
return concatenate(filter(candidates, t => !isObjectOrArrayLiteralType(t)), [literalsType]);
|
||||
}
|
||||
}
|
||||
return candidates;
|
||||
@@ -15739,8 +15748,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getCovariantInference(inference: InferenceInfo, signature: Signature) {
|
||||
// Extract all object literal types and replace them with a single widened and normalized type.
|
||||
const candidates = widenObjectLiteralCandidates(inference.candidates!);
|
||||
// Extract all object and array literal types and replace them with a single widened and normalized type.
|
||||
const candidates = unionObjectAndArrayLiteralCandidates(inference.candidates!);
|
||||
// We widen inferred literal types if
|
||||
// all inferences were made to top-level occurrences of the type parameter, and
|
||||
// the type parameter has no constraint or its constraint includes no primitive or literal types, and
|
||||
@@ -19226,22 +19235,34 @@ namespace ts {
|
||||
const minLength = elementCount - (hasRestElement ? 1 : 0);
|
||||
// If array literal is actually a destructuring pattern, mark it as an implied type. We do this such
|
||||
// that we get the same behavior for "var [x, y] = []" and "[x, y] = []".
|
||||
let tupleResult: Type | undefined;
|
||||
let tupleResult;
|
||||
if (inDestructuringPattern && minLength > 0) {
|
||||
const type = cloneTypeReference(<TypeReference>createTupleType(elementTypes, minLength, hasRestElement));
|
||||
type.pattern = node;
|
||||
return type;
|
||||
}
|
||||
else if (tupleResult = getArrayLiteralTupleTypeIfApplicable(elementTypes, contextualType, hasRestElement, elementCount, inConstContext)) {
|
||||
return tupleResult;
|
||||
return createArrayLiteralType(tupleResult);
|
||||
}
|
||||
else if (forceTuple) {
|
||||
return createTupleType(elementTypes, minLength, hasRestElement);
|
||||
return createArrayLiteralType(createTupleType(elementTypes, minLength, hasRestElement));
|
||||
}
|
||||
}
|
||||
return createArrayType(elementTypes.length ?
|
||||
return createArrayLiteralType(createArrayType(elementTypes.length ?
|
||||
getUnionType(elementTypes, UnionReduction.Subtype) :
|
||||
strictNullChecks ? implicitNeverType : undefinedWideningType, inConstContext);
|
||||
strictNullChecks ? implicitNeverType : undefinedWideningType, inConstContext));
|
||||
}
|
||||
|
||||
function createArrayLiteralType(type: ObjectType) {
|
||||
if (!(getObjectFlags(type) & ObjectFlags.Reference)) {
|
||||
return type;
|
||||
}
|
||||
let literalType = (<TypeReference>type).literalType;
|
||||
if (!literalType) {
|
||||
literalType = (<TypeReference>type).literalType = cloneTypeReference(<TypeReference>type);
|
||||
literalType.objectFlags |= ObjectFlags.ArrayLiteral | ObjectFlags.ContainsObjectOrArrayLiteral;
|
||||
}
|
||||
return literalType;
|
||||
}
|
||||
|
||||
function getArrayLiteralTupleTypeIfApplicable(elementTypes: Type[], contextualType: Type | undefined, hasRestElement: boolean, elementCount = elementTypes.length, readonly = false) {
|
||||
@@ -19526,7 +19547,7 @@ namespace ts {
|
||||
const stringIndexInfo = hasComputedStringProperty ? getObjectLiteralIndexInfo(node, offset, propertiesArray, IndexKind.String) : undefined;
|
||||
const numberIndexInfo = hasComputedNumberProperty ? getObjectLiteralIndexInfo(node, offset, propertiesArray, IndexKind.Number) : undefined;
|
||||
const result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
|
||||
result.objectFlags |= objectFlags | ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectLiteral;
|
||||
result.objectFlags |= objectFlags | ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectOrArrayLiteral;
|
||||
if (isJSObjectLiteral) {
|
||||
result.objectFlags |= ObjectFlags.JSLiteral;
|
||||
}
|
||||
@@ -19722,7 +19743,7 @@ namespace ts {
|
||||
function createJsxAttributesType() {
|
||||
objectFlags |= freshObjectLiteralFlag;
|
||||
const result = createAnonymousType(attributes.symbol, attributesTable, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined);
|
||||
result.objectFlags |= objectFlags | ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectLiteral;
|
||||
result.objectFlags |= objectFlags | ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectOrArrayLiteral;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -21496,7 +21517,8 @@ namespace ts {
|
||||
reorderCandidates(signatures, candidates);
|
||||
if (!candidates.length) {
|
||||
if (reportErrors) {
|
||||
diagnostics.add(createDiagnosticForNode(node, Diagnostics.Call_target_does_not_contain_any_signatures));
|
||||
const errorNode = getCallErrorNode(node);
|
||||
diagnostics.add(createDiagnosticForNode(errorNode, Diagnostics.Call_target_does_not_contain_any_signatures));
|
||||
}
|
||||
return resolveErrorCall(node);
|
||||
}
|
||||
@@ -21574,6 +21596,7 @@ namespace ts {
|
||||
// If candidate is undefined, it means that no candidates had a suitable arity. In that case,
|
||||
// skip the checkApplicableSignature check.
|
||||
if (reportErrors) {
|
||||
const errorNode = getCallErrorNode(node);
|
||||
if (candidatesForArgumentError) {
|
||||
if (candidatesForArgumentError.length === 1 || candidatesForArgumentError.length > 3) {
|
||||
const last = candidatesForArgumentError[candidatesForArgumentError.length - 1];
|
||||
@@ -21608,7 +21631,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else if (candidateForArgumentArityError) {
|
||||
diagnostics.add(getArgumentArityError(node, [candidateForArgumentArityError], args));
|
||||
diagnostics.add(getArgumentArityError(errorNode, [candidateForArgumentArityError], args));
|
||||
}
|
||||
else if (candidateForTypeArgumentError) {
|
||||
checkTypeArguments(candidateForTypeArgumentError, (node as CallExpression | TaggedTemplateExpression | JsxOpeningLikeElement).typeArguments!, /*reportErrors*/ true, fallbackError);
|
||||
@@ -21616,19 +21639,31 @@ namespace ts {
|
||||
else {
|
||||
const signaturesWithCorrectTypeArgumentArity = filter(signatures, s => hasCorrectTypeArgumentArity(s, typeArguments));
|
||||
if (signaturesWithCorrectTypeArgumentArity.length === 0) {
|
||||
diagnostics.add(getTypeArgumentArityError(node, signatures, typeArguments!));
|
||||
diagnostics.add(getTypeArgumentArityError(errorNode, signatures, typeArguments!));
|
||||
}
|
||||
else if (!isDecorator) {
|
||||
diagnostics.add(getArgumentArityError(node, signaturesWithCorrectTypeArgumentArity, args));
|
||||
diagnostics.add(getArgumentArityError(errorNode, signaturesWithCorrectTypeArgumentArity, args));
|
||||
}
|
||||
else if (fallbackError) {
|
||||
diagnostics.add(createDiagnosticForNode(node, fallbackError));
|
||||
diagnostics.add(createDiagnosticForNode(errorNode, fallbackError));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return produceDiagnostics || !args ? resolveErrorCall(node) : getCandidateForOverloadFailure(node, candidates, args, !!candidatesOutArray);
|
||||
|
||||
function getCallErrorNode(node: CallLikeExpression): Node {
|
||||
if (isCallExpression(node)) {
|
||||
if (isPropertyAccessExpression(node.expression)) {
|
||||
return node.expression.name;
|
||||
}
|
||||
else {
|
||||
return node.expression;
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
function chooseOverload(candidates: Signature[], relation: Map<RelationComparisonResult>, signatureHelpTrailingComma = false) {
|
||||
candidatesForArgumentError = undefined;
|
||||
candidateForArgumentArityError = undefined;
|
||||
@@ -25418,7 +25453,7 @@ namespace ts {
|
||||
forEach(node.types, checkSourceElement);
|
||||
}
|
||||
|
||||
function checkIndexedAccessIndexType(type: Type, accessNode: Node) {
|
||||
function checkIndexedAccessIndexType(type: Type, accessNode: IndexedAccessTypeNode | ElementAccessExpression) {
|
||||
if (!(type.flags & TypeFlags.IndexedAccess)) {
|
||||
return type;
|
||||
}
|
||||
@@ -25434,9 +25469,20 @@ namespace ts {
|
||||
}
|
||||
// Check if we're indexing with a numeric type and if either object or index types
|
||||
// is a generic type with a constraint that has a numeric index signature.
|
||||
if (getIndexInfoOfType(getApparentType(objectType), IndexKind.Number) && isTypeAssignableToKind(indexType, TypeFlags.NumberLike)) {
|
||||
const apparentObjectType = getApparentType(objectType);
|
||||
if (getIndexInfoOfType(apparentObjectType, IndexKind.Number) && isTypeAssignableToKind(indexType, TypeFlags.NumberLike)) {
|
||||
return type;
|
||||
}
|
||||
if (isGenericObjectType(objectType)) {
|
||||
const propertyName = getPropertyNameFromIndex(indexType, accessNode);
|
||||
if (propertyName) {
|
||||
const propertySymbol = forEachType(apparentObjectType, t => getPropertyOfType(t, propertyName));
|
||||
if (propertySymbol && getDeclarationModifierFlagsFromSymbol(propertySymbol) & ModifierFlags.NonPublicAccessibilityModifier) {
|
||||
error(accessNode, Diagnostics.Private_or_protected_member_0_cannot_be_accessed_on_a_type_parameter, unescapeLeadingUnderscores(propertyName));
|
||||
return errorType;
|
||||
}
|
||||
}
|
||||
}
|
||||
error(accessNode, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(objectType));
|
||||
return errorType;
|
||||
}
|
||||
|
||||
@@ -147,6 +147,12 @@ namespace ts {
|
||||
category: Diagnostics.Basic_Options,
|
||||
description: Diagnostics.Enable_incremental_compilation,
|
||||
},
|
||||
{
|
||||
name: "locale",
|
||||
type: "string",
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.The_locale_used_when_displaying_messages_to_the_user_e_g_en_us
|
||||
},
|
||||
];
|
||||
|
||||
/* @internal */
|
||||
@@ -698,12 +704,6 @@ namespace ts {
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files
|
||||
},
|
||||
{
|
||||
name: "locale",
|
||||
type: "string",
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.The_locale_used_when_displaying_messages_to_the_user_e_g_en_us
|
||||
},
|
||||
{
|
||||
name: "newLine",
|
||||
type: createMapFromTemplate({
|
||||
@@ -1171,7 +1171,7 @@ namespace ts {
|
||||
export interface ParsedBuildCommand {
|
||||
buildOptions: BuildOptions;
|
||||
projects: string[];
|
||||
errors: ReadonlyArray<Diagnostic>;
|
||||
errors: Diagnostic[];
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
|
||||
@@ -2975,6 +2975,10 @@
|
||||
"category": "Error",
|
||||
"code": 4104
|
||||
},
|
||||
"Private or protected member '{0}' cannot be accessed on a type parameter.": {
|
||||
"category": "Error",
|
||||
"code": 4105
|
||||
},
|
||||
|
||||
"The current host does not support the '{0}' option.": {
|
||||
"category": "Error",
|
||||
|
||||
@@ -725,7 +725,8 @@ namespace ts {
|
||||
fileExists: f => host.fileExists(f),
|
||||
directoryExists: host.directoryExists && (f => host.directoryExists!(f)),
|
||||
useCaseSensitiveFileNames: () => host.useCaseSensitiveFileNames(),
|
||||
getProgramBuildInfo: returnUndefined
|
||||
getProgramBuildInfo: returnUndefined,
|
||||
getSourceFileFromReference: returnUndefined,
|
||||
};
|
||||
emitFiles(
|
||||
notImplementedResolver,
|
||||
|
||||
@@ -1487,8 +1487,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
/**
|
||||
* LSHost may load a module from a global cache of typings.
|
||||
* This is the minumum code needed to expose that functionality; the rest is in LSHost.
|
||||
* A host may load a module from a global cache of typings.
|
||||
* This is the minumum code needed to expose that functionality; the rest is in the host.
|
||||
*/
|
||||
/* @internal */
|
||||
export function loadModuleFromGlobalCache(moduleName: string, projectName: string | undefined, compilerOptions: CompilerOptions, host: ModuleResolutionHost, globalCache: string): ResolvedModuleWithFailedLookupLocations {
|
||||
|
||||
@@ -1442,7 +1442,8 @@ namespace ts {
|
||||
},
|
||||
...(host.directoryExists ? { directoryExists: f => host.directoryExists!(f) } : {}),
|
||||
useCaseSensitiveFileNames: () => host.useCaseSensitiveFileNames(),
|
||||
getProgramBuildInfo: () => program.getProgramBuildInfo && program.getProgramBuildInfo()
|
||||
getProgramBuildInfo: () => program.getProgramBuildInfo && program.getProgramBuildInfo(),
|
||||
getSourceFileFromReference: (file, ref) => program.getSourceFileFromReference(file, ref),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2127,7 +2128,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
/** This should have similar behavior to 'processSourceFile' without diagnostics or mutation. */
|
||||
function getSourceFileFromReference(referencingFile: SourceFile, ref: FileReference): SourceFile | undefined {
|
||||
function getSourceFileFromReference(referencingFile: SourceFile | UnparsedSource, ref: FileReference): SourceFile | undefined {
|
||||
return getSourceFileFromReferenceWorker(resolveTripleslashReference(ref.fileName, referencingFile.fileName), fileName => filesByName.get(toPath(fileName)) || undefined);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -330,7 +330,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export const ignoredPaths = ["/node_modules/.", "/.git"];
|
||||
export const ignoredPaths = ["/node_modules/.", "/.git", "/.#"];
|
||||
|
||||
/*@internal*/
|
||||
export interface RecursiveDirectoryWatcherHost {
|
||||
|
||||
@@ -348,7 +348,7 @@ namespace ts {
|
||||
function collectReferences(sourceFile: SourceFile | UnparsedSource, ret: Map<SourceFile>) {
|
||||
if (noResolve || (!isUnparsedSource(sourceFile) && isSourceFileJS(sourceFile))) return ret;
|
||||
forEach(sourceFile.referencedFiles, f => {
|
||||
const elem = tryResolveScriptReference(host, sourceFile, f);
|
||||
const elem = host.getSourceFileFromReference(sourceFile, f);
|
||||
if (elem) {
|
||||
ret.set("" + getOriginalNodeId(elem), elem);
|
||||
}
|
||||
@@ -1036,19 +1036,25 @@ namespace ts {
|
||||
/*body*/ undefined
|
||||
));
|
||||
if (clean && resolver.isExpandoFunctionDeclaration(input)) {
|
||||
const declarations = mapDefined(resolver.getPropertiesOfContainerFunction(input), p => {
|
||||
const props = resolver.getPropertiesOfContainerFunction(input);
|
||||
const fakespace = createModuleDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, clean.name || createIdentifier("_default"), createModuleBlock([]), NodeFlags.Namespace);
|
||||
fakespace.flags ^= NodeFlags.Synthesized; // unset synthesized so it is usable as an enclosing declaration
|
||||
fakespace.parent = enclosingDeclaration as SourceFile | NamespaceDeclaration;
|
||||
fakespace.locals = createSymbolTable(props);
|
||||
fakespace.symbol = props[0].parent!;
|
||||
const declarations = mapDefined(props, p => {
|
||||
if (!isPropertyAccessExpression(p.valueDeclaration)) {
|
||||
return undefined;
|
||||
}
|
||||
getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(p.valueDeclaration);
|
||||
const type = resolver.createTypeOfDeclaration(p.valueDeclaration, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker);
|
||||
const type = resolver.createTypeOfDeclaration(p.valueDeclaration, fakespace, declarationEmitNodeBuilderFlags, symbolTracker);
|
||||
getSymbolAccessibilityDiagnostic = oldDiag;
|
||||
const varDecl = createVariableDeclaration(unescapeLeadingUnderscores(p.escapedName), type, /*initializer*/ undefined);
|
||||
return createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([varDecl]));
|
||||
});
|
||||
const namespaceDecl = createModuleDeclaration(/*decorators*/ undefined, ensureModifiers(input, isPrivate), input.name!, createModuleBlock(declarations), NodeFlags.Namespace);
|
||||
|
||||
if (!hasModifier(clean, ModifierFlags.ExportDefault)) {
|
||||
if (!hasModifier(clean, ModifierFlags.Default)) {
|
||||
return [clean, namespaceDecl];
|
||||
}
|
||||
|
||||
|
||||
@@ -172,6 +172,7 @@ namespace ts {
|
||||
traceResolution?: boolean;
|
||||
/* @internal */ diagnostics?: boolean;
|
||||
/* @internal */ extendedDiagnostics?: boolean;
|
||||
/* @internal */ locale?: string;
|
||||
|
||||
[option: string]: CompilerOptionsValue | undefined;
|
||||
}
|
||||
@@ -1461,7 +1462,8 @@ namespace ts {
|
||||
const refStatus = getUpToDateStatus(state, parseConfigFile(state, resolvedRef, resolvedRefPath), resolvedRefPath);
|
||||
|
||||
// Its a circular reference ignore the status of this project
|
||||
if (refStatus.type === UpToDateStatusType.ComputingUpstream) {
|
||||
if (refStatus.type === UpToDateStatusType.ComputingUpstream ||
|
||||
refStatus.type === UpToDateStatusType.ContainerOnly) { // Container only ignore this project
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
+11
-7
@@ -2975,7 +2975,7 @@ namespace ts {
|
||||
// For testing purposes only.
|
||||
/* @internal */ structureIsReused?: StructureIsReused;
|
||||
|
||||
/* @internal */ getSourceFileFromReference(referencingFile: SourceFile, ref: FileReference): SourceFile | undefined;
|
||||
/* @internal */ getSourceFileFromReference(referencingFile: SourceFile | UnparsedSource, ref: FileReference): SourceFile | undefined;
|
||||
/* @internal */ getLibFileFromReference(ref: FileReference): SourceFile | undefined;
|
||||
|
||||
/** Given a source file, get the name of the package it was imported from. */
|
||||
@@ -4089,19 +4089,20 @@ namespace ts {
|
||||
MarkerType = 1 << 13, // Marker type used for variance probing
|
||||
JSLiteral = 1 << 14, // Object type declared in JS - disables errors on read/write of nonexisting members
|
||||
FreshLiteral = 1 << 15, // Fresh object literal
|
||||
ArrayLiteral = 1 << 16, // Originates in an array literal
|
||||
/* @internal */
|
||||
PrimitiveUnion = 1 << 16, // Union of only primitive types
|
||||
PrimitiveUnion = 1 << 17, // Union of only primitive types
|
||||
/* @internal */
|
||||
ContainsWideningType = 1 << 17, // Type is or contains undefined or null widening type
|
||||
ContainsWideningType = 1 << 18, // Type is or contains undefined or null widening type
|
||||
/* @internal */
|
||||
ContainsObjectLiteral = 1 << 18, // Type is or contains object literal type
|
||||
ContainsObjectOrArrayLiteral = 1 << 19, // Type is or contains object literal type
|
||||
/* @internal */
|
||||
NonInferrableType = 1 << 19, // Type is or contains anyFunctionType or silentNeverType
|
||||
NonInferrableType = 1 << 20, // Type is or contains anyFunctionType or silentNeverType
|
||||
ClassOrInterface = Class | Interface,
|
||||
/* @internal */
|
||||
RequiresWidening = ContainsWideningType | ContainsObjectLiteral,
|
||||
RequiresWidening = ContainsWideningType | ContainsObjectOrArrayLiteral,
|
||||
/* @internal */
|
||||
PropagatingFlags = ContainsWideningType | ContainsObjectLiteral | NonInferrableType
|
||||
PropagatingFlags = ContainsWideningType | ContainsObjectOrArrayLiteral | NonInferrableType
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -4154,6 +4155,8 @@ namespace ts {
|
||||
export interface TypeReference extends ObjectType {
|
||||
target: GenericType; // Type reference target
|
||||
typeArguments?: ReadonlyArray<Type>; // Type reference type arguments (undefined if none)
|
||||
/* @internal */
|
||||
literalType?: TypeReference; // Clone of type with ObjectFlags.ArrayLiteral set
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -5396,6 +5399,7 @@ namespace ts {
|
||||
|
||||
writeFile: WriteFileCallback;
|
||||
getProgramBuildInfo(): ProgramBuildInfo | undefined;
|
||||
getSourceFileFromReference: Program["getSourceFileFromReference"];
|
||||
}
|
||||
|
||||
export interface TransformationContext {
|
||||
|
||||
@@ -2611,13 +2611,6 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function tryResolveScriptReference(host: ScriptReferenceHost, sourceFile: SourceFile | UnparsedSource, reference: FileReference) {
|
||||
if (!host.getCompilerOptions().noResolve) {
|
||||
const referenceFileName = isRootedDiskPath(reference.fileName) ? reference.fileName : combinePaths(getDirectoryPath(sourceFile.fileName), reference.fileName);
|
||||
return host.getSourceFile(referenceFileName);
|
||||
}
|
||||
}
|
||||
|
||||
export function getAncestor(node: Node | undefined, kind: SyntaxKind): Node | undefined {
|
||||
while (node) {
|
||||
if (node.kind === kind) {
|
||||
|
||||
@@ -1177,7 +1177,9 @@ Actual: ${stringify(fullActual)}`);
|
||||
public verifyRenameLocations(startRanges: ArrayOrSingle<Range>, options: FourSlashInterface.RenameLocationsOptions) {
|
||||
const { findInStrings = false, findInComments = false, ranges = this.getRanges(), providePrefixAndSuffixTextForRename = true } = ts.isArray(options) ? { findInStrings: false, findInComments: false, ranges: options, providePrefixAndSuffixTextForRename: true } : options;
|
||||
|
||||
for (const startRange of toArray(startRanges)) {
|
||||
const _startRanges = toArray(startRanges);
|
||||
assert(_startRanges.length);
|
||||
for (const startRange of _startRanges) {
|
||||
this.goToRangeStart(startRange);
|
||||
|
||||
const renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition);
|
||||
@@ -2731,6 +2733,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
|
||||
public verifyRangesAreOccurrences(isWriteAccess?: boolean, ranges?: Range[]) {
|
||||
ranges = ranges || this.getRanges();
|
||||
assert(ranges.length);
|
||||
for (const r of ranges) {
|
||||
this.goToRangeStart(r);
|
||||
this.verifyOccurrencesAtPositionListCount(ranges.length);
|
||||
@@ -2761,6 +2764,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
|
||||
public verifyRangesAreDocumentHighlights(ranges: Range[] | undefined, options: FourSlashInterface.VerifyDocumentHighlightsOptions | undefined) {
|
||||
ranges = ranges || this.getRanges();
|
||||
assert(ranges.length);
|
||||
const fileNames = options && options.filesToSearch || unique(ranges, range => range.fileName);
|
||||
for (const range of ranges) {
|
||||
this.goToRangeStart(range);
|
||||
@@ -2930,7 +2934,9 @@ Actual: ${stringify(fullActual)}`);
|
||||
}
|
||||
|
||||
public noMoveToNewFile() {
|
||||
for (const range of this.getRanges()) {
|
||||
const ranges = this.getRanges();
|
||||
assert(ranges.length);
|
||||
for (const range of ranges) {
|
||||
for (const refactor of this.getApplicableRefactors(range, { allowTextChangesInNewFiles: true })) {
|
||||
if (refactor.name === "Move to a new file") {
|
||||
ts.Debug.fail("Did not expect to get 'move to a new file' refactor");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
type TestRunnerKind = CompilerTestKind | FourslashTestKind | "project" | "rwc" | "test262" | "user" | "dt";
|
||||
type TestRunnerKind = CompilerTestKind | FourslashTestKind | "project" | "rwc" | "test262" | "user" | "dt" | "docker";
|
||||
type CompilerTestKind = "conformance" | "compiler";
|
||||
type FourslashTestKind = "fourslash" | "fourslash-shims" | "fourslash-shims-pp" | "fourslash-server";
|
||||
|
||||
|
||||
@@ -952,7 +952,7 @@ namespace ts.server {
|
||||
this.externalFiles = this.getExternalFiles();
|
||||
enumerateInsertsAndDeletes<string, string>(this.externalFiles, oldExternalFiles, getStringComparer(!this.useCaseSensitiveFileNames()),
|
||||
// Ensure a ScriptInfo is created for new external files. This is performed indirectly
|
||||
// by the LSHost for files in the program when the program is retrieved above but
|
||||
// by the host for files in the program when the program is retrieved above but
|
||||
// the program doesn't contain external files so this must be done explicitly.
|
||||
inserted => {
|
||||
const scriptInfo = this.projectService.getOrCreateScriptInfoNotOpenedByClient(inserted, this.currentDirectory, this.directoryStructureHost)!;
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
# How does TypeScript formatting work?
|
||||
|
||||
To format code you need to have a formatting context and a `SourceFile`. The formatting context contains
|
||||
all user settings like tab size, newline character, etc.
|
||||
|
||||
The end result of formatting is represented by TextChange objects which hold the new string content, and
|
||||
the text to replace it with.
|
||||
|
||||
```ts
|
||||
export interface TextChange {
|
||||
span: TextSpan; // start, length
|
||||
newText: string;
|
||||
}
|
||||
```
|
||||
|
||||
## Internals
|
||||
|
||||
Most of the exposed APIs internally are `format*` and they all set up and configure `formatSpan` which could be considered the root call for formatting. Span in this case refers to the range of
|
||||
the sourcefile which should be formatted.
|
||||
|
||||
The formatSpan then uses a scanner (either with or without JSX support) which starts at the highest
|
||||
node the covers the span of text and recurses down through the node's children.
|
||||
|
||||
As it recurses, `processNode` is called on the children setting the indentation is decided and passed
|
||||
through into each of that node's children.
|
||||
|
||||
The meat of formatting decisions is made via `processPair`, the pair here being the current node and the previous node. `processPair` which mutates the formatting context to represent the current place in the scanner and requests a set of rules which can be applied to the items via `createRulesMap`.
|
||||
|
||||
There are a lot of rules, which you can find in [rules.ts](./rules.ts) each one has a left and right reference to nodes or token ranges and note of what action should be applied by the formatter.
|
||||
|
||||
### Where is this used?
|
||||
|
||||
The formatter is used mainly from any language service operation that inserts or modifies code. The formatter is not exported publicly, and so all usage can only come through the language server.
|
||||
@@ -108,7 +108,7 @@ namespace ts.GoToDefinition {
|
||||
export function getReferenceAtPosition(sourceFile: SourceFile, position: number, program: Program): { fileName: string, file: SourceFile } | undefined {
|
||||
const referencePath = findReferenceInPosition(sourceFile.referencedFiles, position);
|
||||
if (referencePath) {
|
||||
const file = tryResolveScriptReference(program, sourceFile, referencePath);
|
||||
const file = program.getSourceFileFromReference(sourceFile, referencePath);
|
||||
return file && { fileName: referencePath.fileName, file };
|
||||
}
|
||||
|
||||
|
||||
@@ -143,6 +143,7 @@ class CompilerTest {
|
||||
this.tsConfigFiles = [];
|
||||
if (testCaseContent.tsConfig) {
|
||||
assert.equal(testCaseContent.tsConfig.fileNames.length, 0, `list of files in tsconfig is not currently supported`);
|
||||
assert.equal(testCaseContent.tsConfig.raw.exclude, undefined, `exclude in tsconfig is not currently supported`);
|
||||
|
||||
tsConfigOptions = ts.cloneCompilerOptions(testCaseContent.tsConfig.options);
|
||||
this.tsConfigFiles.push(this.createHarnessTestFile(testCaseContent.tsConfigFileUnitData!, rootDir, ts.combinePaths(rootDir, tsConfigOptions.configFilePath!)));
|
||||
|
||||
@@ -106,6 +106,81 @@ ${stripAbsoluteImportPaths(result.stderr.toString().replace(/\r\n/g, "\n"))}`;
|
||||
}
|
||||
}
|
||||
|
||||
class DockerfileRunner extends ExternalCompileRunnerBase {
|
||||
readonly testDir = "tests/cases/docker/";
|
||||
kind(): TestRunnerKind {
|
||||
return "docker";
|
||||
}
|
||||
initializeTests(): void {
|
||||
// Read in and evaluate the test list
|
||||
const testList = this.tests && this.tests.length ? this.tests : this.enumerateTestFiles();
|
||||
|
||||
// tslint:disable-next-line:no-this-assignment
|
||||
const cls = this;
|
||||
describe(`${this.kind()} code samples`, function(this: Mocha.ISuiteCallbackContext) {
|
||||
this.timeout(cls.timeout); // 20 minutes
|
||||
before(() => {
|
||||
cls.exec("docker", ["build", ".", "-t", "typescript/typescript"], { cwd: Harness.IO.getWorkspaceRoot() }); // cached because workspace is hashed to determine cacheability
|
||||
});
|
||||
for (const test of testList) {
|
||||
const directory = typeof test === "string" ? test : test.file;
|
||||
const cwd = path.join(Harness.IO.getWorkspaceRoot(), cls.testDir, directory);
|
||||
it(`should build ${directory} successfully`, () => {
|
||||
const imageName = `tstest/${directory}`;
|
||||
cls.exec("docker", ["build", "--no-cache", ".", "-t", imageName], { cwd }); // --no-cache so the latest version of the repos referenced is always fetched
|
||||
const cp: typeof import("child_process") = require("child_process");
|
||||
Harness.Baseline.runBaseline(`${cls.kind()}/${directory}.log`, cls.report(cp.spawnSync(`docker`, ["run", imageName], { cwd, timeout: cls.timeout, shell: true })));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private timeout = 1_200_000; // 20 minutes;
|
||||
private exec(command: string, args: string[], options: { cwd: string, timeout?: number }): void {
|
||||
const cp: typeof import("child_process") = require("child_process");
|
||||
const stdio = isWorker ? "pipe" : "inherit";
|
||||
const res = cp.spawnSync(command, args, { timeout: this.timeout, shell: true, stdio, ...options });
|
||||
if (res.status !== 0) {
|
||||
throw new Error(`${command} ${args.join(" ")} for ${options.cwd} failed: ${res.stderr && res.stderr.toString()}`);
|
||||
}
|
||||
}
|
||||
report(result: ExecResult) {
|
||||
// tslint:disable-next-line:no-null-keyword
|
||||
return result.status === 0 && !result.stdout.length && !result.stderr.length ? null : `Exit Code: ${result.status}
|
||||
Standard output:
|
||||
${sanitizeDockerfileOutput(result.stdout.toString())}
|
||||
|
||||
|
||||
Standard error:
|
||||
${sanitizeDockerfileOutput(result.stderr.toString())}`;
|
||||
}
|
||||
}
|
||||
|
||||
function sanitizeDockerfileOutput(result: string): string {
|
||||
return stripAbsoluteImportPaths(sanitizeTimestamps(stripRushStageNumbers(stripANSIEscapes(normalizeNewlines(result)))));
|
||||
}
|
||||
|
||||
function normalizeNewlines(result: string): string {
|
||||
return result.replace(/\r\n/g, "\n");
|
||||
}
|
||||
|
||||
function stripANSIEscapes(result: string): string {
|
||||
return result.replace(/\x1b\[[0-9;]*[a-zA-Z]/g, "");
|
||||
}
|
||||
|
||||
function stripRushStageNumbers(result: string): string {
|
||||
return result.replace(/\d+ of \d+:/g, "XX of XX:");
|
||||
}
|
||||
|
||||
function sanitizeTimestamps(result: string): string {
|
||||
return result.replace(/\[\d?\d:\d\d:\d\d (A|P)M\]/g, "[XX:XX:XX XM]")
|
||||
.replace(/\d+(\.\d+)? seconds?/g, "? seconds")
|
||||
.replace(/\d+(\.\d+)? minutes?/g, "")
|
||||
.replace(/\d+(\.\d+)?s/g, "?s")
|
||||
.replace(/\d+.\d+.\d+-insiders.\d\d\d\d\d\d\d\d/g, "X.X.X-insiders.xxxxxxxx");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Import types and some other error messages use absolute paths in errors as they have no context to be written relative to;
|
||||
* This is problematic for error baselines, so we grep for them and strip them out.
|
||||
|
||||
@@ -40,6 +40,8 @@ function createRunner(kind: TestRunnerKind): RunnerBase {
|
||||
return new UserCodeRunner();
|
||||
case "dt":
|
||||
return new DefinitelyTypedRunner();
|
||||
case "docker":
|
||||
return new DockerfileRunner();
|
||||
}
|
||||
return ts.Debug.fail(`Unknown runner kind ${kind}`);
|
||||
}
|
||||
@@ -172,6 +174,9 @@ function handleTestConfig() {
|
||||
case "dt":
|
||||
runners.push(new DefinitelyTypedRunner());
|
||||
break;
|
||||
case "docker":
|
||||
runners.push(new DockerfileRunner());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -194,6 +199,7 @@ function handleTestConfig() {
|
||||
// CRON-only tests
|
||||
if (process.env.TRAVIS_EVENT_TYPE === "cron") {
|
||||
runners.push(new UserCodeRunner());
|
||||
runners.push(new DockerfileRunner());
|
||||
}
|
||||
}
|
||||
if (runUnitTests === undefined) {
|
||||
|
||||
@@ -90,6 +90,7 @@
|
||||
"unittests/services/textChanges.ts",
|
||||
"unittests/services/transpile.ts",
|
||||
"unittests/tsbuild/amdModulesWithOut.ts",
|
||||
"unittests/tsbuild/containerOnlyReferenced.ts",
|
||||
"unittests/tsbuild/emptyFiles.ts",
|
||||
"unittests/tsbuild/graphOrdering.ts",
|
||||
"unittests/tsbuild/inferredTypeFromTransitiveModule.ts",
|
||||
|
||||
@@ -486,6 +486,16 @@ namespace ts {
|
||||
});
|
||||
});
|
||||
|
||||
it("parse build with --locale en-us", () => {
|
||||
// --lib es6 0.ts
|
||||
assertParseResult(["--locale", "en-us", "src"],
|
||||
{
|
||||
errors: [],
|
||||
projects: ["src"],
|
||||
buildOptions: { locale: "en-us" }
|
||||
});
|
||||
});
|
||||
|
||||
it("parse build with --tsBuildInfoFile", () => {
|
||||
// --lib es6 0.ts
|
||||
assertParseResult(["--tsBuildInfoFile", "build.tsbuildinfo", "tests"],
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
namespace ts {
|
||||
describe("unittests:: tsbuild:: when containerOnly project is referenced", () => {
|
||||
let projFs: vfs.FileSystem;
|
||||
before(() => {
|
||||
projFs = loadProjectFromDisk("tests/projects/containerOnlyReferenced");
|
||||
});
|
||||
|
||||
after(() => {
|
||||
projFs = undefined!; // Release the contents
|
||||
});
|
||||
|
||||
function outputs(folder: string) {
|
||||
return [
|
||||
`${folder}/index.js`,
|
||||
`${folder}/index.d.ts`,
|
||||
`${folder}/tsconfig.tsbuildinfo`
|
||||
];
|
||||
}
|
||||
|
||||
it("verify that subsequent builds after initial build doesnt build anything", () => {
|
||||
const fs = projFs.shadow();
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
createSolutionBuilder(host, ["/src"], { verbose: true }).build();
|
||||
host.assertDiagnosticMessages(
|
||||
getExpectedDiagnosticForProjectsInBuild("src/src/folder/tsconfig.json", "src/src/folder2/tsconfig.json", "src/src/tsconfig.json", "src/tests/tsconfig.json", "src/tsconfig.json"),
|
||||
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/src/folder/tsconfig.json", "src/src/folder/index.js"],
|
||||
[Diagnostics.Building_project_0, "/src/src/folder/tsconfig.json"],
|
||||
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/src/folder2/tsconfig.json", "src/src/folder2/index.js"],
|
||||
[Diagnostics.Building_project_0, "/src/src/folder2/tsconfig.json"],
|
||||
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/tests/tsconfig.json", "src/tests/index.js"],
|
||||
[Diagnostics.Building_project_0, "/src/tests/tsconfig.json"],
|
||||
);
|
||||
verifyOutputsPresent(fs, [
|
||||
...outputs("/src/src/folder"),
|
||||
...outputs("/src/src/folder2"),
|
||||
...outputs("/src/tests"),
|
||||
]);
|
||||
host.clearDiagnostics();
|
||||
createSolutionBuilder(host, ["/src"], { verbose: true }).build();
|
||||
host.assertDiagnosticMessages(
|
||||
getExpectedDiagnosticForProjectsInBuild("src/src/folder/tsconfig.json", "src/src/folder2/tsconfig.json", "src/src/tsconfig.json", "src/tests/tsconfig.json", "src/tsconfig.json"),
|
||||
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, "src/src/folder/tsconfig.json", "src/src/folder/index.ts", "src/src/folder/index.js"],
|
||||
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, "src/src/folder2/tsconfig.json", "src/src/folder2/index.ts", "src/src/folder2/index.js"],
|
||||
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, "src/tests/tsconfig.json", "src/tests/index.ts", "src/tests/index.js"],
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -10,7 +10,6 @@ namespace ts {
|
||||
});
|
||||
|
||||
it("verify that it builds correctly", () => {
|
||||
const projFs = loadProjectFromDisk("tests/projects/projectReferenceWithRootDirInParent");
|
||||
const allExpectedOutputs = [
|
||||
"/src/dist/other/other.js", "/src/dist/other/other.d.ts",
|
||||
"/src/dist/main/a.js", "/src/dist/main/a.d.ts",
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace ts.tscWatch {
|
||||
root.content = `import {x} from "f2"`;
|
||||
host.reloadFS(files);
|
||||
|
||||
// trigger synchronization to make sure that LSHost will try to find 'f2' module on disk
|
||||
// trigger synchronization to make sure that system will try to find 'f2' module on disk
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
|
||||
// ensure file has correct number of errors after edit
|
||||
|
||||
@@ -131,10 +131,10 @@ namespace ts.projectSystem {
|
||||
verifyImportedDiagnostics();
|
||||
callsTrackingHost.verifyNoHostCalls();
|
||||
|
||||
// trigger synchronization to make sure that LSHost will try to find 'f2' module on disk
|
||||
// trigger synchronization to make sure that the host will try to find 'f2' module on disk
|
||||
editContent(`import {x} from "f2"`);
|
||||
try {
|
||||
// trigger synchronization to make sure that LSHost will try to find 'f2' module on disk
|
||||
// trigger synchronization to make sure that the host will try to find 'f2' module on disk
|
||||
verifyImportedDiagnostics();
|
||||
assert.isTrue(false, `should not find file '${imported.path}'`);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace ts.projectSystem {
|
||||
return resolutionTrace;
|
||||
}
|
||||
|
||||
describe("unittests:: tsserver:: resolutionCache:: tsserverProjectSystem extra resolution pass in lshost", () => {
|
||||
describe("unittests:: tsserver:: resolutionCache:: tsserverProjectSystem extra resolution pass in server host", () => {
|
||||
it("can load typings that are proper modules", () => {
|
||||
const file1 = {
|
||||
path: "/a/b/app.js",
|
||||
|
||||
@@ -171,33 +171,37 @@ namespace ts.projectSystem {
|
||||
path: `${projectFolder}/node_modules/.cache/someFile.d.ts`,
|
||||
content: ""
|
||||
};
|
||||
host.ensureFileOrFolder(nodeModulesIgnoredFileFromIgnoreDirectory);
|
||||
host.checkTimeoutQueueLength(0);
|
||||
verifyProject();
|
||||
|
||||
const nodeModulesIgnoredFile: File = {
|
||||
path: `${projectFolder}/node_modules/.cacheFile.ts`,
|
||||
content: ""
|
||||
};
|
||||
host.ensureFileOrFolder(nodeModulesIgnoredFile);
|
||||
host.checkTimeoutQueueLength(0);
|
||||
verifyProject();
|
||||
|
||||
const gitIgnoredFileFromIgnoreDirectory: File = {
|
||||
path: `${projectFolder}/.git/someFile.d.ts`,
|
||||
content: ""
|
||||
};
|
||||
host.ensureFileOrFolder(gitIgnoredFileFromIgnoreDirectory);
|
||||
host.checkTimeoutQueueLength(0);
|
||||
verifyProject();
|
||||
|
||||
const gitIgnoredFile: File = {
|
||||
path: `${projectFolder}/.gitCache.d.ts`,
|
||||
content: ""
|
||||
};
|
||||
host.ensureFileOrFolder(gitIgnoredFile);
|
||||
host.checkTimeoutQueueLength(0);
|
||||
verifyProject();
|
||||
const emacsIgnoredFileFromIgnoreDirectory: File = {
|
||||
path: `${projectFolder}/src/.#field.ts`,
|
||||
content: ""
|
||||
};
|
||||
|
||||
[
|
||||
nodeModulesIgnoredFileFromIgnoreDirectory,
|
||||
nodeModulesIgnoredFile,
|
||||
gitIgnoredFileFromIgnoreDirectory,
|
||||
gitIgnoredFile,
|
||||
emacsIgnoredFileFromIgnoreDirectory
|
||||
].forEach(ignoredEntity => {
|
||||
host.ensureFileOrFolder(ignoredEntity);
|
||||
host.checkTimeoutQueueLength(0);
|
||||
verifyProject();
|
||||
});
|
||||
|
||||
function verifyProject() {
|
||||
checkWatchedDirectories(host, emptyArray, /*recursive*/ true);
|
||||
|
||||
@@ -186,6 +186,10 @@ namespace ts {
|
||||
// Update to pretty if host supports it
|
||||
updateReportDiagnostic(buildOptions);
|
||||
|
||||
if (buildOptions.locale) {
|
||||
validateLocaleAndSetLanguage(buildOptions.locale, sys, errors);
|
||||
}
|
||||
|
||||
if (errors.length > 0) {
|
||||
errors.forEach(reportDiagnostic);
|
||||
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||
|
||||
Reference in New Issue
Block a user