Merge branch 'master' into configFileDiag

This commit is contained in:
Sheetal Nandi
2017-10-10 11:12:07 -07:00
152 changed files with 3474 additions and 542 deletions
+30 -23
View File
@@ -230,6 +230,10 @@ namespace ts {
// Should not be called on a declaration with a computed property name,
// unless it is a well known Symbol.
function getDeclarationName(node: Declaration): __String {
if (node.kind === SyntaxKind.ExportAssignment) {
return (<ExportAssignment>node).isExportEquals ? InternalSymbolName.ExportEquals : InternalSymbolName.Default;
}
const name = getNameOfDeclaration(node);
if (name) {
if (isAmbientModule(node)) {
@@ -261,8 +265,6 @@ namespace ts {
return InternalSymbolName.Index;
case SyntaxKind.ExportDeclaration:
return InternalSymbolName.ExportStar;
case SyntaxKind.ExportAssignment:
return (<ExportAssignment>node).isExportEquals ? InternalSymbolName.ExportEquals : InternalSymbolName.Default;
case SyntaxKind.BinaryExpression:
if (getSpecialPropertyAssignmentKind(node as BinaryExpression) === SpecialPropertyAssignmentKind.ModuleExports) {
// module.exports = ...
@@ -2144,7 +2146,7 @@ namespace ts {
// falls through
case SyntaxKind.JSDocPropertyTag:
const propTag = node as JSDocPropertyLikeTag;
const flags = propTag.isBracketed || propTag.typeExpression.type.kind === SyntaxKind.JSDocOptionalType ?
const flags = propTag.isBracketed || propTag.typeExpression && propTag.typeExpression.type.kind === SyntaxKind.JSDocOptionalType ?
SymbolFlags.Property | SymbolFlags.Optional :
SymbolFlags.Property;
return declareSymbolAndAddToSymbolTable(propTag, flags, SymbolFlags.PropertyExcludes);
@@ -2269,16 +2271,13 @@ namespace ts {
function isExportsOrModuleExportsOrAlias(node: Node): boolean {
return isExportsIdentifier(node) ||
isModuleExportsPropertyAccessExpression(node) ||
isNameOfExportsOrModuleExportsAliasDeclaration(node);
isIdentifier(node) && isNameOfExportsOrModuleExportsAliasDeclaration(node);
}
function isNameOfExportsOrModuleExportsAliasDeclaration(node: Node) {
if (isIdentifier(node)) {
const symbol = lookupSymbolForName(node.escapedText);
return symbol && symbol.valueDeclaration && isVariableDeclaration(symbol.valueDeclaration) &&
symbol.valueDeclaration.initializer && isExportsOrModuleExportsOrAliasOrAssignment(symbol.valueDeclaration.initializer);
}
return false;
function isNameOfExportsOrModuleExportsAliasDeclaration(node: Identifier): boolean {
const symbol = lookupSymbolForName(node.escapedText);
return symbol && symbol.valueDeclaration && isVariableDeclaration(symbol.valueDeclaration) &&
symbol.valueDeclaration.initializer && isExportsOrModuleExportsOrAliasOrAssignment(symbol.valueDeclaration.initializer);
}
function isExportsOrModuleExportsOrAliasOrAssignment(node: Node): boolean {
@@ -2352,20 +2351,22 @@ namespace ts {
// Look up the function in the local scope, since prototype assignments should
// follow the function declaration
const leftSideOfAssignment = node.left as PropertyAccessExpression;
const target = leftSideOfAssignment.expression as Identifier;
const target = leftSideOfAssignment.expression;
// Fix up parent pointers since we're going to use these nodes before we bind into them
leftSideOfAssignment.parent = node;
target.parent = leftSideOfAssignment;
if (isIdentifier(target)) {
// Fix up parent pointers since we're going to use these nodes before we bind into them
leftSideOfAssignment.parent = node;
target.parent = leftSideOfAssignment;
if (isNameOfExportsOrModuleExportsAliasDeclaration(target)) {
// This can be an alias for the 'exports' or 'module.exports' names, e.g.
// var util = module.exports;
// util.property = function ...
bindExportsPropertyAssignment(node);
}
else {
bindPropertyAssignment(target.escapedText, leftSideOfAssignment, /*isPrototypeProperty*/ false);
if (isNameOfExportsOrModuleExportsAliasDeclaration(target)) {
// This can be an alias for the 'exports' or 'module.exports' names, e.g.
// var util = module.exports;
// util.property = function ...
bindExportsPropertyAssignment(node);
}
else {
bindPropertyAssignment(target.escapedText, leftSideOfAssignment, /*isPrototypeProperty*/ false);
}
}
}
@@ -2697,6 +2698,12 @@ namespace ts {
if (expression.kind === SyntaxKind.ImportKeyword) {
transformFlags |= TransformFlags.ContainsDynamicImport;
// A dynamic 'import()' call that contains a lexical 'this' will
// require a captured 'this' when emitting down-level.
if (subtreeFlags & TransformFlags.ContainsLexicalThis) {
transformFlags |= TransformFlags.ContainsCapturedLexicalThis;
}
}
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
+110 -27
View File
@@ -503,6 +503,12 @@ namespace ts {
Inferential = 2, // Inferential typing
}
const enum CallbackCheck {
None,
Bivariant,
Strict,
}
const builtinGlobals = createSymbolTable();
builtinGlobals.set(undefinedSymbol.escapedName, undefinedSymbol);
@@ -902,6 +908,7 @@ namespace ts {
const originalLocation = location; // needed for did-you-mean error reporting, which gathers candidates starting from the original location
let result: Symbol;
let lastLocation: Node;
let lastNonBlockLocation: Node;
let propertyWithInvalidInitializer: Node;
const errorLocation = location;
let grandparent: Node;
@@ -1120,6 +1127,9 @@ namespace ts {
}
break;
}
if (location.kind !== SyntaxKind.Block) {
lastNonBlockLocation = location;
}
lastLocation = location;
location = location.parent;
}
@@ -1127,7 +1137,7 @@ namespace ts {
// We just climbed up parents looking for the name, meaning that we started in a descendant node of `lastLocation`.
// If `result === lastLocation.symbol`, that means that we are somewhere inside `lastLocation` looking up a name, and resolving to `lastLocation` itself.
// That means that this is a self-reference of `lastLocation`, and shouldn't count this when considering whether `lastLocation` is used.
if (isUse && result && nameNotFoundMessage && noUnusedIdentifiers && result !== lastLocation.symbol) {
if (isUse && result && nameNotFoundMessage && noUnusedIdentifiers && result !== lastNonBlockLocation.symbol) {
result.isReferenced = true;
}
@@ -8510,7 +8520,7 @@ namespace ts {
function isSignatureAssignableTo(source: Signature,
target: Signature,
ignoreReturnTypes: boolean): boolean {
return compareSignaturesRelated(source, target, /*checkAsCallback*/ false, ignoreReturnTypes, /*reportErrors*/ false,
return compareSignaturesRelated(source, target, CallbackCheck.None, ignoreReturnTypes, /*reportErrors*/ false,
/*errorReporter*/ undefined, compareTypesAssignable) !== Ternary.False;
}
@@ -8521,7 +8531,7 @@ namespace ts {
*/
function compareSignaturesRelated(source: Signature,
target: Signature,
checkAsCallback: boolean,
callbackCheck: CallbackCheck,
ignoreReturnTypes: boolean,
reportErrors: boolean,
errorReporter: ErrorReporter,
@@ -8540,7 +8550,7 @@ namespace ts {
}
const kind = target.declaration ? target.declaration.kind : SyntaxKind.Unknown;
const strictVariance = strictFunctionTypes && kind !== SyntaxKind.MethodDeclaration &&
const strictVariance = !callbackCheck && strictFunctionTypes && kind !== SyntaxKind.MethodDeclaration &&
kind !== SyntaxKind.MethodSignature && kind !== SyntaxKind.Constructor;
let result = Ternary.True;
@@ -8582,8 +8592,8 @@ namespace ts {
const callbacks = sourceSig && targetSig && !sourceSig.typePredicate && !targetSig.typePredicate &&
(getFalsyFlags(sourceType) & TypeFlags.Nullable) === (getFalsyFlags(targetType) & TypeFlags.Nullable);
const related = callbacks ?
compareSignaturesRelated(targetSig, sourceSig, /*checkAsCallback*/ true, /*ignoreReturnTypes*/ false, reportErrors, errorReporter, compareTypes) :
!checkAsCallback && !strictVariance && compareTypes(sourceType, targetType, /*reportErrors*/ false) || compareTypes(targetType, sourceType, reportErrors);
compareSignaturesRelated(targetSig, sourceSig, strictVariance ? CallbackCheck.Strict : CallbackCheck.Bivariant, /*ignoreReturnTypes*/ false, reportErrors, errorReporter, compareTypes) :
!callbackCheck && !strictVariance && compareTypes(sourceType, targetType, /*reportErrors*/ false) || compareTypes(targetType, sourceType, reportErrors);
if (!related) {
if (reportErrors) {
errorReporter(Diagnostics.Types_of_parameters_0_and_1_are_incompatible,
@@ -8618,7 +8628,7 @@ namespace ts {
// When relating callback signatures, we still need to relate return types bi-variantly as otherwise
// the containing type wouldn't be co-variant. For example, interface Foo<T> { add(cb: () => T): void }
// wouldn't be co-variant for T without this rule.
result &= checkAsCallback && compareTypes(targetReturnType, sourceReturnType, /*reportErrors*/ false) ||
result &= callbackCheck === CallbackCheck.Bivariant && compareTypes(targetReturnType, sourceReturnType, /*reportErrors*/ false) ||
compareTypes(sourceReturnType, targetReturnType, reportErrors);
}
@@ -9062,6 +9072,13 @@ namespace ts {
(isTypeSubsetOf(globalObjectType, target) || (!isComparingJsxAttributes && isEmptyObjectType(target)))) {
return false;
}
if (target.flags & TypeFlags.Union) {
const discriminantType = findMatchingDiscriminantType(source, target as UnionType);
if (discriminantType) {
// check excess properties against discriminant type only, not the entire union
return hasExcessProperties(source, discriminantType, reportErrors);
}
}
for (const prop of getPropertiesOfObjectType(source)) {
if (!isKnownProperty(target, prop.escapedName, isComparingJsxAttributes)) {
if (reportErrors) {
@@ -9138,20 +9155,24 @@ namespace ts {
}
function findMatchingDiscriminantType(source: Type, target: UnionOrIntersectionType) {
let match: Type;
const sourceProperties = getPropertiesOfObjectType(source);
if (sourceProperties) {
for (const sourceProperty of sourceProperties) {
if (isDiscriminantProperty(target, sourceProperty.escapedName)) {
const sourceType = getTypeOfSymbol(sourceProperty);
for (const type of target.types) {
const targetType = getTypeOfPropertyOfType(type, sourceProperty.escapedName);
if (targetType && isRelatedTo(sourceType, targetType)) {
return type;
const sourceProperty = findSingleDiscriminantProperty(sourceProperties, target);
if (sourceProperty) {
const sourceType = getTypeOfSymbol(sourceProperty);
for (const type of target.types) {
const targetType = getTypeOfPropertyOfType(type, sourceProperty.escapedName);
if (targetType && isRelatedTo(sourceType, targetType)) {
if (match) {
return undefined;
}
match = type;
}
}
}
}
return match;
}
function typeRelatedToEachType(source: Type, target: IntersectionType, reportErrors: boolean): Ternary {
@@ -9715,7 +9736,7 @@ namespace ts {
*/
function signatureRelatedTo(source: Signature, target: Signature, erase: boolean, reportErrors: boolean): Ternary {
return compareSignaturesRelated(erase ? getErasedSignature(source) : source, erase ? getErasedSignature(target) : target,
/*checkAsCallback*/ false, /*ignoreReturnTypes*/ false, reportErrors, reportError, isRelatedTo);
CallbackCheck.None, /*ignoreReturnTypes*/ false, reportErrors, reportError, isRelatedTo);
}
function signaturesIdenticalTo(source: Type, target: Type, kind: SignatureKind): Ternary {
@@ -11154,6 +11175,19 @@ namespace ts {
return false;
}
function findSingleDiscriminantProperty(sourceProperties: Symbol[], target: Type): Symbol | undefined {
let result: Symbol;
for (const sourceProperty of sourceProperties) {
if (isDiscriminantProperty(target, sourceProperty.escapedName)) {
if (result) {
return undefined;
}
result = sourceProperty;
}
}
return result;
}
function isOrContainsMatchingReference(source: Node, target: Node) {
return isMatchingReference(source, target) || containsMatchingReference(source, target);
}
@@ -14796,11 +14830,7 @@ namespace ts {
// where this references the constructor function object of a derived class,
// a super property access is permitted and must specify a public static member function of the base class.
if (languageVersion < ScriptTarget.ES2015) {
const hasNonMethodDeclaration = forEachProperty(prop, p => {
const propKind = getDeclarationKindFromSymbol(p);
return propKind !== SyntaxKind.MethodDeclaration && propKind !== SyntaxKind.MethodSignature;
});
if (hasNonMethodDeclaration) {
if (symbolHasNonMethodDeclaration(prop)) {
error(errorNode, Diagnostics.Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword);
return false;
}
@@ -14815,6 +14845,16 @@ namespace ts {
}
}
// Referencing Abstract Properties within Constructors is not allowed
if ((flags & ModifierFlags.Abstract) && symbolHasNonMethodDeclaration(prop)) {
const declaringClassDeclaration = <ClassLikeDeclaration>getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop));
if (declaringClassDeclaration && isNodeWithinConstructor(node, declaringClassDeclaration)) {
error(errorNode, Diagnostics.Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor, symbolToString(prop), typeToString(getDeclaringClass(prop)));
return false;
}
}
// Public properties are otherwise accessible.
if (!(flags & ModifierFlags.NonPublicAccessibilityModifier)) {
return true;
@@ -14866,6 +14906,13 @@ namespace ts {
return true;
}
function symbolHasNonMethodDeclaration(symbol: Symbol) {
return forEachProperty(symbol, prop => {
const propKind = getDeclarationKindFromSymbol(prop);
return propKind !== SyntaxKind.MethodDeclaration && propKind !== SyntaxKind.MethodSignature;
});
}
function checkNonNullExpression(node: Expression | QualifiedName) {
return checkNonNullType(checkExpression(node), node);
}
@@ -16548,6 +16595,12 @@ namespace ts {
return resolveUntypedCall(node);
}
if (isPotentiallyUncalledDecorator(node, callSignatures)) {
const nodeStr = getTextOfNode(node.expression, /*includeTrivia*/ false);
error(node, Diagnostics._0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write_0, nodeStr);
return resolveErrorCall(node);
}
const headMessage = getDiagnosticHeadMessageForDecoratorResolution(node);
if (!callSignatures.length) {
let errorInfo: DiagnosticMessageChain;
@@ -16560,6 +16613,18 @@ namespace ts {
return resolveCall(node, callSignatures, candidatesOutArray, headMessage);
}
/**
* Sometimes, we have a decorator that could accept zero arguments,
* but is receiving too many arguments as part of the decorator invocation.
* In those cases, a user may have meant to *call* the expression before using it as a decorator.
*/
function isPotentiallyUncalledDecorator(decorator: Decorator, signatures: Signature[]) {
return signatures.length && every(signatures, signature =>
signature.minArgumentCount === 0 &&
!signature.hasRestParameter &&
signature.parameters.length < getEffectiveArgumentCount(decorator, /*args*/ undefined, signature));
}
/**
* This function is similar to getResolvedSignature but is exclusively for trying to resolve JSX stateless-function component.
* The main reason we have to use this function instead of getResolvedSignature because, the caller of this function will already check the type of openingLikeElement's tagName
@@ -18433,9 +18498,8 @@ namespace ts {
checkGrammarDecorators(node) || checkGrammarModifiers(node);
checkVariableLikeDeclaration(node);
let func = getContainingFunction(node);
const func = getContainingFunction(node);
if (hasModifier(node, ModifierFlags.ParameterPropertyModifier)) {
func = getContainingFunction(node);
if (!(func.kind === SyntaxKind.Constructor && nodeIsPresent(func.body))) {
error(node, Diagnostics.A_parameter_property_is_only_allowed_in_a_constructor_implementation);
}
@@ -19968,14 +20032,20 @@ namespace ts {
}
function checkJSDocAugmentsTag(node: JSDocAugmentsTag): void {
const cls = getJSDocHost(node);
if (!isClassDeclaration(cls) && !isClassExpression(cls)) {
error(cls, Diagnostics.JSDoc_augments_is_not_attached_to_a_class_declaration);
const classLike = getJSDocHost(node);
if (!isClassDeclaration(classLike) && !isClassExpression(classLike)) {
error(classLike, Diagnostics.JSDoc_augments_is_not_attached_to_a_class_declaration);
return;
}
const augmentsTags = getAllJSDocTagsOfKind(classLike, SyntaxKind.JSDocAugmentsTag);
Debug.assert(augmentsTags.length > 0);
if (augmentsTags.length > 1) {
error(augmentsTags[1], Diagnostics.Class_declarations_cannot_have_more_than_one_augments_or_extends_tag);
}
const name = getIdentifierFromEntityNameExpression(node.class.expression);
const extend = getClassExtendsHeritageClauseElement(cls);
const extend = getClassExtendsHeritageClauseElement(classLike);
if (extend) {
const className = getIdentifierFromEntityNameExpression(extend.expression);
if (className && name.escapedText !== className.escapedText) {
@@ -20251,7 +20321,7 @@ namespace ts {
function checkCollisionWithArgumentsInGeneratedCode(node: SignatureDeclaration) {
// no rest parameters \ declaration context \ overload - no codegen impact
if (!hasDeclaredRestParameter(node) || isInAmbientContext(node) || nodeIsMissing((<FunctionLikeDeclaration>node).body)) {
if (!hasRestParameter(node) || isInAmbientContext(node) || nodeIsMissing((<FunctionLikeDeclaration>node).body)) {
return;
}
@@ -23092,6 +23162,19 @@ namespace ts {
return result;
}
function isNodeWithinConstructor(node: Node, classDeclaration: ClassLikeDeclaration) {
return findAncestor(node, element => {
if (isConstructorDeclaration(element) && nodeIsPresent(element.body)) {
return true;
}
else if (element === classDeclaration || isFunctionLikeDeclaration(element)) {
return "quit";
}
return false;
});
}
function isNodeWithinClass(node: Node, classDeclaration: ClassLikeDeclaration) {
return !!forEachEnclosingClass(node, n => n === classDeclaration);
}
+16
View File
@@ -907,6 +907,10 @@
"category": "Error",
"code": 1328
},
"'{0}' accepts too few arguments to be used as a decorator here. Did you mean to call it first and write '@{0}()'?": {
"category": "Error",
"code": 1329
},
"Duplicate identifier '{0}'.": {
"category": "Error",
@@ -2216,6 +2220,10 @@
"category": "Error",
"code": 2714
},
"Abstract property '{0}' in class '{1}' cannot be accessed in the constructor.": {
"category": "Error",
"code": 2715
},
"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",
@@ -3523,6 +3531,10 @@
"category": "Error",
"code": 8024
},
"Class declarations cannot have more than one `@augments` or `@extends` tag.": {
"category": "Error",
"code": 8025
},
"Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clause.": {
"category": "Error",
"code": 9002
@@ -3705,6 +3717,10 @@
"category": "Message",
"code": 90027
},
"Call decorator expression.": {
"category": "Message",
"code": 90028
},
"Convert function to an ES2015 class": {
"category": "Message",
Executable → Regular
View File
+2 -1
View File
@@ -6373,6 +6373,7 @@ namespace ts {
if (tagName) {
switch (tagName.escapedText) {
case "augments":
case "extends":
tag = parseAugmentsTag(atToken, tagName);
break;
case "class":
@@ -6699,7 +6700,7 @@ namespace ts {
if (typeExpression && typeExpression.type.kind === SyntaxKind.ArrayType) {
jsdocTypeLiteral.isArrayType = true;
}
typedefTag.typeExpression = childTypeTag && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type) ?
typedefTag.typeExpression = childTypeTag && childTypeTag.typeExpression && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type) ?
childTypeTag.typeExpression :
finishNode(jsdocTypeLiteral);
}
+10 -3
View File
@@ -1092,11 +1092,18 @@ namespace ts {
return true;
}
if (defaultLibraryPath && defaultLibraryPath.length !== 0) {
return containsPath(defaultLibraryPath, file.path, currentDirectory, /*ignoreCase*/ !host.useCaseSensitiveFileNames());
if (!options.noLib) {
return false;
}
return compareStrings(file.fileName, getDefaultLibraryFileName(), /*ignoreCase*/ !host.useCaseSensitiveFileNames()) === Comparison.EqualTo;
// If '--lib' is not specified, include default library file according to '--target'
// otherwise, using options specified in '--lib' instead of '--target' default library file
if (!options.lib) {
return compareStrings(file.fileName, getDefaultLibraryFileName(), /*ignoreCase*/ !host.useCaseSensitiveFileNames()) === Comparison.EqualTo;
}
else {
return forEach(options.lib, libFileName => compareStrings(file.fileName, combinePaths(defaultLibraryPath, libFileName), /*ignoreCase*/ !host.useCaseSensitiveFileNames()) === Comparison.EqualTo);
}
}
function getDiagnosticsProducingTypeChecker() {
+68 -25
View File
@@ -561,46 +561,89 @@ namespace ts {
// });
const resolve = createUniqueName("resolve");
const reject = createUniqueName("reject");
return createNew(
createIdentifier("Promise"),
/*typeArguments*/ undefined,
[createFunctionExpression(
const parameters = [
createParameter(/*decorator*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, /*name*/ resolve),
createParameter(/*decorator*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, /*name*/ reject)
];
const body = createBlock([
createStatement(
createCall(
createIdentifier("require"),
/*typeArguments*/ undefined,
[createArrayLiteral([firstOrUndefined(node.arguments) || createOmittedExpression()]), resolve, reject]
)
)
]);
let func: FunctionExpression | ArrowFunction;
if (languageVersion >= ScriptTarget.ES2015) {
func = createArrowFunction(
/*modifiers*/ undefined,
/*typeParameters*/ undefined,
parameters,
/*type*/ undefined,
/*equalsGreaterThanToken*/ undefined,
body);
}
else {
func = createFunctionExpression(
/*modifiers*/ undefined,
/*asteriskToken*/ undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
[createParameter(/*decorator*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, /*name*/ resolve),
createParameter(/*decorator*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, /*name*/ reject)],
parameters,
/*type*/ undefined,
createBlock([createStatement(
createCall(
createIdentifier("require"),
/*typeArguments*/ undefined,
[createArrayLiteral([firstOrUndefined(node.arguments) || createOmittedExpression()]), resolve, reject]
))])
)]);
body);
// if there is a lexical 'this' in the import call arguments, ensure we indicate
// that this new function expression indicates it captures 'this' so that the
// es2015 transformer will properly substitute 'this' with '_this'.
if (node.transformFlags & TransformFlags.ContainsLexicalThis) {
setEmitFlags(func, EmitFlags.CapturesThis);
}
}
return createNew(createIdentifier("Promise"), /*typeArguments*/ undefined, [func]);
}
function transformImportCallExpressionCommonJS(node: ImportCall): Expression {
function transformImportCallExpressionCommonJS(node: ImportCall): Expression {
// import("./blah")
// emit as
// Promise.resolve().then(function () { return require(x); }) /*CommonJs Require*/
// We have to wrap require in then callback so that require is done in asynchronously
// if we simply do require in resolve callback in Promise constructor. We will execute the loading immediately
return createCall(
createPropertyAccess(
createCall(createPropertyAccess(createIdentifier("Promise"), "resolve"), /*typeArguments*/ undefined, /*argumentsArray*/ []),
"then"),
/*typeArguments*/ undefined,
[createFunctionExpression(
const promiseResolveCall = createCall(createPropertyAccess(createIdentifier("Promise"), "resolve"), /*typeArguments*/ undefined, /*argumentsArray*/ []);
const requireCall = createCall(createIdentifier("require"), /*typeArguments*/ undefined, node.arguments);
let func: FunctionExpression | ArrowFunction;
if (languageVersion >= ScriptTarget.ES2015) {
func = createArrowFunction(
/*modifiers*/ undefined,
/*typeParameters*/ undefined,
/*parameters*/ [],
/*type*/ undefined,
/*equalsGreaterThanToken*/ undefined,
requireCall);
}
else {
func = createFunctionExpression(
/*modifiers*/ undefined,
/*asteriskToken*/ undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
/*parameters*/ undefined,
/*parameters*/ [],
/*type*/ undefined,
createBlock([createReturn(createCall(createIdentifier("require"), /*typeArguments*/ undefined, node.arguments))])
)]);
createBlock([createReturn(requireCall)]));
// if there is a lexical 'this' in the import call arguments, ensure we indicate
// that this new function expression indicates it captures 'this' so that the
// es2015 transformer will properly substitute 'this' with '_this'.
if (node.transformFlags & TransformFlags.ContainsLexicalThis) {
setEmitFlags(func, EmitFlags.CapturesThis);
}
}
return createCall(createPropertyAccess(promiseResolveCall, "then"), /*typeArguments*/ undefined, [func]);
}
/**
@@ -861,10 +904,10 @@ namespace ts {
if (original && hasAssociatedEndOfDeclarationMarker(original)) {
// Defer exports until we encounter an EndOfDeclarationMarker node
const id = getOriginalNodeId(node);
deferredExports[id] = appendExportStatement(deferredExports[id], createIdentifier("default"), node.expression, /*location*/ node, /*allowComments*/ true);
deferredExports[id] = appendExportStatement(deferredExports[id], createIdentifier("default"), visitNode(node.expression, importCallExpressionVisitor), /*location*/ node, /*allowComments*/ true);
}
else {
statements = appendExportStatement(statements, createIdentifier("default"), node.expression, /*location*/ node, /*allowComments*/ true);
statements = appendExportStatement(statements, createIdentifier("default"), visitNode(node.expression, importCallExpressionVisitor), /*location*/ node, /*allowComments*/ true);
}
return singleOrMany(statements);
+9 -1
View File
@@ -2159,6 +2159,10 @@ namespace ts {
kind: SyntaxKind.JSDocTag;
}
/**
* Note that `@extends` is a synonym of `@augments`.
* Both tags are represented by this interface.
*/
export interface JSDocAugmentsTag extends JSDocTag {
kind: SyntaxKind.JSDocAugmentsTag;
class: ExpressionWithTypeArguments & { expression: Identifier | PropertyAccessEntityNameExpression };
@@ -2194,7 +2198,7 @@ namespace ts {
export interface JSDocPropertyLikeTag extends JSDocTag, Declaration {
parent: JSDoc;
name: EntityName;
typeExpression: JSDocTypeExpression;
typeExpression?: JSDocTypeExpression;
/** Whether the property name came before the type -- non-standard for JSDoc, but Typescript-like */
isNameFirst: boolean;
isBracketed: boolean;
@@ -2649,6 +2653,10 @@ namespace ts {
signatureToString(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): string;
typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string;
symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string;
/**
* @deprecated Use the createX factory functions or XToY typechecker methods and `createPrinter` or the `xToString` methods instead
* This will be removed in a future version.
*/
getSymbolDisplayBuilder(): SymbolDisplayBuilder;
getFullyQualifiedName(symbol: Symbol): string;
getAugmentedPropertiesOfType(type: Type): Symbol[];
+37 -37
View File
@@ -1604,26 +1604,12 @@ namespace ts {
}
export function hasRestParameter(s: SignatureDeclaration): boolean {
return isRestParameter(lastOrUndefined(s.parameters));
const last = lastOrUndefined(s.parameters);
return last && isRestParameter(last);
}
export function hasDeclaredRestParameter(s: SignatureDeclaration): boolean {
return isDeclaredRestParam(lastOrUndefined(s.parameters));
}
export function isRestParameter(node: ParameterDeclaration) {
if (isInJavaScriptFile(node)) {
if (node.type && node.type.kind === SyntaxKind.JSDocVariadicType ||
forEach(getJSDocParameterTags(node),
t => t.typeExpression && t.typeExpression.type.kind === SyntaxKind.JSDocVariadicType)) {
return true;
}
}
return isDeclaredRestParam(node);
}
export function isDeclaredRestParam(node: ParameterDeclaration) {
return node && node.dotDotDotToken !== undefined;
export function isRestParameter(node: ParameterDeclaration): boolean {
return node.dotDotDotToken !== undefined;
}
export const enum AssignmentKind {
@@ -4112,27 +4098,35 @@ namespace ts {
if (!declaration) {
return undefined;
}
if (isJSDocPropertyLikeTag(declaration) && declaration.name.kind === SyntaxKind.QualifiedName) {
return declaration.name.right;
}
if (declaration.kind === SyntaxKind.BinaryExpression) {
const expr = declaration as BinaryExpression;
switch (getSpecialPropertyAssignmentKind(expr)) {
case SpecialPropertyAssignmentKind.ExportsProperty:
case SpecialPropertyAssignmentKind.ThisProperty:
case SpecialPropertyAssignmentKind.Property:
case SpecialPropertyAssignmentKind.PrototypeProperty:
return (expr.left as PropertyAccessExpression).name;
default:
return undefined;
switch (declaration.kind) {
case SyntaxKind.JSDocPropertyTag:
case SyntaxKind.JSDocParameterTag: {
const { name } = declaration as JSDocPropertyLikeTag;
if (name.kind === SyntaxKind.QualifiedName) {
return name.right;
}
break;
}
case SyntaxKind.BinaryExpression: {
const expr = declaration as BinaryExpression;
switch (getSpecialPropertyAssignmentKind(expr)) {
case SpecialPropertyAssignmentKind.ExportsProperty:
case SpecialPropertyAssignmentKind.ThisProperty:
case SpecialPropertyAssignmentKind.Property:
case SpecialPropertyAssignmentKind.PrototypeProperty:
return (expr.left as PropertyAccessExpression).name;
default:
return undefined;
}
}
case SyntaxKind.JSDocTypedefTag:
return getNameOfJSDocTypedef(declaration as JSDocTypedefTag);
case SyntaxKind.ExportAssignment: {
const { expression } = declaration as ExportAssignment;
return isIdentifier(expression) ? expression : undefined;
}
}
else if (declaration.kind === SyntaxKind.JSDocTypedefTag) {
return getNameOfJSDocTypedef(declaration as JSDocTypedefTag);
}
else {
return (declaration as NamedDeclaration).name;
}
return (declaration as NamedDeclaration).name;
}
/**
@@ -4247,6 +4241,12 @@ namespace ts {
return find(tags, doc => doc.kind === kind);
}
/** Gets all JSDoc tags of a specified kind, or undefined if not present. */
export function getAllJSDocTagsOfKind(node: Node, kind: SyntaxKind): ReadonlyArray<JSDocTag> | undefined {
const tags = getJSDocTags(node);
return filter(tags, doc => doc.kind === kind);
}
}
// Simple node tests of the form `node.kind === SyntaxKind.Foo`.
+4 -4
View File
@@ -249,10 +249,10 @@ namespace ts {
let hasChangedAutomaticTypeDirectiveNames = false; // True if the automatic type directives have changed
const loggingEnabled = compilerOptions.diagnostics || compilerOptions.extendedDiagnostics;
const writeLog: (s: string) => void = loggingEnabled ? s => system.write(s) : noop;
const watchFile = loggingEnabled ? ts.addFileWatcherWithLogging : ts.addFileWatcher;
const watchFilePath = loggingEnabled ? ts.addFilePathWatcherWithLogging : ts.addFilePathWatcher;
const watchDirectoryWorker = loggingEnabled ? ts.addDirectoryWatcherWithLogging : ts.addDirectoryWatcher;
const writeLog: (s: string) => void = loggingEnabled ? s => { system.write(s); system.write(system.newLine); } : noop;
const watchFile = compilerOptions.extendedDiagnostics ? ts.addFileWatcherWithLogging : loggingEnabled ? ts.addFileWatcherWithOnlyTriggerLogging : ts.addFileWatcher;
const watchFilePath = compilerOptions.extendedDiagnostics ? ts.addFilePathWatcherWithLogging : ts.addFilePathWatcher;
const watchDirectoryWorker = compilerOptions.extendedDiagnostics ? ts.addDirectoryWatcherWithLogging : ts.addDirectoryWatcher;
watchingHost = watchingHost || createWatchingSystemHost(compilerOptions.pretty);
const { system, parseConfigFile, reportDiagnostic, reportWatchDiagnostic, beforeCompile, afterCompile } = watchingHost;
+25 -6
View File
@@ -82,7 +82,12 @@ namespace ts {
export function addFileWatcherWithLogging(host: System, file: string, cb: FileWatcherCallback, log: (s: string) => void): FileWatcher {
const watcherCaption = `FileWatcher:: `;
return createWatcherWithLogging(addFileWatcher, watcherCaption, log, host, file, cb);
return createWatcherWithLogging(addFileWatcher, watcherCaption, log, /*logOnlyTrigger*/ false, host, file, cb);
}
export function addFileWatcherWithOnlyTriggerLogging(host: System, file: string, cb: FileWatcherCallback, log: (s: string) => void): FileWatcher {
const watcherCaption = `FileWatcher:: `;
return createWatcherWithLogging(addFileWatcher, watcherCaption, log, /*logOnlyTrigger*/ true, host, file, cb);
}
export type FilePathWatcherCallback = (fileName: string, eventKind: FileWatcherEventKind, filePath: Path) => void;
@@ -92,7 +97,12 @@ namespace ts {
export function addFilePathWatcherWithLogging(host: System, file: string, cb: FilePathWatcherCallback, path: Path, log: (s: string) => void): FileWatcher {
const watcherCaption = `FileWatcher:: `;
return createWatcherWithLogging(addFileWatcher, watcherCaption, log, host, file, cb, path);
return createWatcherWithLogging(addFileWatcher, watcherCaption, log, /*logOnlyTrigger*/ false, host, file, cb, path);
}
export function addFilePathWatcherWithOnlyTriggerLogging(host: System, file: string, cb: FilePathWatcherCallback, path: Path, log: (s: string) => void): FileWatcher {
const watcherCaption = `FileWatcher:: `;
return createWatcherWithLogging(addFileWatcher, watcherCaption, log, /*logOnlyTrigger*/ true, host, file, cb, path);
}
export function addDirectoryWatcher(host: System, directory: string, cb: DirectoryWatcherCallback, flags: WatchDirectoryFlags): FileWatcher {
@@ -102,14 +112,21 @@ namespace ts {
export function addDirectoryWatcherWithLogging(host: System, directory: string, cb: DirectoryWatcherCallback, flags: WatchDirectoryFlags, log: (s: string) => void): FileWatcher {
const watcherCaption = `DirectoryWatcher ${(flags & WatchDirectoryFlags.Recursive) !== 0 ? "recursive" : ""}:: `;
return createWatcherWithLogging(addDirectoryWatcher, watcherCaption, log, host, directory, cb, flags);
return createWatcherWithLogging(addDirectoryWatcher, watcherCaption, log, /*logOnlyTrigger*/ false, host, directory, cb, flags);
}
export function addDirectoryWatcherWithOnlyTriggerLogging(host: System, directory: string, cb: DirectoryWatcherCallback, flags: WatchDirectoryFlags, log: (s: string) => void): FileWatcher {
const watcherCaption = `DirectoryWatcher ${(flags & WatchDirectoryFlags.Recursive) !== 0 ? "recursive" : ""}:: `;
return createWatcherWithLogging(addDirectoryWatcher, watcherCaption, log, /*logOnlyTrigger*/ true, host, directory, cb, flags);
}
type WatchCallback<T, U> = (fileName: string, cbOptional1?: T, optional?: U) => void;
type AddWatch<T, U> = (host: System, file: string, cb: WatchCallback<T, U>, optional?: U) => FileWatcher;
function createWatcherWithLogging<T, U>(addWatch: AddWatch<T, U>, watcherCaption: string, log: (s: string) => void, host: System, file: string, cb: WatchCallback<T, U>, optional?: U): FileWatcher {
function createWatcherWithLogging<T, U>(addWatch: AddWatch<T, U>, watcherCaption: string, log: (s: string) => void, logOnlyTrigger: boolean, host: System, file: string, cb: WatchCallback<T, U>, optional?: U): FileWatcher {
const info = `PathInfo: ${file}`;
log(`${watcherCaption}Added: ${info}`);
if (!logOnlyTrigger) {
log(`${watcherCaption}Added: ${info}`);
}
const watcher = addWatch(host, file, (fileName, cbOptional1?) => {
const optionalInfo = cbOptional1 !== undefined ? ` ${cbOptional1}` : "";
log(`${watcherCaption}Trigger: ${fileName}${optionalInfo} ${info}`);
@@ -120,7 +137,9 @@ namespace ts {
}, optional);
return {
close: () => {
log(`${watcherCaption}Close: ${info}`);
if (!logOnlyTrigger) {
log(`${watcherCaption}Close: ${info}`);
}
watcher.close();
}
};
+44 -1
View File
@@ -563,7 +563,7 @@ namespace ts.projectSystem {
path: "/a/b/file3.js",
content: "console.log('file3');"
};
const externalProjectName = "externalproject";
const externalProjectName = "/a/b/externalproject";
const host = createServerHost([file1, file2, file3, libFile]);
const session = createSession(host);
const projectService = session.getProjectService();
@@ -588,5 +588,48 @@ namespace ts.projectSystem {
assert.isTrue(outFileContent.indexOf(file2.content) === -1);
assert.isTrue(outFileContent.indexOf(file3.content) === -1);
});
it("should use project root as current directory so that compile on save results in correct file mapping", () => {
const inputFileName = "Foo.ts";
const file1 = {
path: `/root/TypeScriptProject3/TypeScriptProject3/${inputFileName}`,
content: "consonle.log('file1');"
};
const externalProjectName = "/root/TypeScriptProject3/TypeScriptProject3/TypeScriptProject3.csproj";
const host = createServerHost([file1, libFile]);
const session = createSession(host);
const projectService = session.getProjectService();
const outFileName = "bar.js";
projectService.openExternalProject({
rootFiles: toExternalFiles([file1.path]),
options: {
outFile: outFileName,
sourceMap: true,
compileOnSave: true
},
projectFileName: externalProjectName
});
const emitRequest = makeSessionRequest<server.protocol.CompileOnSaveEmitFileRequestArgs>(CommandNames.CompileOnSaveEmitFile, { file: file1.path });
session.executeCommand(emitRequest);
// Verify js file
const expectedOutFileName = "/root/TypeScriptProject3/TypeScriptProject3/" + outFileName;
assert.isTrue(host.fileExists(expectedOutFileName));
const outFileContent = host.readFile(expectedOutFileName);
verifyContentHasString(outFileContent, file1.content);
verifyContentHasString(outFileContent, `//# sourceMappingURL=${outFileName}.map`);
// Verify map file
const expectedMapFileName = expectedOutFileName + ".map";
assert.isTrue(host.fileExists(expectedMapFileName));
const mapFileContent = host.readFile(expectedMapFileName);
verifyContentHasString(mapFileContent, `"sources":["${inputFileName}"]`);
function verifyContentHasString(content: string, string: string) {
assert.isTrue(content.indexOf(string) !== -1, `Expected "${content}" to have "${string}"`);
}
});
});
}
+29 -5
View File
@@ -1,10 +1,34 @@
/// <reference path="../harness.ts" />
describe("Public APIs", () => {
it("for the language service and compiler should be acknowledged when they change", () => {
Harness.Baseline.runBaseline("api/typescript.d.ts", () => Harness.IO.readFile("built/local/typescript.d.ts"));
function verifyApi(fileName: string) {
const builtFile = `built/local/${fileName}`;
const api = `api/${fileName}`;
let fileContent: string;
before(() => {
fileContent = Harness.IO.readFile(builtFile);
});
it("should be acknowledged when they change", () => {
Harness.Baseline.runBaseline(api, () => fileContent);
});
it("should compile", () => {
const testFile: Harness.Compiler.TestFile = {
unitName: builtFile,
content: fileContent
};
const inputFiles = [testFile];
const output = Harness.Compiler.compileFiles(inputFiles, [], /*harnessSettings*/ undefined, /*options*/ {}, /*currentDirectory*/ undefined);
assert(!output.result.errors || !output.result.errors.length, Harness.Compiler.minimalDiagnosticsToString(output.result.errors, /*pretty*/ true));
});
}
describe("for the language service and compiler", () => {
verifyApi("typescript.d.ts");
});
it("for the language server should be acknowledged when they change", () => {
Harness.Baseline.runBaseline("api/tsserverlibrary.d.ts", () => Harness.IO.readFile("built/local/tsserverlibrary.d.ts"));
describe("for the language server", () => {
verifyApi("tsserverlibrary.d.ts");
});
});
});
+57 -2
View File
@@ -16,8 +16,8 @@ namespace ts.server {
directoryExists: () => false,
getDirectories: () => [],
createDirectory: noop,
getExecutingFilePath(): string { return void 0; },
getCurrentDirectory(): string { return void 0; },
getExecutingFilePath(): string { return ""; },
getCurrentDirectory(): string { return ""; },
getEnvironmentVariable(): string { return ""; },
readDirectory() { return []; },
exit: noop,
@@ -386,6 +386,61 @@ namespace ts.server {
});
});
describe("exceptions", () => {
const command = "testhandler";
class TestSession extends Session {
lastSent: protocol.Message;
private exceptionRaisingHandler(_request: protocol.Request): { response?: any, responseRequired: boolean } {
f1();
return;
function f1() {
throw new Error("myMessage");
}
}
constructor() {
super({
host: mockHost,
cancellationToken: nullCancellationToken,
useSingleInferredProject: false,
useInferredProjectPerProjectRoot: false,
typingsInstaller: undefined,
byteLength: Utils.byteLength,
hrtime: process.hrtime,
logger: projectSystem.nullLogger,
canUseEvents: true
});
this.addProtocolHandler(command, this.exceptionRaisingHandler);
}
send(msg: protocol.Message) {
this.lastSent = msg;
}
}
it("raised in a protocol handler generate an event", () => {
const session = new TestSession();
const request = {
command,
seq: 0,
type: "request"
};
session.onMessage(JSON.stringify(request));
const lastSent = session.lastSent as protocol.Response;
expect(lastSent).to.contain({
seq: 0,
type: "response",
command,
success: false
});
expect(lastSent.message).has.string("myMessage").and.has.string("f1");
});
});
describe("how Session is extendable via subclassing", () => {
class TestSession extends Session {
lastSent: protocol.Message;
@@ -352,8 +352,6 @@ namespace ts.projectSystem {
verifyDiagnostics(actual, []);
}
const typeRootFromTsserverLocation = "/node_modules/@types";
export function getTypeRootsFromLocation(currentDirectory: string) {
currentDirectory = normalizePath(currentDirectory);
const result: string[] = [];
@@ -401,7 +399,7 @@ namespace ts.projectSystem {
const configFiles = flatMap(configFileLocations, location => [location + "tsconfig.json", location + "jsconfig.json"]);
checkWatchedFiles(host, configFiles.concat(libFile.path, moduleFile.path));
checkWatchedDirectories(host, [], /*recursive*/ false);
checkWatchedDirectories(host, ["/a/b/c", typeRootFromTsserverLocation], /*recursive*/ true);
checkWatchedDirectories(host, ["/a/b/c", ...getTypeRootsFromLocation(getDirectoryPath(appFile.path))], /*recursive*/ true);
});
it("can handle tsconfig file name with difference casing", () => {
@@ -4394,7 +4392,7 @@ namespace ts.projectSystem {
function verifyCalledOnEachEntry(callback: CalledMaps, expectedKeys: Map<number>) {
const calledMap = calledMaps[callback];
assert.equal(calledMap.size, expectedKeys.size, `${callback}: incorrect size of map: Actual keys: ${arrayFrom(calledMap.keys())} Expected: ${arrayFrom(expectedKeys.keys())}`);
ts.TestFSWithWatch.verifyMapSize(callback, calledMap, arrayFrom(expectedKeys.keys()));
expectedKeys.forEach((called, name) => {
assert.isTrue(calledMap.has(name), `${callback} is expected to contain ${name}, actual keys: ${arrayFrom(calledMap.keys())}`);
assert.equal(calledMap.get(name).length, called, `${callback} is expected to be called ${called} times with ${name}. Actual entry: ${calledMap.get(name)}`);
@@ -4476,6 +4474,7 @@ namespace ts.projectSystem {
}
const f2Lookups = getLocationsForModuleLookup("f2");
callsTrackingHost.verifyCalledOnEachEntryNTimes(CalledMapsWithSingleArg.fileExists, f2Lookups, 1);
const typeRootLocations = getTypeRootsFromLocation(getDirectoryPath(root.path));
const f2DirLookups = getLocationsForDirectoryLookup();
callsTrackingHost.verifyCalledOnEachEntry(CalledMapsWithSingleArg.directoryExists, f2DirLookups);
callsTrackingHost.verifyNoCall(CalledMapsWithSingleArg.getDirectories);
@@ -4486,7 +4485,7 @@ namespace ts.projectSystem {
verifyImportedDiagnostics();
const f1Lookups = f2Lookups.map(s => s.replace("f2", "f1"));
f1Lookups.length = f1Lookups.indexOf(imported.path) + 1;
const f1DirLookups = ["/c/d", "/c", typeRootFromTsserverLocation];
const f1DirLookups = ["/c/d", "/c", ...typeRootLocations];
vertifyF1Lookups();
// setting compiler options discards module resolution cache
@@ -4538,7 +4537,7 @@ namespace ts.projectSystem {
function getLocationsForDirectoryLookup() {
const result = createMap<number>();
// Type root
result.set(typeRootFromTsserverLocation, 1);
typeRootLocations.forEach(location => result.set(location, 1));
forEachAncestorDirectory(getDirectoryPath(root.path), ancestor => {
// To resolve modules
result.set(ancestor, 2);
+8 -4
View File
@@ -95,7 +95,7 @@ namespace ts.TestFSWithWatch {
}
}
function getDiffInKeys(map: Map<any>, expectedKeys: ReadonlyArray<string>) {
function getDiffInKeys<T>(map: Map<T>, expectedKeys: ReadonlyArray<string>) {
if (map.size === expectedKeys.length) {
return "";
}
@@ -122,8 +122,12 @@ namespace ts.TestFSWithWatch {
return `\n\nNotInActual: ${notInActual}\nDuplicates: ${duplicates}\nInActualButNotInExpected: ${inActualNotExpected}`;
}
function checkMapKeys(caption: string, map: Map<any>, expectedKeys: ReadonlyArray<string>) {
export function verifyMapSize(caption: string, map: Map<any>, expectedKeys: ReadonlyArray<string>) {
assert.equal(map.size, expectedKeys.length, `${caption}: incorrect size of map: Actual keys: ${arrayFrom(map.keys())} Expected: ${expectedKeys}${getDiffInKeys(map, expectedKeys)}`);
}
function checkMapKeys(caption: string, map: Map<any>, expectedKeys: ReadonlyArray<string>) {
verifyMapSize(caption, map, expectedKeys);
for (const name of expectedKeys) {
assert.isTrue(map.has(name), `${caption} is expected to contain ${name}, actual keys: ${arrayFrom(map.keys())}`);
}
@@ -548,7 +552,7 @@ namespace ts.TestFSWithWatch {
const folder = this.toFolder(directoryName);
// base folder has to be present
const base = getDirectoryPath(folder.fullPath);
const base = getDirectoryPath(folder.path);
const baseFolder = this.fs.get(base) as Folder;
Debug.assert(isFolder(baseFolder));
@@ -560,7 +564,7 @@ namespace ts.TestFSWithWatch {
const file = this.toFile({ path, content });
// base folder has to be present
const base = getDirectoryPath(file.fullPath);
const base = getDirectoryPath(file.path);
const folder = this.fs.get(base) as Folder;
Debug.assert(isFolder(folder));
+2
View File
@@ -10,6 +10,7 @@ interface Array<T> {
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
find<S extends T>(predicate: (this: void, value: T, index: number, obj: T[]) => value is S, thisArg?: any): S | undefined;
find(predicate: (value: T, index: number, obj: T[]) => boolean, thisArg?: any): T | undefined;
/**
@@ -350,6 +351,7 @@ interface ReadonlyArray<T> {
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
find<S extends T>(predicate: (this: void, value: T, index: number, obj: ReadonlyArray<T>) => value is S, thisArg?: any): S | undefined;
find(predicate: (value: T, index: number, obj: ReadonlyArray<T>) => boolean, thisArg?: any): T | undefined;
/**
+2 -2
View File
@@ -3,7 +3,7 @@ interface ObjectConstructor {
* Returns an array of values of the enumerable properties of an object
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
*/
values<T>(o: { [s: string]: T }): T[];
values<T>(o: { [s: string]: T } | { [n: number]: T }): T[];
/**
* Returns an array of values of the enumerable properties of an object
@@ -15,7 +15,7 @@ interface ObjectConstructor {
* Returns an array of key/values of the enumerable properties of an object
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
*/
entries<T>(o: { [s: string]: T }): [string, T][];
entries<T>(o: { [s: string]: T } | { [n: number]: T }): [string, T][];
/**
* Returns an array of key/values of the enumerable properties of an object
+44 -22
View File
@@ -1050,7 +1050,8 @@ interface ReadonlyArray<T> {
* @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.
* @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.
*/
reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: ReadonlyArray<T>) => T, initialValue?: T): T;
reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: ReadonlyArray<T>) => T): T;
reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: ReadonlyArray<T>) => T, initialValue: T): T;
/**
* Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
* @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.
@@ -1062,7 +1063,8 @@ interface ReadonlyArray<T> {
* @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array.
* @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.
*/
reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: ReadonlyArray<T>) => T, initialValue?: T): T;
reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: ReadonlyArray<T>) => T): T;
reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: ReadonlyArray<T>) => T, initialValue: T): T;
/**
* Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
* @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array.
@@ -1200,7 +1202,8 @@ interface Array<T> {
* @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.
* @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.
*/
reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue?: T): T;
reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T;
reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T;
/**
* Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
* @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.
@@ -1212,7 +1215,8 @@ interface Array<T> {
* @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array.
* @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.
*/
reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue?: T): T;
reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T;
reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T;
/**
* Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
* @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array.
@@ -1647,7 +1651,8 @@ interface Int8Array {
* the accumulation. The first call to the callbackfn function provides this value as an argument
* instead of an array value.
*/
reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number, initialValue?: number): number;
reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number): number;
reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number, initialValue: number): number;
/**
* Calls the specified callback function for all the elements in an array. The return value of
@@ -1671,7 +1676,8 @@ interface Int8Array {
* the accumulation. The first call to the callbackfn function provides this value as an
* argument instead of an array value.
*/
reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number, initialValue?: number): number;
reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number): number;
reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number, initialValue: number): number;
/**
* Calls the specified callback function for all the elements in an array, in descending order.
@@ -1914,7 +1920,8 @@ interface Uint8Array {
* the accumulation. The first call to the callbackfn function provides this value as an argument
* instead of an array value.
*/
reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number, initialValue?: number): number;
reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number): number;
reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number, initialValue: number): number;
/**
* Calls the specified callback function for all the elements in an array. The return value of
@@ -1938,7 +1945,8 @@ interface Uint8Array {
* the accumulation. The first call to the callbackfn function provides this value as an
* argument instead of an array value.
*/
reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number, initialValue?: number): number;
reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number): number;
reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number, initialValue: number): number;
/**
* Calls the specified callback function for all the elements in an array, in descending order.
@@ -2181,7 +2189,8 @@ interface Uint8ClampedArray {
* the accumulation. The first call to the callbackfn function provides this value as an argument
* instead of an array value.
*/
reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8ClampedArray) => number, initialValue?: number): number;
reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8ClampedArray) => number): number;
reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8ClampedArray) => number, initialValue: number): number;
/**
* Calls the specified callback function for all the elements in an array. The return value of
@@ -2205,7 +2214,8 @@ interface Uint8ClampedArray {
* the accumulation. The first call to the callbackfn function provides this value as an
* argument instead of an array value.
*/
reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8ClampedArray) => number, initialValue?: number): number;
reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8ClampedArray) => number): number;
reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8ClampedArray) => number, initialValue: number): number;
/**
* Calls the specified callback function for all the elements in an array, in descending order.
@@ -2446,7 +2456,8 @@ interface Int16Array {
* the accumulation. The first call to the callbackfn function provides this value as an argument
* instead of an array value.
*/
reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int16Array) => number, initialValue?: number): number;
reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int16Array) => number): number;
reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int16Array) => number, initialValue: number): number;
/**
* Calls the specified callback function for all the elements in an array. The return value of
@@ -2470,7 +2481,8 @@ interface Int16Array {
* the accumulation. The first call to the callbackfn function provides this value as an
* argument instead of an array value.
*/
reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int16Array) => number, initialValue?: number): number;
reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int16Array) => number): number;
reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int16Array) => number, initialValue: number): number;
/**
* Calls the specified callback function for all the elements in an array, in descending order.
@@ -2714,7 +2726,8 @@ interface Uint16Array {
* the accumulation. The first call to the callbackfn function provides this value as an argument
* instead of an array value.
*/
reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint16Array) => number, initialValue?: number): number;
reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint16Array) => number): number;
reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint16Array) => number, initialValue: number): number;
/**
* Calls the specified callback function for all the elements in an array. The return value of
@@ -2738,7 +2751,8 @@ interface Uint16Array {
* the accumulation. The first call to the callbackfn function provides this value as an
* argument instead of an array value.
*/
reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint16Array) => number, initialValue?: number): number;
reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint16Array) => number): number;
reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint16Array) => number, initialValue: number): number;
/**
* Calls the specified callback function for all the elements in an array, in descending order.
@@ -2981,7 +2995,8 @@ interface Int32Array {
* the accumulation. The first call to the callbackfn function provides this value as an argument
* instead of an array value.
*/
reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int32Array) => number, initialValue?: number): number;
reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int32Array) => number): number;
reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int32Array) => number, initialValue: number): number;
/**
* Calls the specified callback function for all the elements in an array. The return value of
@@ -3005,7 +3020,8 @@ interface Int32Array {
* the accumulation. The first call to the callbackfn function provides this value as an
* argument instead of an array value.
*/
reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int32Array) => number, initialValue?: number): number;
reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int32Array) => number): number;
reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int32Array) => number, initialValue: number): number;
/**
* Calls the specified callback function for all the elements in an array, in descending order.
@@ -3247,7 +3263,8 @@ interface Uint32Array {
* the accumulation. The first call to the callbackfn function provides this value as an argument
* instead of an array value.
*/
reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint32Array) => number, initialValue?: number): number;
reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint32Array) => number): number;
reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint32Array) => number, initialValue: number): number;
/**
* Calls the specified callback function for all the elements in an array. The return value of
@@ -3271,7 +3288,8 @@ interface Uint32Array {
* the accumulation. The first call to the callbackfn function provides this value as an
* argument instead of an array value.
*/
reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint32Array) => number, initialValue?: number): number;
reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint32Array) => number): number;
reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint32Array) => number, initialValue: number): number;
/**
* Calls the specified callback function for all the elements in an array, in descending order.
@@ -3514,7 +3532,8 @@ interface Float32Array {
* the accumulation. The first call to the callbackfn function provides this value as an argument
* instead of an array value.
*/
reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float32Array) => number, initialValue?: number): number;
reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float32Array) => number): number;
reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float32Array) => number, initialValue: number): number;
/**
* Calls the specified callback function for all the elements in an array. The return value of
@@ -3538,7 +3557,8 @@ interface Float32Array {
* the accumulation. The first call to the callbackfn function provides this value as an
* argument instead of an array value.
*/
reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float32Array) => number, initialValue?: number): number;
reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float32Array) => number): number;
reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float32Array) => number, initialValue: number): number;
/**
* Calls the specified callback function for all the elements in an array, in descending order.
@@ -3782,7 +3802,8 @@ interface Float64Array {
* the accumulation. The first call to the callbackfn function provides this value as an argument
* instead of an array value.
*/
reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float64Array) => number, initialValue?: number): number;
reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float64Array) => number): number;
reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float64Array) => number, initialValue: number): number;
/**
* Calls the specified callback function for all the elements in an array. The return value of
@@ -3806,7 +3827,8 @@ interface Float64Array {
* the accumulation. The first call to the callbackfn function provides this value as an
* argument instead of an array value.
*/
reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float64Array) => number, initialValue?: number): number;
reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float64Array) => number): number;
reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float64Array) => number, initialValue: number): number;
/**
* Calls the specified callback function for all the elements in an array, in descending order.
+20 -4
View File
@@ -403,7 +403,7 @@ namespace ts.server {
this.globalPlugins = opts.globalPlugins || emptyArray;
this.pluginProbeLocations = opts.pluginProbeLocations || emptyArray;
this.allowLocalPluginLoads = !!opts.allowLocalPluginLoads;
this.typesMapLocation = (opts.typesMapLocation === undefined) ? combinePaths(this.host.getExecutingFilePath(), "../typesMap.json") : opts.typesMapLocation;
this.typesMapLocation = (opts.typesMapLocation === undefined) ? combinePaths(this.getExecutingFilePath(), "../typesMap.json") : opts.typesMapLocation;
Debug.assert(!!this.host.createHash, "'ServerHost.createHash' is required for ProjectService");
@@ -431,6 +431,11 @@ namespace ts.server {
this.watchFilePath = (host, file, cb, path, watchType, project) => ts.addFilePathWatcherWithLogging(host, file, cb, path, this.createWatcherLog(watchType, project));
this.watchDirectory = (host, dir, cb, flags, watchType, project) => ts.addDirectoryWatcherWithLogging(host, dir, cb, flags, this.createWatcherLog(watchType, project));
}
else if (this.logger.loggingEnabled()) {
this.watchFile = (host, file, cb, watchType, project) => ts.addFileWatcherWithOnlyTriggerLogging(host, file, cb, this.createWatcherLog(watchType, project));
this.watchFilePath = (host, file, cb, path, watchType, project) => ts.addFilePathWatcherWithOnlyTriggerLogging(host, file, cb, path, this.createWatcherLog(watchType, project));
this.watchDirectory = (host, dir, cb, flags, watchType, project) => ts.addDirectoryWatcherWithOnlyTriggerLogging(host, dir, cb, flags, this.createWatcherLog(watchType, project));
}
else {
this.watchFile = ts.addFileWatcher;
this.watchFilePath = ts.addFilePathWatcher;
@@ -447,6 +452,16 @@ namespace ts.server {
return toPath(fileName, this.currentDirectory, this.toCanonicalFileName);
}
/*@internal*/
getExecutingFilePath() {
return this.getNormalizedAbsolutePath(this.host.getExecutingFilePath());
}
/*@internal*/
getNormalizedAbsolutePath(fileName: string) {
return getNormalizedAbsolutePath(fileName, this.host.getCurrentDirectory());
}
/* @internal */
getChangedFiles_TestOnly() {
return this.changedFiles;
@@ -1624,12 +1639,13 @@ namespace ts.server {
return this.inferredProjects[0];
}
return this.createInferredProject(/*rootDirectoryForResolution*/ undefined, /*isSingleInferredProject*/ true);
// Single inferred project does not have a project root and hence no current directory
return this.createInferredProject(/*currentDirectory*/ undefined, /*isSingleInferredProject*/ true);
}
private createInferredProject(rootDirectoryForResolution: string | undefined, isSingleInferredProject?: boolean, projectRootPath?: string): InferredProject {
private createInferredProject(currentDirectory: string | undefined, isSingleInferredProject?: boolean, projectRootPath?: string): InferredProject {
const compilerOptions = projectRootPath && this.compilerOptionsForInferredProjectsPerProjectRoot.get(projectRootPath) || this.compilerOptionsForInferredProjects;
const project = new InferredProject(this, this.documentRegistry, compilerOptions, projectRootPath, rootDirectoryForResolution);
const project = new InferredProject(this, this.documentRegistry, compilerOptions, projectRootPath, currentDirectory);
if (isSingleInferredProject) {
this.inferredProjects.unshift(project);
}
+19 -35
View File
@@ -195,6 +195,9 @@ namespace ts.server {
return result.module;
}
/*@internal*/
readonly currentDirectory: string;
/*@internal*/
constructor(
/*@internal*/readonly projectName: string,
@@ -206,7 +209,8 @@ namespace ts.server {
private compilerOptions: CompilerOptions,
public compileOnSaveEnabled: boolean,
/*@internal*/public directoryStructureHost: DirectoryStructureHost,
rootDirectoryForResolution: string | undefined) {
currentDirectory: string | undefined) {
this.currentDirectory = this.projectService.getNormalizedAbsolutePath(currentDirectory || "");
this.cancellationToken = new ThrottledCancellationToken(this.projectService.cancellationToken, this.projectService.throttleWaitMilliseconds);
if (!this.compilerOptions) {
@@ -230,7 +234,8 @@ namespace ts.server {
}
this.languageService = createLanguageService(this, this.documentRegistry);
this.resolutionCache = createResolutionCache(this, rootDirectoryForResolution);
// Use the current directory as resolution root only if the project created using current directory string
this.resolutionCache = createResolutionCache(this, currentDirectory && this.currentDirectory);
if (!languageServiceEnabled) {
this.disableLanguageService();
}
@@ -296,16 +301,16 @@ namespace ts.server {
}
}
getCancellationToken() {
getCancellationToken(): HostCancellationToken {
return this.cancellationToken;
}
getCurrentDirectory(): string {
return this.directoryStructureHost.getCurrentDirectory();
return this.currentDirectory;
}
getDefaultLibFileName() {
const nodeModuleBinDir = getDirectoryPath(normalizePath(this.projectService.host.getExecutingFilePath()));
const nodeModuleBinDir = getDirectoryPath(normalizePath(this.projectService.getExecutingFilePath()));
return combinePaths(nodeModuleBinDir, getDefaultLibFileName(this.compilerOptions));
}
@@ -448,9 +453,8 @@ namespace ts.server {
this.ensureBuilder();
const { emitSkipped, outputFiles } = this.builder.emitFile(this.program, scriptInfo.path);
if (!emitSkipped) {
const projectRootPath = this.getProjectRootPath();
for (const outputFile of outputFiles) {
const outputFileAbsoluteFileName = getNormalizedAbsolutePath(outputFile.name, projectRootPath ? projectRootPath : getDirectoryPath(scriptInfo.fileName));
const outputFileAbsoluteFileName = getNormalizedAbsolutePath(outputFile.name, this.currentDirectory);
writeFile(outputFileAbsoluteFileName, outputFile.text, outputFile.writeByteOrderMark);
}
}
@@ -479,7 +483,6 @@ namespace ts.server {
getProjectName() {
return this.projectName;
}
abstract getProjectRootPath(): string | undefined;
abstract getTypeAcquisition(): TypeAcquisition;
getExternalFiles(): SortedReadonlyArray<string> {
@@ -561,7 +564,7 @@ namespace ts.server {
return map(this.program.getSourceFiles(), sourceFile => {
const scriptInfo = this.projectService.getScriptInfoForPath(sourceFile.path);
if (!scriptInfo) {
Debug.fail(`scriptInfo for a file '${sourceFile.fileName}' is missing.`);
Debug.fail(`scriptInfo for a file '${sourceFile.fileName}' Path: '${sourceFile.path}' is missing.`);
}
return scriptInfo;
});
@@ -1042,8 +1045,8 @@ namespace ts.server {
projectService: ProjectService,
documentRegistry: DocumentRegistry,
compilerOptions: CompilerOptions,
public readonly projectRootPath: string | undefined,
rootDirectoryForResolution: string | undefined) {
readonly projectRootPath: string | undefined,
currentDirectory: string | undefined) {
super(InferredProject.newName(),
ProjectKind.Inferred,
projectService,
@@ -1053,7 +1056,7 @@ namespace ts.server {
compilerOptions,
/*compileOnSaveEnabled*/ false,
projectService.host,
rootDirectoryForResolution);
currentDirectory);
}
addRoot(info: ScriptInfo) {
@@ -1082,12 +1085,6 @@ namespace ts.server {
this.getRootScriptInfos().length === 1;
}
getProjectRootPath() {
return this.projectRootPath ||
// Single inferred project does not have a project root.
!this.projectService.useSingleInferredProject && getDirectoryPath(this.getRootFiles()[0]);
}
close() {
forEach(this.getRootScriptInfos(), info => this.projectService.stopWatchingConfigFilesForInferredProjectRoot(info));
super.close();
@@ -1183,7 +1180,7 @@ namespace ts.server {
// Search our peer node_modules, then any globally-specified probe paths
// ../../.. to walk from X/node_modules/typescript/lib/tsserver.js to X/node_modules/
const searchPaths = [combinePaths(host.getExecutingFilePath(), "../../.."), ...this.projectService.pluginProbeLocations];
const searchPaths = [combinePaths(this.projectService.getExecutingFilePath(), "../../.."), ...this.projectService.pluginProbeLocations];
if (this.projectService.allowLocalPluginLoads) {
const local = getDirectoryPath(this.canonicalConfigFilePath);
@@ -1263,10 +1260,6 @@ namespace ts.server {
}
}
getProjectRootPath() {
return getDirectoryPath(this.getConfigFilePath());
}
/**
* Get the errors that dont have any file name associated
*/
@@ -1381,13 +1374,14 @@ namespace ts.server {
compilerOptions: CompilerOptions,
languageServiceEnabled: boolean,
public compileOnSaveEnabled: boolean,
private readonly projectFilePath?: string) {
projectFilePath?: string) {
super(externalProjectName,
ProjectKind.External,
projectService,
documentRegistry,
/*hasExplicitListOfFiles*/ true,
languageServiceEnabled, compilerOptions,
languageServiceEnabled,
compilerOptions,
compileOnSaveEnabled,
projectService.host,
getDirectoryPath(projectFilePath || normalizeSlashes(externalProjectName)));
@@ -1397,16 +1391,6 @@ namespace ts.server {
return this.excludedFiles;
}
getProjectRootPath() {
if (this.projectFilePath) {
return getDirectoryPath(this.projectFilePath);
}
// if the projectFilePath is not given, we make the assumption that the project name
// is the path of the project file. AS the project name is provided by VS, we need to
// normalize slashes before using it as a file name.
return getDirectoryPath(normalizeSlashes(this.getProjectName()));
}
getTypeAcquisition() {
return this.typeAcquisition;
}
@@ -0,0 +1,20 @@
/* @internal */
namespace ts.codefix {
registerCodeFix({
errorCodes: [Diagnostics._0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write_0.code],
getCodeActions: (context: CodeFixContext) => {
const sourceFile = context.sourceFile;
const token = getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false);
const decorator = getAncestor(token, SyntaxKind.Decorator) as Decorator;
Debug.assert(!!decorator, "Expected position to be owned by a decorator.");
const replacement = createCall(decorator.expression, /*typeArguments*/ undefined, /*argumentsArray*/ undefined);
const changeTracker = textChanges.ChangeTracker.fromContext(context);
changeTracker.replaceNode(sourceFile, decorator.expression, replacement);
return [{
description: getLocaleSpecificMessage(Diagnostics.Call_decorator_expression),
changes: changeTracker.getChanges()
}];
}
});
}
+1
View File
@@ -1,3 +1,4 @@
/// <reference path="addMissingInvocationForDecorator.ts" />
/// <reference path="correctQualifiedNameToIndexedAccessType.ts" />
/// <reference path="fixClassIncorrectlyImplementsInterface.ts" />
/// <reference path="fixAddMissingMember.ts" />
+1 -5
View File
@@ -16,7 +16,7 @@ namespace ts.codefix {
moduleSpecifier?: string;
}
enum ModuleSpecifierComparison {
const enum ModuleSpecifierComparison {
Better,
Equal,
Worse
@@ -26,10 +26,6 @@ namespace ts.codefix {
private symbolIdToActionMap: ImportCodeAction[][] = [];
addAction(symbolId: number, newAction: ImportCodeAction) {
if (!newAction) {
return;
}
const actions = this.symbolIdToActionMap[symbolId];
if (!actions) {
this.symbolIdToActionMap[symbolId] = [newAction];
+4 -1
View File
@@ -482,7 +482,10 @@ namespace ts.FindAllReferences.Core {
/** @param allSearchSymbols set of additinal symbols for use by `includes`. */
createSearch(location: Node, symbol: Symbol, comingFrom: ImportExport | undefined, searchOptions: { text?: string, allSearchSymbols?: Symbol[] } = {}): Search {
// Note: if this is an external module symbol, the name doesn't include quotes.
const { text = stripQuotes(getDeclaredName(this.checker, symbol, location)), allSearchSymbols = undefined } = searchOptions;
const {
text = stripQuotes(unescapeLeadingUnderscores((getLocalSymbolForExportDefault(symbol) || symbol).escapedName)),
allSearchSymbols = undefined,
} = searchOptions;
const escapedText = escapeLeadingUnderscores(text);
const parents = this.options.implementations && getParentSymbolsOfPropertyAccess(location, symbol, this.checker);
return {
-3
View File
@@ -609,9 +609,6 @@ namespace ts.FindAllReferences {
}
return forEach(symbol.declarations, decl => {
if (isExportAssignment(decl)) {
return isIdentifier(decl.expression) ? decl.expression.escapedText : undefined;
}
const name = getNameOfDeclaration(decl);
return name && name.kind === SyntaxKind.Identifier && name.escapedText;
});
+16 -16
View File
@@ -16,7 +16,7 @@
/// <reference path='services.ts' />
/* @internal */
let debugObjectHost = (function (this: any) { return this; })();
let debugObjectHost: { CollectGarbage(): void } = (function (this: any) { return this; })();
// We need to use 'null' to interface with the managed side.
/* tslint:disable:no-null-keyword */
@@ -119,13 +119,13 @@ namespace ts {
}
export interface Shim {
dispose(_dummy: any): void;
dispose(_dummy: {}): void;
}
export interface LanguageServiceShim extends Shim {
languageService: LanguageService;
dispose(_dummy: any): void;
dispose(_dummy: {}): void;
refresh(throwOnError: boolean): void;
@@ -417,7 +417,7 @@ namespace ts {
return this.shimHost.getScriptVersion(fileName);
}
public getLocalizedDiagnosticMessages(): any {
public getLocalizedDiagnosticMessages() {
const diagnosticMessagesJson = this.shimHost.getLocalizedDiagnosticMessages();
if (diagnosticMessagesJson === null || diagnosticMessagesJson === "") {
return null;
@@ -515,7 +515,7 @@ namespace ts {
}
}
function simpleForwardCall(logger: Logger, actionDescription: string, action: () => any, logPerformance: boolean): any {
function simpleForwardCall(logger: Logger, actionDescription: string, action: () => {}, logPerformance: boolean): {} {
let start: number;
if (logPerformance) {
logger.log(actionDescription);
@@ -539,14 +539,14 @@ namespace ts {
return result;
}
function forwardJSONCall(logger: Logger, actionDescription: string, action: () => any, logPerformance: boolean): string {
function forwardJSONCall(logger: Logger, actionDescription: string, action: () => {}, logPerformance: boolean): string {
return <string>forwardCall(logger, actionDescription, /*returnJson*/ true, action, logPerformance);
}
function forwardCall<T>(logger: Logger, actionDescription: string, returnJson: boolean, action: () => T, logPerformance: boolean): T | string {
try {
const result = simpleForwardCall(logger, actionDescription, action, logPerformance);
return returnJson ? JSON.stringify({ result }) : result;
return returnJson ? JSON.stringify({ result }) : result as T;
}
catch (err) {
if (err instanceof OperationCanceledException) {
@@ -563,7 +563,7 @@ namespace ts {
constructor(private factory: ShimFactory) {
factory.registerShim(this);
}
public dispose(_dummy: any): void {
public dispose(_dummy: {}): void {
this.factory.unregisterShim(this);
}
}
@@ -601,7 +601,7 @@ namespace ts {
this.logger = this.host;
}
public forwardJSONCall(actionDescription: string, action: () => any): string {
public forwardJSONCall(actionDescription: string, action: () => {}): string {
return forwardJSONCall(this.logger, actionDescription, action, this.logPerformance);
}
@@ -611,7 +611,7 @@ namespace ts {
* Ensure (almost) deterministic release of internal Javascript resources when
* some external native objects holds onto us (e.g. Com/Interop).
*/
public dispose(dummy: any): void {
public dispose(dummy: {}): void {
this.logger.log("dispose()");
this.languageService.dispose();
this.languageService = null;
@@ -635,7 +635,7 @@ namespace ts {
public refresh(throwOnError: boolean): void {
this.forwardJSONCall(
`refresh(${throwOnError})`,
() => <any>null
() => null
);
}
@@ -644,7 +644,7 @@ namespace ts {
"cleanupSemanticCache()",
() => {
this.languageService.cleanupSemanticCache();
return <any>null;
return null;
});
}
@@ -980,13 +980,13 @@ namespace ts {
);
}
public getEmitOutputObject(fileName: string): any {
public getEmitOutputObject(fileName: string): EmitOutput {
return forwardCall(
this.logger,
`getEmitOutput('${fileName}')`,
/*returnJson*/ false,
() => this.languageService.getEmitOutput(fileName),
this.logPerformance);
this.logPerformance) as EmitOutput;
}
}
@@ -1030,7 +1030,7 @@ namespace ts {
super(factory);
}
private forwardJSONCall(actionDescription: string, action: () => any): any {
private forwardJSONCall(actionDescription: string, action: () => {}): string {
return forwardJSONCall(this.logger, actionDescription, action, this.logPerformance);
}
@@ -1221,7 +1221,7 @@ namespace ts {
// Here we expose the TypeScript services as an external module
// so that it may be consumed easily like a node module.
declare const module: any;
declare const module: { exports: {} };
if (typeof module !== "undefined" && module.exports) {
module.exports = ts;
}
+13 -7
View File
@@ -341,13 +341,19 @@ namespace ts.SymbolDisplay {
}
if (symbolFlags & SymbolFlags.Alias) {
addNewLineIfDisplayPartsExist();
if (symbol.declarations[0].kind === SyntaxKind.NamespaceExportDeclaration) {
displayParts.push(keywordPart(SyntaxKind.ExportKeyword));
displayParts.push(spacePart());
displayParts.push(keywordPart(SyntaxKind.NamespaceKeyword));
}
else {
displayParts.push(keywordPart(SyntaxKind.ImportKeyword));
switch (symbol.declarations[0].kind) {
case SyntaxKind.NamespaceExportDeclaration:
displayParts.push(keywordPart(SyntaxKind.ExportKeyword));
displayParts.push(spacePart());
displayParts.push(keywordPart(SyntaxKind.NamespaceKeyword));
break;
case SyntaxKind.ExportAssignment:
displayParts.push(keywordPart(SyntaxKind.ExportKeyword));
displayParts.push(spacePart());
displayParts.push(keywordPart((symbol.declarations[0] as ExportAssignment).isExportEquals ? SyntaxKind.EqualsToken : SyntaxKind.DefaultKeyword));
break;
default:
displayParts.push(keywordPart(SyntaxKind.ImportKeyword));
}
displayParts.push(spacePart());
addFullSymbolName(symbol);