mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into readonlyMembers
Conflicts: src/compiler/types.ts
This commit is contained in:
+103
-11
@@ -117,6 +117,12 @@ namespace ts {
|
||||
let labelIndexMap: Map<number>;
|
||||
let implicitLabels: number[];
|
||||
|
||||
// state used for emit helpers
|
||||
let hasClassExtends: boolean;
|
||||
let hasAsyncFunctions: boolean;
|
||||
let hasDecorators: boolean;
|
||||
let hasParameterDecorators: boolean;
|
||||
|
||||
// If this file is an external module, then it is automatically in strict-mode according to
|
||||
// ES6. If it is not an external module, then we'll determine if it is in strict mode or
|
||||
// not depending on if we see "use strict" in certain places (or if we hit a class/namespace).
|
||||
@@ -151,6 +157,10 @@ namespace ts {
|
||||
labelStack = undefined;
|
||||
labelIndexMap = undefined;
|
||||
implicitLabels = undefined;
|
||||
hasClassExtends = false;
|
||||
hasAsyncFunctions = false;
|
||||
hasDecorators = false;
|
||||
hasParameterDecorators = false;
|
||||
}
|
||||
|
||||
return bindSourceFile;
|
||||
@@ -241,6 +251,15 @@ namespace ts {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
return node.flags & NodeFlags.Default ? "default" : undefined;
|
||||
case SyntaxKind.JSDocFunctionType:
|
||||
return isJSDocConstructSignature(node) ? "__new" : "__call";
|
||||
case SyntaxKind.Parameter:
|
||||
// Parameters with names are handled at the top of this function. Parameters
|
||||
// without names can only come from JSDocFunctionTypes.
|
||||
Debug.assert(node.parent.kind === SyntaxKind.JSDocFunctionType);
|
||||
let functionType = <JSDocFunctionType>node.parent;
|
||||
let index = indexOf(functionType.parameters, node);
|
||||
return "p" + index;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -351,8 +370,8 @@ namespace ts {
|
||||
// when the emitter comes back to it, it knows not to qualify the name if it was found in a containing scope.
|
||||
|
||||
// NOTE: Nested ambient modules always should go to to 'locals' table to prevent their automatic merge
|
||||
// during global merging in the checker. Why? The only case when ambient module is permitted inside another module is module augmentation
|
||||
// and this case is specially handled. Module augmentations should only be merged with original module definition
|
||||
// during global merging in the checker. Why? The only case when ambient module is permitted inside another module is module augmentation
|
||||
// and this case is specially handled. Module augmentations should only be merged with original module definition
|
||||
// and should never be merged directly with other augmentation, and the latter case would be possible if automatic merge is allowed.
|
||||
if (!isAmbientModule(node) && (hasExportModifier || container.flags & NodeFlags.ExportContext)) {
|
||||
const exportKind =
|
||||
@@ -411,7 +430,6 @@ namespace ts {
|
||||
|
||||
addToContainerChain(container);
|
||||
}
|
||||
|
||||
else if (containerFlags & ContainerFlags.IsBlockScopedContainer) {
|
||||
blockScopeContainer = node;
|
||||
blockScopeContainer.locals = undefined;
|
||||
@@ -429,6 +447,9 @@ namespace ts {
|
||||
// reset all reachability check related flags on node (for incremental scenarios)
|
||||
flags &= ~NodeFlags.ReachabilityCheckFlags;
|
||||
|
||||
// reset all emit helper flags on node (for incremental scenarios)
|
||||
flags &= ~NodeFlags.EmitHelperFlags;
|
||||
|
||||
if (kind === SyntaxKind.InterfaceDeclaration) {
|
||||
seenThisKeyword = false;
|
||||
}
|
||||
@@ -446,6 +467,10 @@ namespace ts {
|
||||
labelStack = labelIndexMap = implicitLabels = undefined;
|
||||
}
|
||||
|
||||
if (isInJavaScriptFile(node) && node.jsDocComment) {
|
||||
bind(node.jsDocComment);
|
||||
}
|
||||
|
||||
bindReachableStatement(node);
|
||||
|
||||
if (currentReachabilityState === Reachability.Reachable && isFunctionLikeKind(kind) && nodeIsPresent((<FunctionLikeDeclaration>node).body)) {
|
||||
@@ -459,6 +484,21 @@ namespace ts {
|
||||
flags = seenThisKeyword ? flags | NodeFlags.ContainsThis : flags & ~NodeFlags.ContainsThis;
|
||||
}
|
||||
|
||||
if (kind === SyntaxKind.SourceFile) {
|
||||
if (hasClassExtends) {
|
||||
flags |= NodeFlags.HasClassExtends;
|
||||
}
|
||||
if (hasDecorators) {
|
||||
flags |= NodeFlags.HasDecorators;
|
||||
}
|
||||
if (hasParameterDecorators) {
|
||||
flags |= NodeFlags.HasParamDecorators;
|
||||
}
|
||||
if (hasAsyncFunctions) {
|
||||
flags |= NodeFlags.HasAsyncFunctions;
|
||||
}
|
||||
}
|
||||
|
||||
node.flags = flags;
|
||||
|
||||
if (saveState) {
|
||||
@@ -694,8 +734,9 @@ namespace ts {
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
case SyntaxKind.TypeLiteral:
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
case SyntaxKind.TypeLiteral:
|
||||
case SyntaxKind.JSDocRecordType:
|
||||
return ContainerFlags.IsContainer;
|
||||
|
||||
case SyntaxKind.CallSignature:
|
||||
@@ -781,6 +822,7 @@ namespace ts {
|
||||
case SyntaxKind.TypeLiteral:
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.JSDocRecordType:
|
||||
// Interface/Object-types always have their children added to the 'members' of
|
||||
// their container. They are only accessible through an instance of their
|
||||
// container, and are never in scope otherwise (even inside the body of the
|
||||
@@ -801,6 +843,7 @@ namespace ts {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.JSDocFunctionType:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
// All the children of these container types are never visible through another
|
||||
// symbol (i.e. through another symbol's 'exports' or 'members'). Instead,
|
||||
@@ -882,7 +925,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function bindFunctionOrConstructorType(node: SignatureDeclaration) {
|
||||
function bindFunctionOrConstructorType(node: SignatureDeclaration): void {
|
||||
// For a given function symbol "<...>(...) => T" we want to generate a symbol identical
|
||||
// to the one we would get for: { <...>(...): T }
|
||||
//
|
||||
@@ -957,7 +1000,7 @@ namespace ts {
|
||||
declareModuleMember(node, symbolFlags, symbolExcludes);
|
||||
break;
|
||||
}
|
||||
// fall through.
|
||||
// fall through.
|
||||
default:
|
||||
if (!blockScopeContainer.locals) {
|
||||
blockScopeContainer.locals = {};
|
||||
@@ -1236,12 +1279,14 @@ namespace ts {
|
||||
return bindVariableDeclarationOrBindingElement(<VariableDeclaration | BindingElement>node);
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.PropertySignature:
|
||||
case SyntaxKind.JSDocRecordMember:
|
||||
return bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.Property | ((<PropertyDeclaration>node).questionToken ? SymbolFlags.Optional : SymbolFlags.None), SymbolFlags.PropertyExcludes);
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
return bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
|
||||
case SyntaxKind.EnumMember:
|
||||
return bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.EnumMember, SymbolFlags.EnumMemberExcludes);
|
||||
|
||||
case SyntaxKind.CallSignature:
|
||||
case SyntaxKind.ConstructSignature:
|
||||
case SyntaxKind.IndexSignature:
|
||||
@@ -1255,8 +1300,7 @@ namespace ts {
|
||||
return bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.Method | ((<MethodDeclaration>node).questionToken ? SymbolFlags.Optional : SymbolFlags.None),
|
||||
isObjectLiteralMethod(node) ? SymbolFlags.PropertyExcludes : SymbolFlags.MethodExcludes);
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
checkStrictModeFunctionName(<FunctionDeclaration>node);
|
||||
return declareSymbolAndAddToSymbolTable(<Declaration>node, SymbolFlags.Function, SymbolFlags.FunctionExcludes);
|
||||
return bindFunctionDeclaration(<FunctionDeclaration>node);
|
||||
case SyntaxKind.Constructor:
|
||||
return declareSymbolAndAddToSymbolTable(<Declaration>node, SymbolFlags.Constructor, /*symbolExcludes:*/ SymbolFlags.None);
|
||||
case SyntaxKind.GetAccessor:
|
||||
@@ -1265,16 +1309,16 @@ namespace ts {
|
||||
return bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.SetAccessor, SymbolFlags.SetAccessorExcludes);
|
||||
case SyntaxKind.FunctionType:
|
||||
case SyntaxKind.ConstructorType:
|
||||
case SyntaxKind.JSDocFunctionType:
|
||||
return bindFunctionOrConstructorType(<SignatureDeclaration>node);
|
||||
case SyntaxKind.TypeLiteral:
|
||||
case SyntaxKind.JSDocRecordType:
|
||||
return bindAnonymousDeclaration(<TypeLiteralNode>node, SymbolFlags.TypeLiteral, "__type");
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
return bindObjectLiteralExpression(<ObjectLiteralExpression>node);
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
checkStrictModeFunctionName(<FunctionExpression>node);
|
||||
const bindingName = (<FunctionExpression>node).name ? (<FunctionExpression>node).name.text : "__function";
|
||||
return bindAnonymousDeclaration(<FunctionExpression>node, SymbolFlags.Function, bindingName);
|
||||
return bindFunctionExpression(<FunctionExpression>node);
|
||||
|
||||
case SyntaxKind.CallExpression:
|
||||
if (isInJavaScriptFile(node)) {
|
||||
@@ -1424,6 +1468,15 @@ namespace ts {
|
||||
}
|
||||
|
||||
function bindClassLikeDeclaration(node: ClassLikeDeclaration) {
|
||||
if (!isDeclarationFile(file) && !isInAmbientContext(node)) {
|
||||
if (getClassExtendsHeritageClauseElement(node) !== undefined) {
|
||||
hasClassExtends = true;
|
||||
}
|
||||
if (nodeIsDecorated(node)) {
|
||||
hasDecorators = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (node.kind === SyntaxKind.ClassDeclaration) {
|
||||
bindBlockScopedDeclaration(node, SymbolFlags.Class, SymbolFlags.ClassExcludes);
|
||||
}
|
||||
@@ -1493,6 +1546,13 @@ namespace ts {
|
||||
}
|
||||
|
||||
function bindParameter(node: ParameterDeclaration) {
|
||||
if (!isDeclarationFile(file) &&
|
||||
!isInAmbientContext(node) &&
|
||||
nodeIsDecorated(node)) {
|
||||
hasDecorators = true;
|
||||
hasParameterDecorators = true;
|
||||
}
|
||||
|
||||
if (inStrictMode) {
|
||||
// It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a
|
||||
// strict mode FunctionLikeDeclaration or FunctionExpression(13.1)
|
||||
@@ -1514,7 +1574,39 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function bindFunctionDeclaration(node: FunctionDeclaration) {
|
||||
if (!isDeclarationFile(file) && !isInAmbientContext(node)) {
|
||||
if (isAsyncFunctionLike(node)) {
|
||||
hasAsyncFunctions = true;
|
||||
}
|
||||
}
|
||||
|
||||
checkStrictModeFunctionName(<FunctionDeclaration>node);
|
||||
return declareSymbolAndAddToSymbolTable(<Declaration>node, SymbolFlags.Function, SymbolFlags.FunctionExcludes);
|
||||
}
|
||||
|
||||
function bindFunctionExpression(node: FunctionExpression) {
|
||||
if (!isDeclarationFile(file) && !isInAmbientContext(node)) {
|
||||
if (isAsyncFunctionLike(node)) {
|
||||
hasAsyncFunctions = true;
|
||||
}
|
||||
}
|
||||
|
||||
checkStrictModeFunctionName(<FunctionExpression>node);
|
||||
const bindingName = (<FunctionExpression>node).name ? (<FunctionExpression>node).name.text : "__function";
|
||||
return bindAnonymousDeclaration(<FunctionExpression>node, SymbolFlags.Function, bindingName);
|
||||
}
|
||||
|
||||
function bindPropertyOrMethodOrAccessor(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) {
|
||||
if (!isDeclarationFile(file) && !isInAmbientContext(node)) {
|
||||
if (isAsyncFunctionLike(node)) {
|
||||
hasAsyncFunctions = true;
|
||||
}
|
||||
if (nodeIsDecorated(node)) {
|
||||
hasDecorators = true;
|
||||
}
|
||||
}
|
||||
|
||||
return hasDynamicName(node)
|
||||
? bindAnonymousDeclaration(node, symbolFlags, "__computed")
|
||||
: declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
|
||||
|
||||
+254
-81
@@ -178,11 +178,6 @@ namespace ts {
|
||||
const unionTypes: Map<UnionType> = {};
|
||||
const intersectionTypes: Map<IntersectionType> = {};
|
||||
const stringLiteralTypes: Map<StringLiteralType> = {};
|
||||
let emitExtends = false;
|
||||
let emitDecorate = false;
|
||||
let emitParam = false;
|
||||
let emitAwaiter = false;
|
||||
const emitGenerator = false;
|
||||
|
||||
const resolutionTargets: TypeSystemEntity[] = [];
|
||||
const resolutionResults: boolean[] = [];
|
||||
@@ -462,7 +457,7 @@ namespace ts {
|
||||
* Get symbols that represent parameter-property-declaration as parameter and as property declaration
|
||||
* @param parameter a parameterDeclaration node
|
||||
* @param parameterName a name of the parameter to get the symbols for.
|
||||
* @return a tuple of two symbols
|
||||
* @return a tuple of two symbols
|
||||
*/
|
||||
function getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: string): [Symbol, Symbol] {
|
||||
const constructoDeclaration = parameter.parent;
|
||||
@@ -566,7 +561,9 @@ namespace ts {
|
||||
// - Type parameters of a function are in scope in the entire function declaration, including the parameter
|
||||
// list and return type. However, local types are only in scope in the function body.
|
||||
// - parameters are only in the scope of function body
|
||||
if (meaning & result.flags & SymbolFlags.Type) {
|
||||
// This restriction does not apply to JSDoc comment types because they are parented
|
||||
// at a higher level than type parameters would normally be
|
||||
if (meaning & result.flags & SymbolFlags.Type && lastLocation.kind !== SyntaxKind.JSDocComment) {
|
||||
useResult = result.flags & SymbolFlags.TypeParameter
|
||||
// type parameters are visible in parameter list, return type and type parameter list
|
||||
? lastLocation === (<FunctionLikeDeclaration>location).type ||
|
||||
@@ -2588,8 +2585,54 @@ namespace ts {
|
||||
return type;
|
||||
}
|
||||
|
||||
function getTypeForVariableLikeDeclarationFromJSDocComment(declaration: VariableLikeDeclaration) {
|
||||
const jsDocType = getJSDocTypeForVariableLikeDeclarationFromJSDocComment(declaration);
|
||||
if (jsDocType) {
|
||||
return getTypeFromTypeNode(jsDocType);
|
||||
}
|
||||
}
|
||||
|
||||
function getJSDocTypeForVariableLikeDeclarationFromJSDocComment(declaration: VariableLikeDeclaration): JSDocType {
|
||||
// First, see if this node has an @type annotation on it directly.
|
||||
const typeTag = getJSDocTypeTag(declaration);
|
||||
if (typeTag) {
|
||||
return typeTag.typeExpression.type;
|
||||
}
|
||||
|
||||
if (declaration.kind === SyntaxKind.VariableDeclaration &&
|
||||
declaration.parent.kind === SyntaxKind.VariableDeclarationList &&
|
||||
declaration.parent.parent.kind === SyntaxKind.VariableStatement) {
|
||||
|
||||
// @type annotation might have been on the variable statement, try that instead.
|
||||
const annotation = getJSDocTypeTag(declaration.parent.parent);
|
||||
if (annotation) {
|
||||
return annotation.typeExpression.type;
|
||||
}
|
||||
}
|
||||
else if (declaration.kind === SyntaxKind.Parameter) {
|
||||
// If it's a parameter, see if the parent has a jsdoc comment with an @param
|
||||
// annotation.
|
||||
const paramTag = getCorrespondingJSDocParameterTag(<ParameterDeclaration>declaration);
|
||||
if (paramTag && paramTag.typeExpression) {
|
||||
return paramTag.typeExpression.type;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Return the inferred type for a variable, parameter, or property declaration
|
||||
function getTypeForVariableLikeDeclaration(declaration: VariableLikeDeclaration): Type {
|
||||
if (declaration.parserContextFlags & ParserContextFlags.JavaScriptFile) {
|
||||
// If this is a variable in a JavaScript file, then use the JSDoc type (if it has
|
||||
// one as its type), otherwise fallback to the below standard TS codepaths to
|
||||
// try to figure it out.
|
||||
const type = getTypeForVariableLikeDeclarationFromJSDocComment(declaration);
|
||||
if (type && type !== unknownType) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
// A variable declared in a for..in statement is always of type string
|
||||
if (declaration.parent.parent.kind === SyntaxKind.ForInStatement) {
|
||||
return stringType;
|
||||
@@ -3926,6 +3969,17 @@ namespace ts {
|
||||
return getIndexTypeOfStructuredType(getApparentType(type), kind);
|
||||
}
|
||||
|
||||
function getTypeParametersFromJSDocTemplate(declaration: SignatureDeclaration): TypeParameter[] {
|
||||
if (declaration.parserContextFlags & ParserContextFlags.JavaScriptFile) {
|
||||
const templateTag = getJSDocTemplateTag(declaration);
|
||||
if (templateTag) {
|
||||
return getTypeParametersFromDeclaration(templateTag.typeParameters);
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Return list of type parameters with duplicates removed (duplicate identifier errors are generated in the actual
|
||||
// type checking functions).
|
||||
function getTypeParametersFromDeclaration(typeParameterDeclarations: TypeParameterDeclaration[]): TypeParameter[] {
|
||||
@@ -3950,6 +4004,23 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isOptionalParameter(node: ParameterDeclaration) {
|
||||
if (node.parserContextFlags & ParserContextFlags.JavaScriptFile) {
|
||||
if (node.type && node.type.kind === SyntaxKind.JSDocOptionalType) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const paramTag = getCorrespondingJSDocParameterTag(node);
|
||||
if (paramTag) {
|
||||
if (paramTag.isBracketed) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (paramTag.typeExpression) {
|
||||
return paramTag.typeExpression.type.kind === SyntaxKind.JSDocOptionalType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasQuestionToken(node)) {
|
||||
return true;
|
||||
}
|
||||
@@ -3990,12 +4061,20 @@ namespace ts {
|
||||
getDeclaredTypeOfClassOrInterface(getMergedSymbol((<ClassDeclaration>declaration.parent).symbol))
|
||||
: undefined;
|
||||
const typeParameters = classType ? classType.localTypeParameters :
|
||||
declaration.typeParameters ? getTypeParametersFromDeclaration(declaration.typeParameters) : undefined;
|
||||
declaration.typeParameters ? getTypeParametersFromDeclaration(declaration.typeParameters) :
|
||||
getTypeParametersFromJSDocTemplate(declaration);
|
||||
const parameters: Symbol[] = [];
|
||||
let hasStringLiterals = false;
|
||||
let minArgumentCount = -1;
|
||||
for (let i = 0, n = declaration.parameters.length; i < n; i++) {
|
||||
const isJSConstructSignature = isJSDocConstructSignature(declaration);
|
||||
let returnType: Type = undefined;
|
||||
|
||||
// If this is a JSDoc construct signature, then skip the first parameter in the
|
||||
// parameter list. The first parameter represents the return type of the construct
|
||||
// signature.
|
||||
for (let i = isJSConstructSignature ? 1 : 0, n = declaration.parameters.length; i < n; i++) {
|
||||
const param = declaration.parameters[i];
|
||||
|
||||
let paramSymbol = param.symbol;
|
||||
// Include parameter symbol instead of property symbol in the signature
|
||||
if (paramSymbol && !!(paramSymbol.flags & SymbolFlags.Property) && !isBindingPattern(param.name)) {
|
||||
@@ -4003,6 +4082,7 @@ namespace ts {
|
||||
paramSymbol = resolvedSymbol;
|
||||
}
|
||||
parameters.push(paramSymbol);
|
||||
|
||||
if (param.type && param.type.kind === SyntaxKind.StringLiteralType) {
|
||||
hasStringLiterals = true;
|
||||
}
|
||||
@@ -4022,14 +4102,24 @@ namespace ts {
|
||||
minArgumentCount = declaration.parameters.length;
|
||||
}
|
||||
|
||||
let returnType: Type;
|
||||
if (classType) {
|
||||
if (isJSConstructSignature) {
|
||||
minArgumentCount--;
|
||||
returnType = getTypeFromTypeNode(declaration.parameters[0].type);
|
||||
}
|
||||
else if (classType) {
|
||||
returnType = classType;
|
||||
}
|
||||
else if (declaration.type) {
|
||||
returnType = getTypeFromTypeNode(declaration.type);
|
||||
}
|
||||
else {
|
||||
if (declaration.parserContextFlags & ParserContextFlags.JavaScriptFile) {
|
||||
const type = getReturnTypeFromJSDocComment(declaration);
|
||||
if (type && type !== unknownType) {
|
||||
returnType = type;
|
||||
}
|
||||
}
|
||||
|
||||
// TypeScript 1.0 spec (April 2014):
|
||||
// If only one accessor includes a type annotation, the other behaves as if it had the same type annotation.
|
||||
if (declaration.kind === SyntaxKind.GetAccessor && !hasDynamicName(declaration)) {
|
||||
@@ -4066,6 +4156,7 @@ namespace ts {
|
||||
case SyntaxKind.SetAccessor:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.JSDocFunctionType:
|
||||
// Don't include signature if node is the implementation of an overloaded function. A node is considered
|
||||
// an implementation node if it has a body and the previous node is of the same kind and immediately
|
||||
// precedes the implementation node (i.e. has the same parent and ends where the implementation starts).
|
||||
@@ -4291,7 +4382,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Get type from reference to class or interface
|
||||
function getTypeFromClassOrInterfaceReference(node: TypeReferenceNode | ExpressionWithTypeArguments, symbol: Symbol): Type {
|
||||
function getTypeFromClassOrInterfaceReference(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference, symbol: Symbol): Type {
|
||||
const type = <InterfaceType>getDeclaredTypeOfSymbol(symbol);
|
||||
const typeParameters = type.localTypeParameters;
|
||||
if (typeParameters) {
|
||||
@@ -4314,7 +4405,7 @@ namespace ts {
|
||||
// Get type from reference to type alias. When a type alias is generic, the declared type of the type alias may include
|
||||
// references to the type parameters of the alias. We replace those with the actual type arguments by instantiating the
|
||||
// declared type. Instantiations are cached using the type identities of the type arguments as the key.
|
||||
function getTypeFromTypeAliasReference(node: TypeReferenceNode | ExpressionWithTypeArguments, symbol: Symbol): Type {
|
||||
function getTypeFromTypeAliasReference(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference, symbol: Symbol): Type {
|
||||
const type = getDeclaredTypeOfSymbol(symbol);
|
||||
const links = getSymbolLinks(symbol);
|
||||
const typeParameters = links.typeParameters;
|
||||
@@ -4335,7 +4426,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Get type from reference to named type that cannot be generic (enum or type parameter)
|
||||
function getTypeFromNonGenericTypeReference(node: TypeReferenceNode | ExpressionWithTypeArguments, symbol: Symbol): Type {
|
||||
function getTypeFromNonGenericTypeReference(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference, symbol: Symbol): Type {
|
||||
if (node.typeArguments) {
|
||||
error(node, Diagnostics.Type_0_is_not_generic, symbolToString(symbol));
|
||||
return unknownType;
|
||||
@@ -4343,18 +4434,83 @@ namespace ts {
|
||||
return getDeclaredTypeOfSymbol(symbol);
|
||||
}
|
||||
|
||||
function getTypeFromTypeReference(node: TypeReferenceNode | ExpressionWithTypeArguments): Type {
|
||||
function getTypeReferenceName(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference): LeftHandSideExpression | EntityName {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.TypeReference:
|
||||
return (<TypeReferenceNode>node).typeName;
|
||||
case SyntaxKind.JSDocTypeReference:
|
||||
return (<JSDocTypeReference>node).name;
|
||||
case SyntaxKind.ExpressionWithTypeArguments:
|
||||
// We only support expressions that are simple qualified names. For other
|
||||
// expressions this produces undefined.
|
||||
if (isSupportedExpressionWithTypeArguments(<ExpressionWithTypeArguments>node)) {
|
||||
return (<ExpressionWithTypeArguments>node).expression;
|
||||
}
|
||||
|
||||
// fall through;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function resolveTypeReferenceName(
|
||||
node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference,
|
||||
typeReferenceName: LeftHandSideExpression | EntityName) {
|
||||
|
||||
if (!typeReferenceName) {
|
||||
return unknownSymbol;
|
||||
}
|
||||
|
||||
return resolveEntityName(typeReferenceName, SymbolFlags.Type) || unknownSymbol;
|
||||
}
|
||||
|
||||
function getTypeReferenceType(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference, symbol: Symbol) {
|
||||
if (symbol === unknownSymbol) {
|
||||
return unknownType;
|
||||
}
|
||||
|
||||
if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
|
||||
return getTypeFromClassOrInterfaceReference(node, symbol);
|
||||
}
|
||||
|
||||
if (symbol.flags & SymbolFlags.TypeAlias) {
|
||||
return getTypeFromTypeAliasReference(node, symbol);
|
||||
}
|
||||
|
||||
if (symbol.flags & SymbolFlags.Value && node.kind === SyntaxKind.JSDocTypeReference) {
|
||||
// A JSDocTypeReference may have resolved to a value (as opposed to a type). In
|
||||
// that case, the type of this reference is just the type of the value we resolved
|
||||
// to.
|
||||
return getTypeOfSymbol(symbol);
|
||||
}
|
||||
|
||||
return getTypeFromNonGenericTypeReference(node, symbol);
|
||||
}
|
||||
|
||||
function getTypeFromTypeReference(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference): Type {
|
||||
const links = getNodeLinks(node);
|
||||
if (!links.resolvedType) {
|
||||
// We only support expressions that are simple qualified names. For other expressions this produces undefined.
|
||||
const typeNameOrExpression = node.kind === SyntaxKind.TypeReference ? (<TypeReferenceNode>node).typeName :
|
||||
isSupportedExpressionWithTypeArguments(<ExpressionWithTypeArguments>node) ? (<ExpressionWithTypeArguments>node).expression :
|
||||
undefined;
|
||||
const symbol = typeNameOrExpression && resolveEntityName(typeNameOrExpression, SymbolFlags.Type) || unknownSymbol;
|
||||
const type = symbol === unknownSymbol ? unknownType :
|
||||
symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface) ? getTypeFromClassOrInterfaceReference(node, symbol) :
|
||||
symbol.flags & SymbolFlags.TypeAlias ? getTypeFromTypeAliasReference(node, symbol) :
|
||||
getTypeFromNonGenericTypeReference(node, symbol);
|
||||
let symbol: Symbol;
|
||||
let type: Type;
|
||||
if (node.kind === SyntaxKind.JSDocTypeReference) {
|
||||
const typeReferenceName = getTypeReferenceName(node);
|
||||
symbol = resolveTypeReferenceName(node, typeReferenceName);
|
||||
type = getTypeReferenceType(node, symbol);
|
||||
|
||||
links.resolvedSymbol = symbol;
|
||||
links.resolvedType = type;
|
||||
}
|
||||
else {
|
||||
// We only support expressions that are simple qualified names. For other expressions this produces undefined.
|
||||
const typeNameOrExpression = node.kind === SyntaxKind.TypeReference ? (<TypeReferenceNode>node).typeName :
|
||||
isSupportedExpressionWithTypeArguments(<ExpressionWithTypeArguments>node) ? (<ExpressionWithTypeArguments>node).expression :
|
||||
undefined;
|
||||
symbol = typeNameOrExpression && resolveEntityName(typeNameOrExpression, SymbolFlags.Type) || unknownSymbol;
|
||||
type = symbol === unknownSymbol ? unknownType :
|
||||
symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface) ? getTypeFromClassOrInterfaceReference(node, symbol) :
|
||||
symbol.flags & SymbolFlags.TypeAlias ? getTypeFromTypeAliasReference(node, symbol) :
|
||||
getTypeFromNonGenericTypeReference(node, symbol);
|
||||
}
|
||||
// Cache both the resolved symbol and the resolved type. The resolved symbol is needed in when we check the
|
||||
// type reference in checkTypeReferenceOrExpressionWithTypeArguments.
|
||||
links.resolvedSymbol = symbol;
|
||||
@@ -4649,6 +4805,24 @@ namespace ts {
|
||||
return links.resolvedType;
|
||||
}
|
||||
|
||||
function getTypeFromJSDocVariadicType(node: JSDocVariadicType): Type {
|
||||
const links = getNodeLinks(node);
|
||||
if (!links.resolvedType) {
|
||||
const type = getTypeFromTypeNode(node.type);
|
||||
links.resolvedType = type ? createArrayType(type) : unknownType;
|
||||
}
|
||||
return links.resolvedType;
|
||||
}
|
||||
|
||||
function getTypeFromJSDocTupleType(node: JSDocTupleType): Type {
|
||||
const links = getNodeLinks(node);
|
||||
if (!links.resolvedType) {
|
||||
const types = map(node.types, getTypeFromTypeNode);
|
||||
links.resolvedType = createTupleType(types);
|
||||
}
|
||||
return links.resolvedType;
|
||||
}
|
||||
|
||||
function getThisType(node: TypeNode): Type {
|
||||
const container = getThisContainer(node, /*includeArrowFunctions*/ false);
|
||||
const parent = container && container.parent;
|
||||
@@ -4692,6 +4866,8 @@ namespace ts {
|
||||
function getTypeFromTypeNode(node: TypeNode): Type {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.AnyKeyword:
|
||||
case SyntaxKind.JSDocAllType:
|
||||
case SyntaxKind.JSDocUnknownType:
|
||||
return anyType;
|
||||
case SyntaxKind.StringKeyword:
|
||||
return stringType;
|
||||
@@ -4708,6 +4884,7 @@ namespace ts {
|
||||
case SyntaxKind.StringLiteralType:
|
||||
return getTypeFromStringLiteralTypeNode(<StringLiteralTypeNode>node);
|
||||
case SyntaxKind.TypeReference:
|
||||
case SyntaxKind.JSDocTypeReference:
|
||||
return getTypeFromTypeReference(<TypeReferenceNode>node);
|
||||
case SyntaxKind.TypePredicate:
|
||||
return getTypeFromPredicateTypeNode(<TypePredicateNode>node);
|
||||
@@ -4716,18 +4893,27 @@ namespace ts {
|
||||
case SyntaxKind.TypeQuery:
|
||||
return getTypeFromTypeQueryNode(<TypeQueryNode>node);
|
||||
case SyntaxKind.ArrayType:
|
||||
case SyntaxKind.JSDocArrayType:
|
||||
return getTypeFromArrayTypeNode(<ArrayTypeNode>node);
|
||||
case SyntaxKind.TupleType:
|
||||
return getTypeFromTupleTypeNode(<TupleTypeNode>node);
|
||||
case SyntaxKind.UnionType:
|
||||
case SyntaxKind.JSDocUnionType:
|
||||
return getTypeFromUnionTypeNode(<UnionTypeNode>node);
|
||||
case SyntaxKind.IntersectionType:
|
||||
return getTypeFromIntersectionTypeNode(<IntersectionTypeNode>node);
|
||||
case SyntaxKind.ParenthesizedType:
|
||||
return getTypeFromTypeNode((<ParenthesizedTypeNode>node).type);
|
||||
case SyntaxKind.JSDocNullableType:
|
||||
case SyntaxKind.JSDocNonNullableType:
|
||||
case SyntaxKind.JSDocConstructorType:
|
||||
case SyntaxKind.JSDocThisType:
|
||||
case SyntaxKind.JSDocOptionalType:
|
||||
return getTypeFromTypeNode((<ParenthesizedTypeNode | JSDocTypeReferencingNode>node).type);
|
||||
case SyntaxKind.FunctionType:
|
||||
case SyntaxKind.ConstructorType:
|
||||
case SyntaxKind.TypeLiteral:
|
||||
case SyntaxKind.JSDocFunctionType:
|
||||
case SyntaxKind.JSDocRecordType:
|
||||
return getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node);
|
||||
// This function assumes that an identifier or qualified name is a type expression
|
||||
// Callers should first ensure this by calling isTypeNode
|
||||
@@ -4735,6 +4921,10 @@ namespace ts {
|
||||
case SyntaxKind.QualifiedName:
|
||||
const symbol = getSymbolAtLocation(node);
|
||||
return symbol && getDeclaredTypeOfSymbol(symbol);
|
||||
case SyntaxKind.JSDocTupleType:
|
||||
return getTypeFromJSDocTupleType(<JSDocTupleType>node);
|
||||
case SyntaxKind.JSDocVariadicType:
|
||||
return getTypeFromJSDocVariadicType(<JSDocVariadicType>node);
|
||||
default:
|
||||
return unknownType;
|
||||
}
|
||||
@@ -7120,18 +7310,25 @@ namespace ts {
|
||||
return container.flags & NodeFlags.Static ? getTypeOfSymbol(symbol) : (<InterfaceType>getDeclaredTypeOfSymbol(symbol)).thisType;
|
||||
}
|
||||
|
||||
// If this is a function in a JS file, it might be a class method. Check if it's the RHS
|
||||
// of a x.prototype.y = function [name]() { .... }
|
||||
if (isInJavaScriptFile(node) && container.kind === SyntaxKind.FunctionExpression) {
|
||||
if (getSpecialPropertyAssignmentKind(container.parent) === SpecialPropertyAssignmentKind.PrototypeProperty) {
|
||||
// Get the 'x' of 'x.prototype.y = f' (here, 'f' is 'container')
|
||||
const className = (((container.parent as BinaryExpression) // x.protoype.y = f
|
||||
.left as PropertyAccessExpression) // x.prototype.y
|
||||
.expression as PropertyAccessExpression) // x.prototype
|
||||
.expression; // x
|
||||
const classSymbol = checkExpression(className).symbol;
|
||||
if (classSymbol && classSymbol.members && (classSymbol.flags & SymbolFlags.Function)) {
|
||||
return getInferredClassType(classSymbol);
|
||||
if (isInJavaScriptFile(node)) {
|
||||
const type = getTypeForThisExpressionFromJSDoc(container);
|
||||
if (type && type !== unknownType) {
|
||||
return type;
|
||||
}
|
||||
|
||||
// If this is a function in a JS file, it might be a class method. Check if it's the RHS
|
||||
// of a x.prototype.y = function [name]() { .... }
|
||||
if (container.kind === SyntaxKind.FunctionExpression) {
|
||||
if (getSpecialPropertyAssignmentKind(container.parent) === SpecialPropertyAssignmentKind.PrototypeProperty) {
|
||||
// Get the 'x' of 'x.prototype.y = f' (here, 'f' is 'container')
|
||||
const className = (((container.parent as BinaryExpression) // x.protoype.y = f
|
||||
.left as PropertyAccessExpression) // x.prototype.y
|
||||
.expression as PropertyAccessExpression) // x.prototype
|
||||
.expression; // x
|
||||
const classSymbol = checkExpression(className).symbol;
|
||||
if (classSymbol && classSymbol.members && (classSymbol.flags & SymbolFlags.Function)) {
|
||||
return getInferredClassType(classSymbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7139,6 +7336,16 @@ namespace ts {
|
||||
return anyType;
|
||||
}
|
||||
|
||||
function getTypeForThisExpressionFromJSDoc(node: Node) {
|
||||
const typeTag = getJSDocTypeTag(node);
|
||||
if (typeTag && typeTag.typeExpression.type.kind === SyntaxKind.JSDocFunctionType) {
|
||||
const jsDocFunctionType = <JSDocFunctionType>typeTag.typeExpression.type;
|
||||
if (jsDocFunctionType.parameters.length > 0 && jsDocFunctionType.parameters[0].type.kind === SyntaxKind.JSDocThisType) {
|
||||
return getTypeFromTypeNode(jsDocFunctionType.parameters[0].type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isInConstructorArgumentInitializer(node: Node, constructorDecl: Node): boolean {
|
||||
for (let n = node; n && n !== constructorDecl; n = n.parent) {
|
||||
if (n.kind === SyntaxKind.Parameter) {
|
||||
@@ -9948,7 +10155,8 @@ namespace ts {
|
||||
if (declaration &&
|
||||
declaration.kind !== SyntaxKind.Constructor &&
|
||||
declaration.kind !== SyntaxKind.ConstructSignature &&
|
||||
declaration.kind !== SyntaxKind.ConstructorType) {
|
||||
declaration.kind !== SyntaxKind.ConstructorType &&
|
||||
!isJSDocConstructSignature(declaration)) {
|
||||
|
||||
// When resolved signature is a call signature (and not a construct signature) the result type is any, unless
|
||||
// the declaring function had members created through 'x.prototype.y = expr' or 'this.y = expr' psuedodeclarations
|
||||
@@ -10068,6 +10276,13 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getReturnTypeFromJSDocComment(func: SignatureDeclaration | FunctionDeclaration): Type {
|
||||
const returnTag = getJSDocReturnTag(func);
|
||||
if (returnTag) {
|
||||
return getTypeFromTypeNode(returnTag.typeExpression.type);
|
||||
}
|
||||
}
|
||||
|
||||
function createPromiseType(promisedType: Type): Type {
|
||||
// creates a `Promise<T>` type where `T` is the promisedType argument
|
||||
const globalPromiseType = getGlobalPromiseType();
|
||||
@@ -10278,11 +10493,6 @@ namespace ts {
|
||||
return anyFunctionType;
|
||||
}
|
||||
|
||||
const isAsync = isAsyncFunctionLike(node);
|
||||
if (isAsync) {
|
||||
emitAwaiter = true;
|
||||
}
|
||||
|
||||
const links = getNodeLinks(node);
|
||||
const type = getTypeOfSymbol(node.symbol);
|
||||
const contextSensitive = isContextSensitive(node);
|
||||
@@ -10331,10 +10541,6 @@ namespace ts {
|
||||
Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
|
||||
|
||||
const isAsync = isAsyncFunctionLike(node);
|
||||
if (isAsync) {
|
||||
emitAwaiter = true;
|
||||
}
|
||||
|
||||
const returnOrPromisedType = node.type && (isAsync ? checkAsyncFunctionReturnType(node) : getTypeFromTypeNode(node.type));
|
||||
if (!node.asteriskToken) {
|
||||
// return is not necessary in the body of generators
|
||||
@@ -12470,11 +12676,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
emitDecorate = true;
|
||||
if (node.kind === SyntaxKind.Parameter) {
|
||||
emitParam = true;
|
||||
}
|
||||
|
||||
forEach(node.decorators, checkDecorator);
|
||||
}
|
||||
|
||||
@@ -12492,9 +12693,6 @@ namespace ts {
|
||||
checkDecorators(node);
|
||||
checkSignatureDeclaration(node);
|
||||
const isAsync = isAsyncFunctionLike(node);
|
||||
if (isAsync) {
|
||||
emitAwaiter = true;
|
||||
}
|
||||
|
||||
// Do not use hasDynamicName here, because that returns false for well known symbols.
|
||||
// We want to perform checkComputedPropertyName for all computed properties, including
|
||||
@@ -13626,7 +13824,6 @@ namespace ts {
|
||||
|
||||
const baseTypeNode = getClassExtendsHeritageClauseElement(node);
|
||||
if (baseTypeNode) {
|
||||
emitExtends = emitExtends || !isInAmbientContext(node);
|
||||
const baseTypes = getBaseTypes(type);
|
||||
if (baseTypes.length && produceDiagnostics) {
|
||||
const baseType = baseTypes[0];
|
||||
@@ -14528,7 +14725,7 @@ namespace ts {
|
||||
// find immediate value referenced by exported name (SymbolFlags.Alias is set so we don't chase down aliases)
|
||||
const symbol = resolveName(exportedName, exportedName.text, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias,
|
||||
/*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined);
|
||||
if (symbol && isGlobalSourceFile(getDeclarationContainer(symbol.declarations[0]))) {
|
||||
if (symbol && (symbol === undefinedSymbol || isGlobalSourceFile(getDeclarationContainer(symbol.declarations[0])))) {
|
||||
error(exportedName, Diagnostics.Cannot_re_export_name_that_is_not_defined_in_the_module);
|
||||
}
|
||||
else {
|
||||
@@ -14806,10 +15003,6 @@ namespace ts {
|
||||
// Grammar checking
|
||||
checkGrammarSourceFile(node);
|
||||
|
||||
emitExtends = false;
|
||||
emitDecorate = false;
|
||||
emitParam = false;
|
||||
emitAwaiter = false;
|
||||
potentialThisCollisions.length = 0;
|
||||
|
||||
deferredNodes = [];
|
||||
@@ -14826,26 +15019,6 @@ namespace ts {
|
||||
potentialThisCollisions.length = 0;
|
||||
}
|
||||
|
||||
if (emitExtends) {
|
||||
links.flags |= NodeCheckFlags.EmitExtends;
|
||||
}
|
||||
|
||||
if (emitDecorate) {
|
||||
links.flags |= NodeCheckFlags.EmitDecorate;
|
||||
}
|
||||
|
||||
if (emitParam) {
|
||||
links.flags |= NodeCheckFlags.EmitParam;
|
||||
}
|
||||
|
||||
if (emitAwaiter) {
|
||||
links.flags |= NodeCheckFlags.EmitAwaiter;
|
||||
}
|
||||
|
||||
if (emitGenerator || (emitAwaiter && languageVersion < ScriptTarget.ES6)) {
|
||||
links.flags |= NodeCheckFlags.EmitGenerator;
|
||||
}
|
||||
|
||||
links.flags |= NodeCheckFlags.TypeChecked;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -493,8 +493,8 @@ namespace ts {
|
||||
* @param basePath A root directory to resolve relative path entries in the config
|
||||
* file to. e.g. outDir
|
||||
*/
|
||||
export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string, existingOptions: CompilerOptions = {}): ParsedCommandLine {
|
||||
const { options: optionsFromJsonConfigFile, errors } = convertCompilerOptionsFromJson(json["compilerOptions"], basePath);
|
||||
export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string, existingOptions: CompilerOptions = {}, configFileName?: string): ParsedCommandLine {
|
||||
const { options: optionsFromJsonConfigFile, errors } = convertCompilerOptionsFromJson(json["compilerOptions"], basePath, configFileName);
|
||||
|
||||
const options = extend(existingOptions, optionsFromJsonConfigFile);
|
||||
return {
|
||||
@@ -523,7 +523,7 @@ namespace ts {
|
||||
for (const extension of supportedExtensions) {
|
||||
const filesInDirWithExtension = host.readDirectory(basePath, extension, exclude);
|
||||
for (const fileName of filesInDirWithExtension) {
|
||||
// .ts extension would read the .d.ts extension files too but since .d.ts is lower priority extension,
|
||||
// .ts extension would read the .d.ts extension files too but since .d.ts is lower priority extension,
|
||||
// lets pick them when its turn comes up
|
||||
if (extension === ".ts" && fileExtensionIs(fileName, ".d.ts")) {
|
||||
continue;
|
||||
@@ -547,10 +547,15 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function convertCompilerOptionsFromJson(jsonOptions: any, basePath: string): { options: CompilerOptions, errors: Diagnostic[] } {
|
||||
export function convertCompilerOptionsFromJson(jsonOptions: any, basePath: string, configFileName?: string): { options: CompilerOptions, errors: Diagnostic[] } {
|
||||
const options: CompilerOptions = {};
|
||||
const errors: Diagnostic[] = [];
|
||||
|
||||
if (configFileName && getBaseFileName(configFileName) === "jsconfig.json") {
|
||||
options.module = ModuleKind.CommonJS;
|
||||
options.allowJs = true;
|
||||
}
|
||||
|
||||
if (!jsonOptions) {
|
||||
return { options, errors };
|
||||
}
|
||||
|
||||
+10
-15
@@ -319,17 +319,12 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
};`;
|
||||
|
||||
const awaiterHelper = `
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promise, generator) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
generator = generator.call(thisArg, _arguments);
|
||||
function cast(value) { return value instanceof Promise && value.constructor === Promise ? value : new Promise(function (resolve) { resolve(value); }); }
|
||||
function onfulfill(value) { try { step("next", value); } catch (e) { reject(e); } }
|
||||
function onreject(value) { try { step("throw", value); } catch (e) { reject(e); } }
|
||||
function step(verb, value) {
|
||||
var result = generator[verb](value);
|
||||
result.done ? resolve(result.value) : cast(result.value).then(onfulfill, onreject);
|
||||
}
|
||||
step("next", void 0);
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new P(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.call(thisArg, _arguments)).next());
|
||||
});
|
||||
};`;
|
||||
|
||||
@@ -7354,12 +7349,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
if (!compilerOptions.noEmitHelpers) {
|
||||
// Only Emit __extends function when target ES5.
|
||||
// For target ES6 and above, we can emit classDeclaration as is.
|
||||
if ((languageVersion < ScriptTarget.ES6) && (!extendsEmitted && resolver.getNodeCheckFlags(node) & NodeCheckFlags.EmitExtends)) {
|
||||
if ((languageVersion < ScriptTarget.ES6) && (!extendsEmitted && node.flags & NodeFlags.HasClassExtends)) {
|
||||
writeLines(extendsHelper);
|
||||
extendsEmitted = true;
|
||||
}
|
||||
|
||||
if (!decorateEmitted && resolver.getNodeCheckFlags(node) & NodeCheckFlags.EmitDecorate) {
|
||||
if (!decorateEmitted && node.flags & NodeFlags.HasDecorators) {
|
||||
writeLines(decorateHelper);
|
||||
if (compilerOptions.emitDecoratorMetadata) {
|
||||
writeLines(metadataHelper);
|
||||
@@ -7367,12 +7362,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
decorateEmitted = true;
|
||||
}
|
||||
|
||||
if (!paramEmitted && resolver.getNodeCheckFlags(node) & NodeCheckFlags.EmitParam) {
|
||||
if (!paramEmitted && node.flags & NodeFlags.HasParamDecorators) {
|
||||
writeLines(paramHelper);
|
||||
paramEmitted = true;
|
||||
}
|
||||
|
||||
if (!awaiterEmitted && resolver.getNodeCheckFlags(node) & NodeCheckFlags.EmitAwaiter) {
|
||||
if (!awaiterEmitted && node.flags & NodeFlags.HasAsyncFunctions) {
|
||||
writeLines(awaiterHelper);
|
||||
awaiterEmitted = true;
|
||||
}
|
||||
|
||||
+134
-149
@@ -611,44 +611,24 @@ namespace ts {
|
||||
fixupParentReferences(sourceFile);
|
||||
}
|
||||
|
||||
// If this is a javascript file, proactively see if we can get JSDoc comments for
|
||||
// relevant nodes in the file. We'll use these to provide typing informaion if they're
|
||||
// available.
|
||||
if (isSourceFileJavaScript(sourceFile)) {
|
||||
addJSDocComments();
|
||||
}
|
||||
|
||||
return sourceFile;
|
||||
}
|
||||
|
||||
function addJSDocComments() {
|
||||
forEachChild(sourceFile, visit);
|
||||
return;
|
||||
|
||||
function visit(node: Node) {
|
||||
// Add additional cases as necessary depending on how we see JSDoc comments used
|
||||
// in the wild.
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.VariableStatement:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.Parameter:
|
||||
addJSDocComment(node);
|
||||
}
|
||||
|
||||
forEachChild(node, visit);
|
||||
}
|
||||
}
|
||||
|
||||
function addJSDocComment(node: Node) {
|
||||
const comments = getLeadingCommentRangesOfNode(node, sourceFile);
|
||||
if (comments) {
|
||||
for (const comment of comments) {
|
||||
const jsDocComment = JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos);
|
||||
if (jsDocComment) {
|
||||
node.jsDocComment = jsDocComment;
|
||||
function addJSDocComment<T extends Node>(node: T): T {
|
||||
if (contextFlags & ParserContextFlags.JavaScriptFile) {
|
||||
const comments = getLeadingCommentRangesOfNode(node, sourceFile);
|
||||
if (comments) {
|
||||
for (const comment of comments) {
|
||||
const jsDocComment = JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos);
|
||||
if (jsDocComment) {
|
||||
node.jsDocComment = jsDocComment;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
export function fixupParentReferences(sourceFile: Node) {
|
||||
@@ -2067,7 +2047,8 @@ namespace ts {
|
||||
// contexts. In addition, parameter initializers are semantically disallowed in
|
||||
// overload signatures. So parameter initializers are transitively disallowed in
|
||||
// ambient contexts.
|
||||
return finishNode(node);
|
||||
|
||||
return addJSDocComment(finishNode(node));
|
||||
}
|
||||
|
||||
function parseBindingElementInitializer(inParameter: boolean) {
|
||||
@@ -4742,7 +4723,7 @@ namespace ts {
|
||||
setModifiers(node, modifiers);
|
||||
node.declarationList = parseVariableDeclarationList(/*inForStatementInitializer*/ false);
|
||||
parseSemicolon();
|
||||
return finishNode(node);
|
||||
return addJSDocComment(finishNode(node));
|
||||
}
|
||||
|
||||
function parseFunctionDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray): FunctionDeclaration {
|
||||
@@ -4756,7 +4737,7 @@ namespace ts {
|
||||
const isAsync = !!(node.flags & NodeFlags.Async);
|
||||
fillSignature(SyntaxKind.ColonToken, /*yieldContext*/ isGenerator, /*awaitContext*/ isAsync, /*requireCompleteParameterList*/ false, node);
|
||||
node.body = parseFunctionBlockOrSemicolon(isGenerator, isAsync, Diagnostics.or_expected);
|
||||
return finishNode(node);
|
||||
return addJSDocComment(finishNode(node));
|
||||
}
|
||||
|
||||
function parseConstructorDeclaration(pos: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray): ConstructorDeclaration {
|
||||
@@ -5594,23 +5575,19 @@ namespace ts {
|
||||
|
||||
export function parseJSDocTypeExpressionForTests(content: string, start: number, length: number) {
|
||||
initializeState("file.js", content, ScriptTarget.Latest, /*isJavaScriptFile*/ true, /*_syntaxCursor:*/ undefined);
|
||||
const jsDocTypeExpression = parseJSDocTypeExpression(start, length);
|
||||
scanner.setText(content, start, length);
|
||||
token = scanner.scan();
|
||||
const jsDocTypeExpression = parseJSDocTypeExpression();
|
||||
const diagnostics = parseDiagnostics;
|
||||
clearState();
|
||||
|
||||
return jsDocTypeExpression ? { jsDocTypeExpression, diagnostics } : undefined;
|
||||
}
|
||||
|
||||
// Parses out a JSDoc type expression. The starting position should be right at the open
|
||||
// curly in the type expression. Returns 'undefined' if it encounters any errors while parsing.
|
||||
// Parses out a JSDoc type expression.
|
||||
/* @internal */
|
||||
export function parseJSDocTypeExpression(start: number, length: number): JSDocTypeExpression {
|
||||
scanner.setText(sourceText, start, length);
|
||||
|
||||
// Prime the first token for us to start processing.
|
||||
token = nextToken();
|
||||
|
||||
const result = <JSDocTypeExpression>createNode(SyntaxKind.JSDocTypeExpression);
|
||||
export function parseJSDocTypeExpression(): JSDocTypeExpression {
|
||||
const result = <JSDocTypeExpression>createNode(SyntaxKind.JSDocTypeExpression, scanner.getTokenPos());
|
||||
|
||||
parseExpected(SyntaxKind.OpenBraceToken);
|
||||
result.type = parseJSDocTopLevelType();
|
||||
@@ -5908,7 +5885,8 @@ namespace ts {
|
||||
|
||||
export function parseIsolatedJSDocComment(content: string, start: number, length: number) {
|
||||
initializeState("file.js", content, ScriptTarget.Latest, /*isJavaScriptFile*/ true, /*_syntaxCursor:*/ undefined);
|
||||
const jsDocComment = parseJSDocComment(/*parent:*/ undefined, start, length);
|
||||
sourceFile = <SourceFile>{ languageVariant: LanguageVariant.Standard, text: content };
|
||||
const jsDocComment = parseJSDocCommentWorker(start, length);
|
||||
const diagnostics = parseDiagnostics;
|
||||
clearState();
|
||||
|
||||
@@ -5916,12 +5894,19 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function parseJSDocComment(parent: Node, start: number, length: number): JSDocComment {
|
||||
const saveToken = token;
|
||||
const saveParseDiagnosticsLength = parseDiagnostics.length;
|
||||
const saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode;
|
||||
|
||||
const comment = parseJSDocCommentWorker(start, length);
|
||||
if (comment) {
|
||||
fixupParentReferences(comment);
|
||||
comment.parent = parent;
|
||||
}
|
||||
|
||||
token = saveToken;
|
||||
parseDiagnostics.length = saveParseDiagnosticsLength;
|
||||
parseErrorBeforeNextFinishedNode = saveParseErrorBeforeNextFinishedNode;
|
||||
|
||||
return comment;
|
||||
}
|
||||
|
||||
@@ -5936,69 +5921,69 @@ namespace ts {
|
||||
Debug.assert(end <= content.length);
|
||||
|
||||
let tags: NodeArray<JSDocTag>;
|
||||
let pos: number;
|
||||
|
||||
// NOTE(cyrusn): This is essentially a handwritten scanner for JSDocComments. I
|
||||
// considered using an actual Scanner, but this would complicate things. The
|
||||
// scanner would need to know it was in a Doc Comment. Otherwise, it would then
|
||||
// produce comments *inside* the doc comment. In the end it was just easier to
|
||||
// write a simple scanner rather than go that route.
|
||||
if (length >= "/** */".length) {
|
||||
if (content.charCodeAt(start) === CharacterCodes.slash &&
|
||||
content.charCodeAt(start + 1) === CharacterCodes.asterisk &&
|
||||
content.charCodeAt(start + 2) === CharacterCodes.asterisk &&
|
||||
content.charCodeAt(start + 3) !== CharacterCodes.asterisk) {
|
||||
let result: JSDocComment;
|
||||
|
||||
// Check for /** (JSDoc opening part)
|
||||
if (content.charCodeAt(start) === CharacterCodes.slash &&
|
||||
content.charCodeAt(start + 1) === CharacterCodes.asterisk &&
|
||||
content.charCodeAt(start + 2) === CharacterCodes.asterisk &&
|
||||
content.charCodeAt(start + 3) !== CharacterCodes.asterisk) {
|
||||
|
||||
|
||||
// + 3 for leading /**, - 5 in total for /** */
|
||||
scanner.scanRange(start + 3, length - 5, () => {
|
||||
// Initially we can parse out a tag. We also have seen a starting asterisk.
|
||||
// This is so that /** * @type */ doesn't parse.
|
||||
let canParseTag = true;
|
||||
let seenAsterisk = true;
|
||||
|
||||
for (pos = start + "/**".length; pos < end; ) {
|
||||
const ch = content.charCodeAt(pos);
|
||||
pos++;
|
||||
nextJSDocToken();
|
||||
while (token !== SyntaxKind.EndOfFileToken) {
|
||||
switch (token) {
|
||||
case SyntaxKind.AtToken:
|
||||
if (canParseTag) {
|
||||
parseTag();
|
||||
}
|
||||
// This will take us to the end of the line, so it's OK to parse a tag on the next pass through the loop
|
||||
seenAsterisk = false;
|
||||
break;
|
||||
|
||||
if (ch === CharacterCodes.at && canParseTag) {
|
||||
parseTag();
|
||||
case SyntaxKind.NewLineTrivia:
|
||||
// After a line break, we can parse a tag, and we haven't seen an asterisk on the next line yet
|
||||
canParseTag = true;
|
||||
seenAsterisk = false;
|
||||
break;
|
||||
|
||||
// Once we parse out a tag, we cannot keep parsing out tags on this line.
|
||||
canParseTag = false;
|
||||
continue;
|
||||
}
|
||||
case SyntaxKind.AsteriskToken:
|
||||
if (seenAsterisk) {
|
||||
// If we've already seen an asterisk, then we can no longer parse a tag on this line
|
||||
canParseTag = false;
|
||||
}
|
||||
// Ignore the first asterisk on a line
|
||||
seenAsterisk = true;
|
||||
break;
|
||||
|
||||
if (isLineBreak(ch)) {
|
||||
// After a line break, we can parse a tag, and we haven't seen as asterisk
|
||||
// on the next line yet.
|
||||
canParseTag = true;
|
||||
seenAsterisk = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isWhiteSpace(ch)) {
|
||||
// Whitespace doesn't affect any of our parsing.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore the first asterisk on a line.
|
||||
if (ch === CharacterCodes.asterisk) {
|
||||
if (seenAsterisk) {
|
||||
// If we've already seen an asterisk, then we can no longer parse a tag
|
||||
// on this line.
|
||||
case SyntaxKind.Identifier:
|
||||
// Anything else is doc comment text. We can't do anything with it. Because it
|
||||
// wasn't a tag, we can no longer parse a tag on this line until we hit the next
|
||||
// line break.
|
||||
canParseTag = false;
|
||||
}
|
||||
seenAsterisk = true;
|
||||
continue;
|
||||
break;
|
||||
|
||||
case SyntaxKind.EndOfFileToken:
|
||||
break;
|
||||
}
|
||||
|
||||
// Anything else is doc comment text. We can't do anything with it. Because it
|
||||
// wasn't a tag, we can no longer parse a tag on this line until we hit the next
|
||||
// line break.
|
||||
canParseTag = false;
|
||||
nextJSDocToken();
|
||||
}
|
||||
}
|
||||
|
||||
result = createJSDocComment();
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
return createJSDocComment();
|
||||
return result;
|
||||
|
||||
function createJSDocComment(): JSDocComment {
|
||||
if (!tags) {
|
||||
@@ -6011,17 +5996,18 @@ namespace ts {
|
||||
}
|
||||
|
||||
function skipWhitespace(): void {
|
||||
while (pos < end && isWhiteSpace(content.charCodeAt(pos))) {
|
||||
pos++;
|
||||
while (token === SyntaxKind.WhitespaceTrivia || token === SyntaxKind.NewLineTrivia) {
|
||||
nextJSDocToken();
|
||||
}
|
||||
}
|
||||
|
||||
function parseTag(): void {
|
||||
Debug.assert(content.charCodeAt(pos - 1) === CharacterCodes.at);
|
||||
const atToken = createNode(SyntaxKind.AtToken, pos - 1);
|
||||
atToken.end = pos;
|
||||
Debug.assert(token === SyntaxKind.AtToken);
|
||||
const atToken = createNode(SyntaxKind.AtToken, scanner.getTokenPos());
|
||||
atToken.end = scanner.getTextPos();
|
||||
nextJSDocToken();
|
||||
|
||||
const tagName = scanIdentifier();
|
||||
const tagName = parseJSDocIdentifier();
|
||||
if (!tagName) {
|
||||
return;
|
||||
}
|
||||
@@ -6052,7 +6038,7 @@ namespace ts {
|
||||
const result = <JSDocTag>createNode(SyntaxKind.JSDocTag, atToken.pos);
|
||||
result.atToken = atToken;
|
||||
result.tagName = tagName;
|
||||
return finishNode(result, pos);
|
||||
return finishNode(result);
|
||||
}
|
||||
|
||||
function addTag(tag: JSDocTag): void {
|
||||
@@ -6068,14 +6054,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
function tryParseTypeExpression(): JSDocTypeExpression {
|
||||
skipWhitespace();
|
||||
|
||||
if (content.charCodeAt(pos) !== CharacterCodes.openBrace) {
|
||||
if (token !== SyntaxKind.OpenBraceToken) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const typeExpression = parseJSDocTypeExpression(pos, end - pos);
|
||||
pos = typeExpression.end;
|
||||
const typeExpression = parseJSDocTypeExpression();
|
||||
return typeExpression;
|
||||
}
|
||||
|
||||
@@ -6085,18 +6068,25 @@ namespace ts {
|
||||
skipWhitespace();
|
||||
let name: Identifier;
|
||||
let isBracketed: boolean;
|
||||
if (content.charCodeAt(pos) === CharacterCodes.openBracket) {
|
||||
pos++;
|
||||
skipWhitespace();
|
||||
name = scanIdentifier();
|
||||
// Looking for something like '[foo]' or 'foo'
|
||||
if (parseOptionalToken(SyntaxKind.OpenBracketToken)) {
|
||||
name = parseJSDocIdentifier();
|
||||
isBracketed = true;
|
||||
|
||||
// May have an optional default, e.g. '[foo = 42]'
|
||||
if (parseOptionalToken(SyntaxKind.EqualsToken)) {
|
||||
parseExpression();
|
||||
}
|
||||
|
||||
parseExpected(SyntaxKind.CloseBracketToken);
|
||||
}
|
||||
else {
|
||||
name = scanIdentifier();
|
||||
else if (token === SyntaxKind.Identifier) {
|
||||
name = parseJSDocIdentifier();
|
||||
}
|
||||
|
||||
if (!name) {
|
||||
parseErrorAtPosition(pos, 0, Diagnostics.Identifier_expected);
|
||||
parseErrorAtPosition(scanner.getStartPos(), 0, Diagnostics.Identifier_expected);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let preName: Identifier, postName: Identifier;
|
||||
@@ -6118,95 +6108,90 @@ namespace ts {
|
||||
result.typeExpression = typeExpression;
|
||||
result.postParameterName = postName;
|
||||
result.isBracketed = isBracketed;
|
||||
return finishNode(result, pos);
|
||||
return finishNode(result);
|
||||
}
|
||||
|
||||
function handleReturnTag(atToken: Node, tagName: Identifier): JSDocReturnTag {
|
||||
if (forEach(tags, t => t.kind === SyntaxKind.JSDocReturnTag)) {
|
||||
parseErrorAtPosition(tagName.pos, pos - tagName.pos, Diagnostics._0_tag_already_specified, tagName.text);
|
||||
parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.text);
|
||||
}
|
||||
|
||||
const result = <JSDocReturnTag>createNode(SyntaxKind.JSDocReturnTag, atToken.pos);
|
||||
result.atToken = atToken;
|
||||
result.tagName = tagName;
|
||||
result.typeExpression = tryParseTypeExpression();
|
||||
return finishNode(result, pos);
|
||||
return finishNode(result);
|
||||
}
|
||||
|
||||
function handleTypeTag(atToken: Node, tagName: Identifier): JSDocTypeTag {
|
||||
if (forEach(tags, t => t.kind === SyntaxKind.JSDocTypeTag)) {
|
||||
parseErrorAtPosition(tagName.pos, pos - tagName.pos, Diagnostics._0_tag_already_specified, tagName.text);
|
||||
parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.text);
|
||||
}
|
||||
|
||||
const result = <JSDocTypeTag>createNode(SyntaxKind.JSDocTypeTag, atToken.pos);
|
||||
result.atToken = atToken;
|
||||
result.tagName = tagName;
|
||||
result.typeExpression = tryParseTypeExpression();
|
||||
return finishNode(result, pos);
|
||||
return finishNode(result);
|
||||
}
|
||||
|
||||
function handleTemplateTag(atToken: Node, tagName: Identifier): JSDocTemplateTag {
|
||||
if (forEach(tags, t => t.kind === SyntaxKind.JSDocTemplateTag)) {
|
||||
parseErrorAtPosition(tagName.pos, pos - tagName.pos, Diagnostics._0_tag_already_specified, tagName.text);
|
||||
parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.text);
|
||||
}
|
||||
|
||||
// Type parameter list looks like '@template T,U,V'
|
||||
const typeParameters = <NodeArray<TypeParameterDeclaration>>[];
|
||||
typeParameters.pos = pos;
|
||||
typeParameters.pos = scanner.getStartPos();
|
||||
|
||||
while (true) {
|
||||
skipWhitespace();
|
||||
|
||||
const startPos = pos;
|
||||
const name = scanIdentifier();
|
||||
const name = parseJSDocIdentifier();
|
||||
if (!name) {
|
||||
parseErrorAtPosition(startPos, 0, Diagnostics.Identifier_expected);
|
||||
parseErrorAtPosition(scanner.getStartPos(), 0, Diagnostics.Identifier_expected);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const typeParameter = <TypeParameterDeclaration>createNode(SyntaxKind.TypeParameter, name.pos);
|
||||
typeParameter.name = name;
|
||||
finishNode(typeParameter, pos);
|
||||
finishNode(typeParameter);
|
||||
|
||||
typeParameters.push(typeParameter);
|
||||
|
||||
skipWhitespace();
|
||||
if (content.charCodeAt(pos) !== CharacterCodes.comma) {
|
||||
if (token === SyntaxKind.CommaToken) {
|
||||
nextJSDocToken();
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
|
||||
pos++;
|
||||
}
|
||||
|
||||
typeParameters.end = pos;
|
||||
|
||||
const result = <JSDocTemplateTag>createNode(SyntaxKind.JSDocTemplateTag, atToken.pos);
|
||||
result.atToken = atToken;
|
||||
result.tagName = tagName;
|
||||
result.typeParameters = typeParameters;
|
||||
return finishNode(result, pos);
|
||||
finishNode(result);
|
||||
typeParameters.end = result.end;
|
||||
return result;
|
||||
}
|
||||
|
||||
function scanIdentifier(): Identifier {
|
||||
const startPos = pos;
|
||||
for (; pos < end; pos++) {
|
||||
const ch = content.charCodeAt(pos);
|
||||
if (pos === startPos && isIdentifierStart(ch, ScriptTarget.Latest)) {
|
||||
continue;
|
||||
}
|
||||
else if (pos > startPos && isIdentifierPart(ch, ScriptTarget.Latest)) {
|
||||
continue;
|
||||
}
|
||||
function nextJSDocToken(): SyntaxKind {
|
||||
return token = scanner.scanJSDocToken();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (startPos === pos) {
|
||||
function parseJSDocIdentifier(): Identifier {
|
||||
if (token !== SyntaxKind.Identifier) {
|
||||
parseErrorAtCurrentToken(Diagnostics.Identifier_expected);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const result = <Identifier>createNode(SyntaxKind.Identifier, startPos);
|
||||
result.text = content.substring(startPos, pos);
|
||||
return finishNode(result, pos);
|
||||
const pos = scanner.getTokenPos();
|
||||
const end = scanner.getTextPos();
|
||||
const result = <Identifier>createNode(SyntaxKind.Identifier, pos);
|
||||
result.text = content.substring(pos, end);
|
||||
finishNode(result, end);
|
||||
|
||||
nextJSDocToken();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace ts {
|
||||
scanJsxIdentifier(): SyntaxKind;
|
||||
reScanJsxToken(): SyntaxKind;
|
||||
scanJsxToken(): SyntaxKind;
|
||||
scanJSDocToken(): SyntaxKind;
|
||||
scan(): SyntaxKind;
|
||||
// Sets the text for the scanner to scan. An optional subrange starting point and length
|
||||
// can be provided to have the scanner only scan a portion of the text.
|
||||
@@ -42,6 +43,10 @@ namespace ts {
|
||||
// is returned from this function.
|
||||
lookAhead<T>(callback: () => T): T;
|
||||
|
||||
// Invokes the callback with the scanner set to scan the specified range. When the callback
|
||||
// returns, the scanner is restored to the state it was in before scanRange was called.
|
||||
scanRange<T>(start: number, length: number, callback: () => T): T;
|
||||
|
||||
// Invokes the provided callback. If the callback returns something falsy, then it restores
|
||||
// the scanner to the state it was in immediately prior to invoking the callback. If the
|
||||
// callback returns something truthy, then the scanner state is not rolled back. The result
|
||||
@@ -751,6 +756,7 @@ namespace ts {
|
||||
scanJsxIdentifier,
|
||||
reScanJsxToken,
|
||||
scanJsxToken,
|
||||
scanJSDocToken,
|
||||
scan,
|
||||
setText,
|
||||
setScriptTarget,
|
||||
@@ -759,6 +765,7 @@ namespace ts {
|
||||
setTextPos,
|
||||
tryScan,
|
||||
lookAhead,
|
||||
scanRange,
|
||||
};
|
||||
|
||||
function error(message: DiagnosticMessage, length?: number): void {
|
||||
@@ -1666,6 +1673,60 @@ namespace ts {
|
||||
return token;
|
||||
}
|
||||
|
||||
function scanJSDocToken(): SyntaxKind {
|
||||
if (pos >= end) {
|
||||
return token = SyntaxKind.EndOfFileToken;
|
||||
}
|
||||
|
||||
startPos = pos;
|
||||
|
||||
// Eat leading whitespace
|
||||
let ch = text.charCodeAt(pos);
|
||||
while (pos < end) {
|
||||
ch = text.charCodeAt(pos);
|
||||
if (isWhiteSpace(ch)) {
|
||||
pos++;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
tokenPos = pos;
|
||||
|
||||
switch (ch) {
|
||||
case CharacterCodes.at:
|
||||
return pos += 1, token = SyntaxKind.AtToken;
|
||||
case CharacterCodes.lineFeed:
|
||||
case CharacterCodes.carriageReturn:
|
||||
return pos += 1, token = SyntaxKind.NewLineTrivia;
|
||||
case CharacterCodes.asterisk:
|
||||
return pos += 1, token = SyntaxKind.AsteriskToken;
|
||||
case CharacterCodes.openBrace:
|
||||
return pos += 1, token = SyntaxKind.OpenBraceToken;
|
||||
case CharacterCodes.closeBrace:
|
||||
return pos += 1, token = SyntaxKind.CloseBraceToken;
|
||||
case CharacterCodes.openBracket:
|
||||
return pos += 1, token = SyntaxKind.OpenBracketToken;
|
||||
case CharacterCodes.closeBracket:
|
||||
return pos += 1, token = SyntaxKind.CloseBracketToken;
|
||||
case CharacterCodes.equals:
|
||||
return pos += 1, token = SyntaxKind.EqualsToken;
|
||||
case CharacterCodes.comma:
|
||||
return pos += 1, token = SyntaxKind.CommaToken;
|
||||
}
|
||||
|
||||
if (isIdentifierStart(ch, ScriptTarget.Latest)) {
|
||||
pos++;
|
||||
while (isIdentifierPart(text.charCodeAt(pos), ScriptTarget.Latest) && pos < end) {
|
||||
pos++;
|
||||
}
|
||||
return token = SyntaxKind.Identifier;
|
||||
}
|
||||
else {
|
||||
return pos += 1, token = SyntaxKind.Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
function speculationHelper<T>(callback: () => T, isLookahead: boolean): T {
|
||||
const savePos = pos;
|
||||
const saveStartPos = startPos;
|
||||
@@ -1688,6 +1749,33 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function scanRange<T>(start: number, length: number, callback: () => T): T {
|
||||
const saveEnd = end;
|
||||
const savePos = pos;
|
||||
const saveStartPos = startPos;
|
||||
const saveTokenPos = tokenPos;
|
||||
const saveToken = token;
|
||||
const savePrecedingLineBreak = precedingLineBreak;
|
||||
const saveTokenValue = tokenValue;
|
||||
const saveHasExtendedUnicodeEscape = hasExtendedUnicodeEscape;
|
||||
const saveTokenIsUnterminated = tokenIsUnterminated;
|
||||
|
||||
setText(text, start, length);
|
||||
const result = callback();
|
||||
|
||||
end = saveEnd;
|
||||
pos = savePos;
|
||||
startPos = saveStartPos;
|
||||
tokenPos = saveTokenPos;
|
||||
token = saveToken;
|
||||
precedingLineBreak = savePrecedingLineBreak;
|
||||
tokenValue = saveTokenValue;
|
||||
hasExtendedUnicodeEscape = saveHasExtendedUnicodeEscape;
|
||||
tokenIsUnterminated = saveTokenIsUnterminated;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function lookAhead<T>(callback: () => T): T {
|
||||
return speculationHelper(callback, /*isLookahead*/ true);
|
||||
}
|
||||
|
||||
+1
-1
@@ -340,7 +340,7 @@ namespace ts {
|
||||
if (sys.watchDirectory && configFileName) {
|
||||
const directory = ts.getDirectoryPath(configFileName);
|
||||
directoryWatcher = sys.watchDirectory(
|
||||
// When the configFileName is just "tsconfig.json", the watched directory should be
|
||||
// When the configFileName is just "tsconfig.json", the watched directory should be
|
||||
// the current direcotry; if there is a given "project" parameter, then the configFileName
|
||||
// is an absolute file name.
|
||||
directory == "" ? "." : directory,
|
||||
|
||||
+15
-11
@@ -313,11 +313,11 @@ namespace ts {
|
||||
// Top-level nodes
|
||||
SourceFile,
|
||||
|
||||
// JSDoc nodes.
|
||||
// JSDoc nodes
|
||||
JSDocTypeExpression,
|
||||
// The * type.
|
||||
// The * type
|
||||
JSDocAllType,
|
||||
// The ? type.
|
||||
// The ? type
|
||||
JSDocUnknownType,
|
||||
JSDocArrayType,
|
||||
JSDocUnionType,
|
||||
@@ -393,10 +393,17 @@ namespace ts {
|
||||
HasImplicitReturn = 1 << 20, // If function implicitly returns on one of codepaths (initialized by binding)
|
||||
HasExplicitReturn = 1 << 21, // If function has explicit reachable return on one of codepaths (initialized by binding)
|
||||
GlobalAugmentation = 1 << 22, // Set if module declaration is an augmentation for the global scope
|
||||
Modifier = Export | Ambient | Public | Private | Protected | Static | Readonly | Abstract | Default | Async,
|
||||
HasClassExtends = 1 << 23, // If the file has a non-ambient class with an extends clause in ES5 or lower (initialized by binding)
|
||||
HasDecorators = 1 << 24, // If the file has decorators (initialized by binding)
|
||||
HasParamDecorators = 1 << 25, // If the file has parameter decorators (initialized by binding)
|
||||
HasAsyncFunctions = 1 << 26, // If the file has async functions (initialized by binding)
|
||||
|
||||
Modifier = Export | Ambient | Public | Private | Protected | Static | Abstract | Default | Async,
|
||||
AccessibilityModifier = Public | Private | Protected,
|
||||
BlockScoped = Let | Const,
|
||||
ReachabilityCheckFlags = HasImplicitReturn | HasExplicitReturn
|
||||
|
||||
ReachabilityCheckFlags = HasImplicitReturn | HasExplicitReturn,
|
||||
EmitHelperFlags = HasClassExtends | HasDecorators | HasParamDecorators | HasAsyncFunctions,
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -999,7 +1006,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// @kind(SyntaxKind.CallExpression)
|
||||
export interface CallExpression extends LeftHandSideExpression {
|
||||
export interface CallExpression extends LeftHandSideExpression, Declaration {
|
||||
expression: LeftHandSideExpression;
|
||||
typeArguments?: NodeArray<TypeNode>;
|
||||
arguments: NodeArray<Expression>;
|
||||
@@ -1478,6 +1485,8 @@ namespace ts {
|
||||
type: JSDocType;
|
||||
}
|
||||
|
||||
export type JSDocTypeReferencingNode = JSDocThisType | JSDocConstructorType | JSDocVariadicType | JSDocOptionalType | JSDocNullableType | JSDocNonNullableType;
|
||||
|
||||
// @kind(SyntaxKind.JSDocRecordMember)
|
||||
export interface JSDocRecordMember extends PropertySignature {
|
||||
name: Identifier | LiteralExpression;
|
||||
@@ -2048,11 +2057,6 @@ namespace ts {
|
||||
TypeChecked = 0x00000001, // Node has been type checked
|
||||
LexicalThis = 0x00000002, // Lexical 'this' reference
|
||||
CaptureThis = 0x00000004, // Lexical 'this' used in body
|
||||
EmitExtends = 0x00000008, // Emit __extends
|
||||
EmitDecorate = 0x00000010, // Emit __decorate
|
||||
EmitParam = 0x00000020, // Emit __param helper for decorators
|
||||
EmitAwaiter = 0x00000040, // Emit __awaiter
|
||||
EmitGenerator = 0x00000080, // Emit __generator
|
||||
SuperInstance = 0x00000100, // Instance 'super' reference
|
||||
SuperStatic = 0x00000200, // Static 'super' reference
|
||||
ContextChecked = 0x00000400, // Contextual types have been assigned
|
||||
|
||||
+64
-59
@@ -802,8 +802,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an super call\property node returns a closest node where either
|
||||
* - super call\property is legal in the node and not legal in the parent node the node.
|
||||
* Given an super call\property node returns a closest node where either
|
||||
* - super call\property is legal in the node and not legal in the parent node the node.
|
||||
* i.e. super call is legal in constructor but not legal in the class body.
|
||||
* - node is arrow function (so caller might need to call getSuperContainer in case it needs to climb higher)
|
||||
* - super call\property is definitely illegal in the node (but might be legal in some subnode)
|
||||
@@ -885,54 +885,28 @@ namespace ts {
|
||||
// property declarations are valid if their parent is a class declaration.
|
||||
return node.parent.kind === SyntaxKind.ClassDeclaration;
|
||||
|
||||
case SyntaxKind.Parameter:
|
||||
// if the parameter's parent has a body and its grandparent is a class declaration, this is a valid target;
|
||||
return (<FunctionLikeDeclaration>node.parent).body && node.parent.parent.kind === SyntaxKind.ClassDeclaration;
|
||||
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
// if this method has a body and its parent is a class declaration, this is a valid target.
|
||||
return (<FunctionLikeDeclaration>node).body && node.parent.kind === SyntaxKind.ClassDeclaration;
|
||||
return (<FunctionLikeDeclaration>node).body !== undefined
|
||||
&& node.parent.kind === SyntaxKind.ClassDeclaration;
|
||||
|
||||
case SyntaxKind.Parameter:
|
||||
// if the parameter's parent has a body and its grandparent is a class declaration, this is a valid target;
|
||||
return (<FunctionLikeDeclaration>node.parent).body !== undefined
|
||||
&& (node.parent.kind === SyntaxKind.Constructor
|
||||
|| node.parent.kind === SyntaxKind.MethodDeclaration
|
||||
|| node.parent.kind === SyntaxKind.SetAccessor)
|
||||
&& node.parent.parent.kind === SyntaxKind.ClassDeclaration;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export function nodeIsDecorated(node: Node): boolean {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
if (node.decorators) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.Parameter:
|
||||
if (node.decorators) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
case SyntaxKind.GetAccessor:
|
||||
if ((<FunctionLikeDeclaration>node).body && node.decorators) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.SetAccessor:
|
||||
if ((<FunctionLikeDeclaration>node).body && node.decorators) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
return node.decorators !== undefined
|
||||
&& nodeCanBeDecorated(node);
|
||||
}
|
||||
|
||||
export function isPropertyAccessExpression(node: Node): node is PropertyAccessExpression {
|
||||
@@ -1080,7 +1054,7 @@ namespace ts {
|
||||
|
||||
/**
|
||||
* Returns true if the node is a CallExpression to the identifier 'require' with
|
||||
* exactly one string literal argument.
|
||||
* exactly one argument.
|
||||
* This function does not test if the node is in a JavaScript file or not.
|
||||
*/
|
||||
export function isRequireCall(expression: Node): expression is CallExpression {
|
||||
@@ -1088,8 +1062,7 @@ namespace ts {
|
||||
return expression.kind === SyntaxKind.CallExpression &&
|
||||
(<CallExpression>expression).expression.kind === SyntaxKind.Identifier &&
|
||||
(<Identifier>(<CallExpression>expression).expression).text === "require" &&
|
||||
(<CallExpression>expression).arguments.length === 1 &&
|
||||
(<CallExpression>expression).arguments[0].kind === SyntaxKind.StringLiteral;
|
||||
(<CallExpression>expression).arguments.length === 1;
|
||||
}
|
||||
|
||||
/// Given a BinaryExpression, returns SpecialPropertyAssignmentKind for the various kinds of property
|
||||
@@ -1169,26 +1142,56 @@ namespace ts {
|
||||
(<JSDocFunctionType>node).parameters[0].type.kind === SyntaxKind.JSDocConstructorType;
|
||||
}
|
||||
|
||||
function getJSDocTag(node: Node, kind: SyntaxKind): JSDocTag {
|
||||
if (node && node.jsDocComment) {
|
||||
for (const tag of node.jsDocComment.tags) {
|
||||
if (tag.kind === kind) {
|
||||
return tag;
|
||||
}
|
||||
function getJSDocTag(node: Node, kind: SyntaxKind, checkParentVariableStatement: boolean): JSDocTag {
|
||||
if (!node) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const jsDocComment = getJSDocComment(node, checkParentVariableStatement);
|
||||
if (!jsDocComment) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
for (const tag of jsDocComment.tags) {
|
||||
if (tag.kind === kind) {
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getJSDocComment(node: Node, checkParentVariableStatement: boolean): JSDocComment {
|
||||
if (node.jsDocComment) {
|
||||
return node.jsDocComment;
|
||||
}
|
||||
// Try to recognize this pattern when node is initializer of variable declaration and JSDoc comments are on containing variable statement.
|
||||
// /**
|
||||
// * @param {number} name
|
||||
// * @returns {number}
|
||||
// */
|
||||
// var x = function(name) { return name.length; }
|
||||
if (checkParentVariableStatement) {
|
||||
const isInitializerOfVariableDeclarationInStatement =
|
||||
node.parent.kind === SyntaxKind.VariableDeclaration &&
|
||||
(<VariableDeclaration>node.parent).initializer === node &&
|
||||
node.parent.parent.parent.kind === SyntaxKind.VariableStatement;
|
||||
|
||||
const variableStatementNode = isInitializerOfVariableDeclarationInStatement ? node.parent.parent.parent : undefined;
|
||||
return variableStatementNode && variableStatementNode.jsDocComment;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function getJSDocTypeTag(node: Node): JSDocTypeTag {
|
||||
return <JSDocTypeTag>getJSDocTag(node, SyntaxKind.JSDocTypeTag);
|
||||
return <JSDocTypeTag>getJSDocTag(node, SyntaxKind.JSDocTypeTag, /*checkParentVariableStatement*/ false);
|
||||
}
|
||||
|
||||
export function getJSDocReturnTag(node: Node): JSDocReturnTag {
|
||||
return <JSDocReturnTag>getJSDocTag(node, SyntaxKind.JSDocReturnTag);
|
||||
return <JSDocReturnTag>getJSDocTag(node, SyntaxKind.JSDocReturnTag, /*checkParentVariableStatement*/ true);
|
||||
}
|
||||
|
||||
export function getJSDocTemplateTag(node: Node): JSDocTemplateTag {
|
||||
return <JSDocTemplateTag>getJSDocTag(node, SyntaxKind.JSDocTemplateTag);
|
||||
return <JSDocTemplateTag>getJSDocTag(node, SyntaxKind.JSDocTemplateTag, /*checkParentVariableStatement*/ false);
|
||||
}
|
||||
|
||||
export function getCorrespondingJSDocParameterTag(parameter: ParameterDeclaration): JSDocParameterTag {
|
||||
@@ -1197,19 +1200,21 @@ namespace ts {
|
||||
// annotation.
|
||||
const parameterName = (<Identifier>parameter.name).text;
|
||||
|
||||
const docComment = parameter.parent.jsDocComment;
|
||||
if (docComment) {
|
||||
return <JSDocParameterTag>forEach(docComment.tags, t => {
|
||||
if (t.kind === SyntaxKind.JSDocParameterTag) {
|
||||
const parameterTag = <JSDocParameterTag>t;
|
||||
const jsDocComment = getJSDocComment(parameter.parent, /*checkParentVariableStatement*/ true);
|
||||
if (jsDocComment) {
|
||||
for (const tag of jsDocComment.tags) {
|
||||
if (tag.kind === SyntaxKind.JSDocParameterTag) {
|
||||
const parameterTag = <JSDocParameterTag>tag;
|
||||
const name = parameterTag.preParameterName || parameterTag.postParameterName;
|
||||
if (name.text === parameterName) {
|
||||
return t;
|
||||
return parameterTag;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function hasRestParameter(s: SignatureDeclaration): boolean {
|
||||
|
||||
@@ -572,6 +572,31 @@ namespace FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
public verifyCompletionListStartsWithItemsInOrder(items: string[]): void {
|
||||
if (items.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const entries = this.getCompletionListAtCaret().entries;
|
||||
assert.isTrue(items.length <= entries.length, `Amount of expected items in completion list [ ${items.length} ] is greater than actual number of items in list [ ${entries.length} ]`);
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
assert.equal(entries[i].name, items[i], `Unexpected item in completion list`);
|
||||
}
|
||||
}
|
||||
|
||||
public noItemsWithSameNameButDifferentKind(): void {
|
||||
const completions = this.getCompletionListAtCaret();
|
||||
const uniqueItems: ts.Map<string> = {};
|
||||
for (const item of completions.entries) {
|
||||
if (!ts.hasProperty(uniqueItems, item.name)) {
|
||||
uniqueItems[item.name] = item.kind;
|
||||
}
|
||||
else {
|
||||
assert.equal(item.kind, uniqueItems[item.name], `Items should have the same kind, got ${item.kind} and ${uniqueItems[item.name]}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public verifyMemberListIsEmpty(negative: boolean) {
|
||||
const members = this.getMemberListAtCaret();
|
||||
if ((!members || members.entries.length === 0) && negative) {
|
||||
|
||||
Vendored
+32
-13
@@ -1255,7 +1255,7 @@ interface Console {
|
||||
select(element: Element): void;
|
||||
time(timerName?: string): void;
|
||||
timeEnd(timerName?: string): void;
|
||||
trace(): void;
|
||||
trace(message?: any, ...optionalParams: any[]): void;
|
||||
warn(message?: any, ...optionalParams: any[]): void;
|
||||
}
|
||||
|
||||
@@ -1514,9 +1514,9 @@ interface DataTransferItemList {
|
||||
length: number;
|
||||
add(data: File): DataTransferItem;
|
||||
clear(): void;
|
||||
item(index: number): File;
|
||||
item(index: number): DataTransferItem;
|
||||
remove(index: number): void;
|
||||
[index: number]: File;
|
||||
[index: number]: DataTransferItem;
|
||||
}
|
||||
|
||||
declare var DataTransferItemList: {
|
||||
@@ -2569,6 +2569,8 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven
|
||||
* @param content The text and HTML tags to write.
|
||||
*/
|
||||
writeln(...content: string[]): void;
|
||||
createElement(tagName: "picture"): HTMLPictureElement;
|
||||
getElementsByTagName(tagname: "picture"): NodeListOf<HTMLPictureElement>;
|
||||
addEventListener(type: "MSContentZoom", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: "MSGestureChange", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: "MSGestureDoubleTap", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void;
|
||||
@@ -2981,6 +2983,7 @@ interface Element extends Node, GlobalEventHandlers, ElementTraversal, NodeSelec
|
||||
webkitRequestFullscreen(): void;
|
||||
getElementsByClassName(classNames: string): NodeListOf<Element>;
|
||||
matches(selector: string): boolean;
|
||||
getElementsByTagName(tagname: "picture"): NodeListOf<HTMLPictureElement>;
|
||||
addEventListener(type: "MSGestureChange", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: "MSGestureDoubleTap", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: "MSGestureEnd", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void;
|
||||
@@ -3770,6 +3773,7 @@ interface HTMLCanvasElement extends HTMLElement {
|
||||
* @param type The standard MIME type for the image format to return. If you do not specify this parameter, the default value is a PNG format image.
|
||||
*/
|
||||
toDataURL(type?: string, ...args: any[]): string;
|
||||
toBlob(): Blob;
|
||||
}
|
||||
|
||||
declare var HTMLCanvasElement: {
|
||||
@@ -6924,7 +6928,7 @@ interface IDBDatabase extends EventTarget {
|
||||
objectStoreNames: DOMStringList;
|
||||
onabort: (ev: Event) => any;
|
||||
onerror: (ev: Event) => any;
|
||||
version: string;
|
||||
version: number;
|
||||
close(): void;
|
||||
createObjectStore(name: string, optionalParameters?: IDBObjectStoreParameters): IDBObjectStore;
|
||||
deleteObjectStore(name: string): void;
|
||||
@@ -7640,7 +7644,7 @@ declare var MediaQueryList: {
|
||||
interface MediaSource extends EventTarget {
|
||||
activeSourceBuffers: SourceBufferList;
|
||||
duration: number;
|
||||
readyState: number;
|
||||
readyState: string;
|
||||
sourceBuffers: SourceBufferList;
|
||||
addSourceBuffer(type: string): SourceBuffer;
|
||||
endOfStream(error?: number): void;
|
||||
@@ -10369,17 +10373,16 @@ declare var Storage: {
|
||||
}
|
||||
|
||||
interface StorageEvent extends Event {
|
||||
key: string;
|
||||
newValue: any;
|
||||
oldValue: any;
|
||||
storageArea: Storage;
|
||||
url: string;
|
||||
initStorageEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, keyArg: string, oldValueArg: any, newValueArg: any, urlArg: string, storageAreaArg: Storage): void;
|
||||
key?: string;
|
||||
oldValue?: string;
|
||||
newValue?: string;
|
||||
storageArea?: Storage;
|
||||
}
|
||||
|
||||
declare var StorageEvent: {
|
||||
prototype: StorageEvent;
|
||||
new(): StorageEvent;
|
||||
new (type: string, eventInitDict?: StorageEventInit): StorageEvent;
|
||||
}
|
||||
|
||||
interface StyleMedia {
|
||||
@@ -11977,7 +11980,7 @@ interface Window extends EventTarget, WindowTimers, WindowSessionStorage, Window
|
||||
msMatchMedia(mediaQuery: string): MediaQueryList;
|
||||
msRequestAnimationFrame(callback: FrameRequestCallback): number;
|
||||
msWriteProfilerMark(profilerMarkName: string): void;
|
||||
open(url?: string, target?: string, features?: string, replace?: boolean): any;
|
||||
open(url?: string, target?: string, features?: string, replace?: boolean): Window;
|
||||
postMessage(message: any, targetOrigin: string, ports?: any): void;
|
||||
print(): void;
|
||||
prompt(message?: string, _default?: string): string;
|
||||
@@ -12579,6 +12582,14 @@ interface XMLHttpRequestEventTarget {
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
|
||||
interface StorageEventInit extends EventInit {
|
||||
key?: string;
|
||||
oldValue?: string;
|
||||
newValue?: string;
|
||||
url: string;
|
||||
storageArea?: Storage;
|
||||
}
|
||||
|
||||
interface IDBObjectStoreParameters {
|
||||
keyPath?: string | string[];
|
||||
autoIncrement?: boolean;
|
||||
@@ -12633,6 +12644,14 @@ declare var HTMLTemplateElement: {
|
||||
new(): HTMLTemplateElement;
|
||||
}
|
||||
|
||||
interface HTMLPictureElement extends HTMLElement {
|
||||
}
|
||||
|
||||
declare var HTMLPictureElement: {
|
||||
prototype: HTMLPictureElement;
|
||||
new(): HTMLPictureElement;
|
||||
}
|
||||
|
||||
declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject;
|
||||
|
||||
interface ErrorEventHandler {
|
||||
@@ -12829,7 +12848,7 @@ declare function msCancelRequestAnimationFrame(handle: number): void;
|
||||
declare function msMatchMedia(mediaQuery: string): MediaQueryList;
|
||||
declare function msRequestAnimationFrame(callback: FrameRequestCallback): number;
|
||||
declare function msWriteProfilerMark(profilerMarkName: string): void;
|
||||
declare function open(url?: string, target?: string, features?: string, replace?: boolean): any;
|
||||
declare function open(url?: string, target?: string, features?: string, replace?: boolean): Window;
|
||||
declare function postMessage(message: any, targetOrigin: string, ports?: any): void;
|
||||
declare function print(): void;
|
||||
declare function prompt(message?: string, _default?: string): string;
|
||||
|
||||
Vendored
-2
@@ -819,7 +819,6 @@ interface MapConstructor {
|
||||
declare var Map: MapConstructor;
|
||||
|
||||
interface WeakMap<K, V> {
|
||||
clear(): void;
|
||||
delete(key: K): boolean;
|
||||
get(key: K): V;
|
||||
has(key: K): boolean;
|
||||
@@ -859,7 +858,6 @@ declare var Set: SetConstructor;
|
||||
|
||||
interface WeakSet<T> {
|
||||
add(value: T): WeakSet<T>;
|
||||
clear(): void;
|
||||
delete(value: T): boolean;
|
||||
has(value: T): boolean;
|
||||
[Symbol.toStringTag]: "WeakSet";
|
||||
|
||||
Vendored
+89
@@ -0,0 +1,89 @@
|
||||
interface Array<T> {
|
||||
/**
|
||||
* Determines whether an array includes a certain element, returning true or false as appropriate.
|
||||
* @param searchElement The element to search for.
|
||||
* @param fromIndex The position in this array at which to begin searching for searchElement.
|
||||
*/
|
||||
includes(searchElement: T, fromIndex?: number): boolean;
|
||||
}
|
||||
|
||||
interface Int8Array {
|
||||
/**
|
||||
* Determines whether an array includes a certain element, returning true or false as appropriate.
|
||||
* @param searchElement The element to search for.
|
||||
* @param fromIndex The position in this array at which to begin searching for searchElement.
|
||||
*/
|
||||
includes(searchElement: number, fromIndex?: number): boolean;
|
||||
}
|
||||
|
||||
interface Uint8Array {
|
||||
/**
|
||||
* Determines whether an array includes a certain element, returning true or false as appropriate.
|
||||
* @param searchElement The element to search for.
|
||||
* @param fromIndex The position in this array at which to begin searching for searchElement.
|
||||
*/
|
||||
includes(searchElement: number, fromIndex?: number): boolean;
|
||||
}
|
||||
|
||||
interface Uint8ClampedArray {
|
||||
/**
|
||||
* Determines whether an array includes a certain element, returning true or false as appropriate.
|
||||
* @param searchElement The element to search for.
|
||||
* @param fromIndex The position in this array at which to begin searching for searchElement.
|
||||
*/
|
||||
includes(searchElement: number, fromIndex?: number): boolean;
|
||||
}
|
||||
|
||||
interface Int16Array {
|
||||
/**
|
||||
* Determines whether an array includes a certain element, returning true or false as appropriate.
|
||||
* @param searchElement The element to search for.
|
||||
* @param fromIndex The position in this array at which to begin searching for searchElement.
|
||||
*/
|
||||
includes(searchElement: number, fromIndex?: number): boolean;
|
||||
}
|
||||
|
||||
interface Uint16Array {
|
||||
/**
|
||||
* Determines whether an array includes a certain element, returning true or false as appropriate.
|
||||
* @param searchElement The element to search for.
|
||||
* @param fromIndex The position in this array at which to begin searching for searchElement.
|
||||
*/
|
||||
includes(searchElement: number, fromIndex?: number): boolean;
|
||||
}
|
||||
|
||||
interface Int32Array {
|
||||
/**
|
||||
* Determines whether an array includes a certain element, returning true or false as appropriate.
|
||||
* @param searchElement The element to search for.
|
||||
* @param fromIndex The position in this array at which to begin searching for searchElement.
|
||||
*/
|
||||
includes(searchElement: number, fromIndex?: number): boolean;
|
||||
}
|
||||
|
||||
interface Uint32Array {
|
||||
/**
|
||||
* Determines whether an array includes a certain element, returning true or false as appropriate.
|
||||
* @param searchElement The element to search for.
|
||||
* @param fromIndex The position in this array at which to begin searching for searchElement.
|
||||
*/
|
||||
includes(searchElement: number, fromIndex?: number): boolean;
|
||||
}
|
||||
|
||||
interface Float32Array {
|
||||
/**
|
||||
* Determines whether an array includes a certain element, returning true or false as appropriate.
|
||||
* @param searchElement The element to search for.
|
||||
* @param fromIndex The position in this array at which to begin searching for searchElement.
|
||||
*/
|
||||
includes(searchElement: number, fromIndex?: number): boolean;
|
||||
}
|
||||
|
||||
interface Float64Array {
|
||||
/**
|
||||
* Determines whether an array includes a certain element, returning true or false as appropriate.
|
||||
* @param searchElement The element to search for.
|
||||
* @param fromIndex The position in this array at which to begin searching for searchElement.
|
||||
*/
|
||||
includes(searchElement: number, fromIndex?: number): boolean;
|
||||
}
|
||||
Vendored
+2
-2
@@ -69,7 +69,7 @@ interface Console {
|
||||
select(element: any): void;
|
||||
time(timerName?: string): void;
|
||||
timeEnd(timerName?: string): void;
|
||||
trace(): void;
|
||||
trace(message?: any, ...optionalParams: any[]): void;
|
||||
warn(message?: any, ...optionalParams: any[]): void;
|
||||
}
|
||||
|
||||
@@ -309,7 +309,7 @@ interface IDBDatabase extends EventTarget {
|
||||
objectStoreNames: DOMStringList;
|
||||
onabort: (ev: Event) => any;
|
||||
onerror: (ev: Event) => any;
|
||||
version: string;
|
||||
version: number;
|
||||
close(): void;
|
||||
createObjectStore(name: string, optionalParameters?: IDBObjectStoreParameters): IDBObjectStore;
|
||||
deleteObjectStore(name: string): void;
|
||||
|
||||
@@ -120,7 +120,7 @@ namespace ts.server {
|
||||
if (!resolution) {
|
||||
const existingResolution = currentResolutionsInFile && ts.lookUp(currentResolutionsInFile, moduleName);
|
||||
if (moduleResolutionIsValid(existingResolution)) {
|
||||
// ok, it is safe to use existing module resolution results
|
||||
// ok, it is safe to use existing module resolution results
|
||||
resolution = existingResolution;
|
||||
}
|
||||
else {
|
||||
@@ -145,8 +145,8 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
if (resolution.resolvedModule) {
|
||||
// TODO: consider checking failedLookupLocations
|
||||
// TODO: use lastCheckTime to track expiration for module name resolution
|
||||
// TODO: consider checking failedLookupLocations
|
||||
// TODO: use lastCheckTime to track expiration for module name resolution
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -483,7 +483,7 @@ namespace ts.server {
|
||||
openFileRootsConfigured: ScriptInfo[] = [];
|
||||
// a path to directory watcher map that detects added tsconfig files
|
||||
directoryWatchersForTsconfig: ts.Map<FileWatcher> = {};
|
||||
// count of how many projects are using the directory watcher. If the
|
||||
// count of how many projects are using the directory watcher. If the
|
||||
// number becomes 0 for a watcher, then we should close it.
|
||||
directoryWatchersRefCount: ts.Map<number> = {};
|
||||
hostConfiguration: HostConfiguration;
|
||||
@@ -564,11 +564,11 @@ namespace ts.server {
|
||||
// We check if the project file list has changed. If so, we update the project.
|
||||
if (!arrayIsEqualTo(currentRootFiles && currentRootFiles.sort(), newRootFiles && newRootFiles.sort())) {
|
||||
// For configured projects, the change is made outside the tsconfig file, and
|
||||
// it is not likely to affect the project for other files opened by the client. We can
|
||||
// it is not likely to affect the project for other files opened by the client. We can
|
||||
// just update the current project.
|
||||
this.updateConfiguredProject(project);
|
||||
|
||||
// Call updateProjectStructure to clean up inferred projects we may have
|
||||
// Call updateProjectStructure to clean up inferred projects we may have
|
||||
// created for the new files
|
||||
this.updateProjectStructure();
|
||||
}
|
||||
@@ -792,8 +792,8 @@ namespace ts.server {
|
||||
* @param info The file that has been closed or newly configured
|
||||
*/
|
||||
closeOpenFile(info: ScriptInfo) {
|
||||
// Closing file should trigger re-reading the file content from disk. This is
|
||||
// because the user may chose to discard the buffer content before saving
|
||||
// Closing file should trigger re-reading the file content from disk. This is
|
||||
// because the user may chose to discard the buffer content before saving
|
||||
// to the disk, and the server's version of the file can be out of sync.
|
||||
info.svc.reloadFromFile(info.fileName);
|
||||
|
||||
@@ -891,8 +891,8 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is to update the project structure for every projects.
|
||||
* It is called on the premise that all the configured projects are
|
||||
* This function is to update the project structure for every projects.
|
||||
* It is called on the premise that all the configured projects are
|
||||
* up to date.
|
||||
*/
|
||||
updateProjectStructure() {
|
||||
@@ -946,7 +946,7 @@ namespace ts.server {
|
||||
|
||||
if (rootFile.defaultProject && rootFile.defaultProject.isConfiguredProject()) {
|
||||
// If the root file has already been added into a configured project,
|
||||
// meaning the original inferred project is gone already.
|
||||
// meaning the original inferred project is gone already.
|
||||
if (!rootedProject.isConfiguredProject()) {
|
||||
this.removeProject(rootedProject);
|
||||
}
|
||||
@@ -1026,10 +1026,16 @@ namespace ts.server {
|
||||
// the newly opened file.
|
||||
findConfigFile(searchPath: string): string {
|
||||
while (true) {
|
||||
const fileName = ts.combinePaths(searchPath, "tsconfig.json");
|
||||
if (this.host.fileExists(fileName)) {
|
||||
return fileName;
|
||||
const tsconfigFileName = ts.combinePaths(searchPath, "tsconfig.json");
|
||||
if (this.host.fileExists(tsconfigFileName)) {
|
||||
return tsconfigFileName;
|
||||
}
|
||||
|
||||
const jsconfigFileName = ts.combinePaths(searchPath, "jsconfig.json");
|
||||
if (this.host.fileExists(jsconfigFileName)) {
|
||||
return jsconfigFileName;
|
||||
}
|
||||
|
||||
const parentPath = ts.getDirectoryPath(searchPath);
|
||||
if (parentPath === searchPath) {
|
||||
break;
|
||||
@@ -1053,9 +1059,9 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
/**
|
||||
* This function tries to search for a tsconfig.json for the given file. If we found it,
|
||||
* This function tries to search for a tsconfig.json for the given file. If we found it,
|
||||
* we first detect if there is already a configured project created for it: if so, we re-read
|
||||
* the tsconfig file content and update the project; otherwise we create a new one.
|
||||
* the tsconfig file content and update the project; otherwise we create a new one.
|
||||
*/
|
||||
openOrUpdateConfiguredProjectForFile(fileName: string) {
|
||||
const searchPath = ts.normalizePath(getDirectoryPath(fileName));
|
||||
@@ -1180,7 +1186,7 @@ namespace ts.server {
|
||||
return { succeeded: false, error: rawConfig.error };
|
||||
}
|
||||
else {
|
||||
const parsedCommandLine = ts.parseJsonConfigFileContent(rawConfig.config, this.host, dirPath);
|
||||
const parsedCommandLine = ts.parseJsonConfigFileContent(rawConfig.config, this.host, dirPath, /*existingOptions*/ {}, configFilename);
|
||||
Debug.assert(!!parsedCommandLine.fileNames);
|
||||
|
||||
if (parsedCommandLine.errors && (parsedCommandLine.errors.length > 0)) {
|
||||
@@ -1259,7 +1265,7 @@ namespace ts.server {
|
||||
info = this.openFile(fileName, /*openedByClient*/ false);
|
||||
}
|
||||
else {
|
||||
// if the root file was opened by client, it would belong to either
|
||||
// if the root file was opened by client, it would belong to either
|
||||
// openFileRoots or openFileReferenced.
|
||||
if (info.isOpen) {
|
||||
if (this.openFileRoots.indexOf(info) >= 0) {
|
||||
|
||||
@@ -792,7 +792,9 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private closeClientFile(fileName: string) {
|
||||
if (!fileName) { return; }
|
||||
if (!fileName) {
|
||||
return;
|
||||
}
|
||||
const file = ts.normalizePath(fileName);
|
||||
this.projectService.closeClientFile(file);
|
||||
}
|
||||
|
||||
@@ -946,7 +946,8 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
const configFile = parseJsonConfigFileContent(result.config, this.host, getDirectoryPath(normalizeSlashes(fileName)));
|
||||
const normalizedFileName = normalizeSlashes(fileName);
|
||||
const configFile = parseJsonConfigFileContent(result.config, this.host, getDirectoryPath(normalizedFileName), /*existingOptions*/ {}, normalizedFileName);
|
||||
|
||||
return {
|
||||
options: configFile.options,
|
||||
|
||||
Reference in New Issue
Block a user