mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into fixControlFlowStackOverflow
This commit is contained in:
@@ -143,6 +143,7 @@ var harnessSources = harnessCoreSources.concat([
|
||||
"customTransforms.ts",
|
||||
"programMissingFiles.ts",
|
||||
"symbolWalker.ts",
|
||||
"languageService.ts",
|
||||
].map(function (f) {
|
||||
return path.join(unittestsDirectory, f);
|
||||
})).concat([
|
||||
|
||||
@@ -12,13 +12,13 @@
|
||||
|
||||
For the latest stable version:
|
||||
|
||||
```
|
||||
```bash
|
||||
npm install -g typescript
|
||||
```
|
||||
|
||||
For our nightly builds:
|
||||
|
||||
```
|
||||
```bash
|
||||
npm install -g typescript@next
|
||||
```
|
||||
|
||||
@@ -50,19 +50,19 @@ In order to build the TypeScript compiler, ensure that you have [Git](https://gi
|
||||
|
||||
Clone a copy of the repo:
|
||||
|
||||
```
|
||||
```bash
|
||||
git clone https://github.com/Microsoft/TypeScript.git
|
||||
```
|
||||
|
||||
Change to the TypeScript directory:
|
||||
|
||||
```
|
||||
```bash
|
||||
cd TypeScript
|
||||
```
|
||||
|
||||
Install Gulp tools and dev dependencies:
|
||||
|
||||
```
|
||||
```bash
|
||||
npm install -g gulp
|
||||
npm install
|
||||
```
|
||||
@@ -88,7 +88,7 @@ gulp help # List the above commands.
|
||||
|
||||
## Usage
|
||||
|
||||
```shell
|
||||
```bash
|
||||
node built/local/tsc.js hello.ts
|
||||
```
|
||||
|
||||
|
||||
+8
-15
@@ -203,9 +203,11 @@ namespace ts {
|
||||
node.symbol = symbol;
|
||||
|
||||
if (!symbol.declarations) {
|
||||
symbol.declarations = [];
|
||||
symbol.declarations = [node];
|
||||
}
|
||||
else {
|
||||
symbol.declarations.push(node);
|
||||
}
|
||||
symbol.declarations.push(node);
|
||||
|
||||
if (symbolFlags & SymbolFlags.HasExports && !symbol.exports) {
|
||||
symbol.exports = createSymbolTable();
|
||||
@@ -282,17 +284,8 @@ namespace ts {
|
||||
const index = indexOf(functionType.parameters, node);
|
||||
return "arg" + index as __String;
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
const parentNode = node.parent && node.parent.parent;
|
||||
let nameFromParentNode: __String;
|
||||
if (parentNode && parentNode.kind === SyntaxKind.VariableStatement) {
|
||||
if ((<VariableStatement>parentNode).declarationList.declarations.length > 0) {
|
||||
const nameIdentifier = (<VariableStatement>parentNode).declarationList.declarations[0].name;
|
||||
if (isIdentifier(nameIdentifier)) {
|
||||
nameFromParentNode = nameIdentifier.escapedText;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nameFromParentNode;
|
||||
const name = getNameOfJSDocTypedef(node as JSDocTypedefTag);
|
||||
return typeof name !== "undefined" ? name.escapedText : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -598,7 +591,7 @@ namespace ts {
|
||||
// Binding of JsDocComment should be done before the current block scope container changes.
|
||||
// because the scope of JsDocComment should not be affected by whether the current node is a
|
||||
// container or not.
|
||||
if (node.jsDoc) {
|
||||
if (hasJSDocNodes(node)) {
|
||||
if (isInJavaScriptFile(node)) {
|
||||
for (const j of node.jsDoc) {
|
||||
bind(j);
|
||||
@@ -1931,7 +1924,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function bindJSDocTypedefTagIfAny(node: Node) {
|
||||
if (!node.jsDoc) {
|
||||
if (!hasJSDocNodes(node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+188
-201
@@ -58,6 +58,7 @@ namespace ts {
|
||||
let symbolInstantiationDepth = 0;
|
||||
|
||||
const emptySymbols = createSymbolTable();
|
||||
const identityMapper: (type: Type) => Type = identity;
|
||||
|
||||
const compilerOptions = host.getCompilerOptions();
|
||||
const languageVersion = getEmitScriptTarget(compilerOptions);
|
||||
@@ -1687,7 +1688,7 @@ namespace ts {
|
||||
undefined;
|
||||
}
|
||||
else {
|
||||
Debug.fail("Unknown entity name kind.");
|
||||
Debug.assertNever(name, "Unknown entity name kind.");
|
||||
}
|
||||
Debug.assert((getCheckFlags(symbol) & CheckFlags.Instantiated) === 0, "Should never get an instantiated symbol here.");
|
||||
return (symbol.flags & meaning) || dontResolveAlias ? symbol : resolveAlias(symbol);
|
||||
@@ -2096,6 +2097,10 @@ namespace ts {
|
||||
canQualifySymbol(symbolFromSymbolTable, meaning);
|
||||
}
|
||||
|
||||
function isUMDExportSymbol(symbol: Symbol) {
|
||||
return symbol && symbol.declarations && symbol.declarations[0] && isNamespaceExportDeclaration(symbol.declarations[0]);
|
||||
}
|
||||
|
||||
function trySymbolTable(symbols: SymbolTable) {
|
||||
// If symbol is directly available by its name in the symbol table
|
||||
if (isAccessible(symbols.get(symbol.escapedName))) {
|
||||
@@ -2107,6 +2112,7 @@ namespace ts {
|
||||
if (symbolFromSymbolTable.flags & SymbolFlags.Alias
|
||||
&& symbolFromSymbolTable.escapedName !== "export="
|
||||
&& !getDeclarationOfKind(symbolFromSymbolTable, SyntaxKind.ExportSpecifier)
|
||||
&& !(isUMDExportSymbol(symbolFromSymbolTable) && isExternalModule(getSourceFileOfNode(enclosingDeclaration)))
|
||||
// If `!useOnlyExternalAliasing`, we can use any type of alias to get the name
|
||||
&& (!useOnlyExternalAliasing || some(symbolFromSymbolTable.declarations, isExternalModuleImportEqualsDeclaration))) {
|
||||
|
||||
@@ -4795,22 +4801,39 @@ namespace ts {
|
||||
return typeParameters;
|
||||
}
|
||||
|
||||
// Appends the outer type parameters of a node to a set of type parameters and returns the resulting set. The function
|
||||
// allocates a new array if the input type parameter set is undefined, but otherwise it modifies the set in-place and
|
||||
// returns the same array.
|
||||
function appendOuterTypeParameters(typeParameters: TypeParameter[], node: Node): TypeParameter[] {
|
||||
// Return the outer type parameters of a node or undefined if the node has no outer type parameters.
|
||||
function getOuterTypeParameters(node: Node, includeThisTypes?: boolean): TypeParameter[] {
|
||||
while (true) {
|
||||
node = node.parent;
|
||||
if (!node) {
|
||||
return typeParameters;
|
||||
return undefined;
|
||||
}
|
||||
if (node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression ||
|
||||
node.kind === SyntaxKind.FunctionDeclaration || node.kind === SyntaxKind.FunctionExpression ||
|
||||
node.kind === SyntaxKind.MethodDeclaration || node.kind === SyntaxKind.ArrowFunction) {
|
||||
const declarations = (<ClassLikeDeclaration | FunctionLikeDeclaration>node).typeParameters;
|
||||
if (declarations) {
|
||||
return appendTypeParameters(appendOuterTypeParameters(typeParameters, node), declarations);
|
||||
}
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.ClassExpression:
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.CallSignature:
|
||||
case SyntaxKind.ConstructSignature:
|
||||
case SyntaxKind.MethodSignature:
|
||||
case SyntaxKind.FunctionType:
|
||||
case SyntaxKind.ConstructorType:
|
||||
case SyntaxKind.JSDocFunctionType:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
case SyntaxKind.JSDocTemplateTag:
|
||||
case SyntaxKind.MappedType:
|
||||
const outerTypeParameters = getOuterTypeParameters(node, includeThisTypes);
|
||||
if (node.kind === SyntaxKind.MappedType) {
|
||||
return append(outerTypeParameters, getDeclaredTypeOfTypeParameter(getSymbolOfNode((<MappedTypeNode>node).typeParameter)));
|
||||
}
|
||||
const outerAndOwnTypeParameters = appendTypeParameters(outerTypeParameters, getEffectiveTypeParameterDeclarations(<DeclarationWithTypeParameters>node) || emptyArray);
|
||||
const thisType = includeThisTypes &&
|
||||
(node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression || node.kind === SyntaxKind.InterfaceDeclaration) &&
|
||||
getDeclaredTypeOfClassOrInterface(getSymbolOfNode(node)).thisType;
|
||||
return thisType ? append(outerAndOwnTypeParameters, thisType) : outerAndOwnTypeParameters;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4818,7 +4841,7 @@ namespace ts {
|
||||
// The outer type parameters are those defined by enclosing generic classes, methods, or functions.
|
||||
function getOuterTypeParametersOfClassOrInterface(symbol: Symbol): TypeParameter[] {
|
||||
const declaration = symbol.flags & SymbolFlags.Class ? symbol.valueDeclaration : getDeclarationOfKind(symbol, SyntaxKind.InterfaceDeclaration);
|
||||
return appendOuterTypeParameters(/*typeParameters*/ undefined, declaration);
|
||||
return getOuterTypeParameters(declaration);
|
||||
}
|
||||
|
||||
// The local type parameters are the combined set of type parameters from all declarations of the class,
|
||||
@@ -6616,11 +6639,30 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getErasedSignature(signature: Signature): Signature {
|
||||
if (!signature.typeParameters) return signature;
|
||||
if (!signature.erasedSignatureCache) {
|
||||
signature.erasedSignatureCache = instantiateSignature(signature, createTypeEraser(signature.typeParameters), /*eraseTypeParameters*/ true);
|
||||
}
|
||||
return signature.erasedSignatureCache;
|
||||
return signature.typeParameters ?
|
||||
signature.erasedSignatureCache || (signature.erasedSignatureCache = createErasedSignature(signature)) :
|
||||
signature;
|
||||
}
|
||||
|
||||
function createErasedSignature(signature: Signature) {
|
||||
// Create an instantiation of the signature where all type arguments are the any type.
|
||||
return instantiateSignature(signature, createTypeEraser(signature.typeParameters), /*eraseTypeParameters*/ true);
|
||||
}
|
||||
|
||||
function getCanonicalSignature(signature: Signature): Signature {
|
||||
return signature.typeParameters ?
|
||||
signature.canonicalSignatureCache || (signature.canonicalSignatureCache = createCanonicalSignature(signature)) :
|
||||
signature;
|
||||
}
|
||||
|
||||
function createCanonicalSignature(signature: Signature) {
|
||||
// Create an instantiation of the signature where each unconstrained type parameter is replaced with
|
||||
// its original. When a generic class or interface is instantiated, each generic method in the class or
|
||||
// interface is instantiated with a fresh set of cloned type parameters (which we need to handle scenarios
|
||||
// where different generations of the same type parameter are in scope). This leads to a lot of new type
|
||||
// identities, and potentially a lot of work comparing those identities, so here we create an instantiation
|
||||
// that uses the original type identities for all unconstrained type parameters.
|
||||
return getSignatureInstantiation(signature, map(signature.typeParameters, tp => tp.target && !getConstraintOfTypeParameter(tp.target) ? tp.target : tp));
|
||||
}
|
||||
|
||||
function getOrCreateTypeFromSignature(signature: Signature): ObjectType {
|
||||
@@ -6801,7 +6843,7 @@ namespace ts {
|
||||
const id = getTypeListId(typeArguments);
|
||||
let instantiation = links.instantiations.get(id);
|
||||
if (!instantiation) {
|
||||
links.instantiations.set(id, instantiation = instantiateTypeNoAlias(type, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters)))));
|
||||
links.instantiations.set(id, instantiation = instantiateType(type, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters)))));
|
||||
}
|
||||
return instantiation;
|
||||
}
|
||||
@@ -7395,6 +7437,12 @@ namespace ts {
|
||||
type = <UnionType>createType(TypeFlags.Union | propagatedFlags);
|
||||
unionTypes.set(id, type);
|
||||
type.types = types;
|
||||
/*
|
||||
Note: This is the alias symbol (or lack thereof) that we see when we first encounter this union type.
|
||||
For aliases of identical unions, eg `type T = A | B; type U = A | B`, the symbol of the first alias encountered is the aliasSymbol.
|
||||
(In the language service, the order may depend on the order in which a user takes actions, such as hovering over symbols.)
|
||||
It's important that we create equivalent union types only once, so that's an unfortunate side effect.
|
||||
*/
|
||||
type.aliasSymbol = aliasSymbol;
|
||||
type.aliasTypeArguments = aliasTypeArguments;
|
||||
}
|
||||
@@ -7488,7 +7536,7 @@ namespace ts {
|
||||
type = <IntersectionType>createType(TypeFlags.Intersection | propagatedFlags);
|
||||
intersectionTypes.set(id, type);
|
||||
type.types = typeSet;
|
||||
type.aliasSymbol = aliasSymbol;
|
||||
type.aliasSymbol = aliasSymbol; // See comment in `getUnionTypeFromSortedList`.
|
||||
type.aliasTypeArguments = aliasTypeArguments;
|
||||
}
|
||||
return type;
|
||||
@@ -8025,11 +8073,6 @@ namespace ts {
|
||||
return instantiateList(signatures, mapper, instantiateSignature);
|
||||
}
|
||||
|
||||
function instantiateCached<T extends Type>(type: T, mapper: TypeMapper, instantiator: (item: T, mapper: TypeMapper) => T): T {
|
||||
const instantiations = mapper.instantiations || (mapper.instantiations = []);
|
||||
return <T>instantiations[type.id] || (instantiations[type.id] = instantiator(type, mapper));
|
||||
}
|
||||
|
||||
function makeUnaryTypeMapper(source: Type, target: Type) {
|
||||
return (t: Type) => t === source ? target : t;
|
||||
}
|
||||
@@ -8051,11 +8094,9 @@ namespace ts {
|
||||
|
||||
function createTypeMapper(sources: TypeParameter[], targets: Type[]): TypeMapper {
|
||||
Debug.assert(targets === undefined || sources.length === targets.length);
|
||||
const mapper: TypeMapper = sources.length === 1 ? makeUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) :
|
||||
return sources.length === 1 ? makeUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) :
|
||||
sources.length === 2 ? makeBinaryTypeMapper(sources[0], targets ? targets[0] : anyType, sources[1], targets ? targets[1] : anyType) :
|
||||
makeArrayTypeMapper(sources, targets);
|
||||
mapper.mappedTypes = sources;
|
||||
return mapper;
|
||||
makeArrayTypeMapper(sources, targets);
|
||||
}
|
||||
|
||||
function createTypeEraser(sources: TypeParameter[]): TypeMapper {
|
||||
@@ -8066,10 +8107,8 @@ namespace ts {
|
||||
* Maps forward-references to later types parameters to the empty object type.
|
||||
* This is used during inference when instantiating type parameter defaults.
|
||||
*/
|
||||
function createBackreferenceMapper(typeParameters: TypeParameter[], index: number) {
|
||||
const mapper: TypeMapper = t => indexOf(typeParameters, t) >= index ? emptyObjectType : t;
|
||||
mapper.mappedTypes = typeParameters;
|
||||
return mapper;
|
||||
function createBackreferenceMapper(typeParameters: TypeParameter[], index: number): TypeMapper {
|
||||
return t => indexOf(typeParameters, t) >= index ? emptyObjectType : t;
|
||||
}
|
||||
|
||||
function isInferenceContext(mapper: TypeMapper): mapper is InferenceContext {
|
||||
@@ -8082,20 +8121,12 @@ namespace ts {
|
||||
mapper;
|
||||
}
|
||||
|
||||
function identityMapper(type: Type): Type {
|
||||
return type;
|
||||
}
|
||||
|
||||
function combineTypeMappers(mapper1: TypeMapper, mapper2: TypeMapper): TypeMapper {
|
||||
const mapper: TypeMapper = t => instantiateType(mapper1(t), mapper2);
|
||||
mapper.mappedTypes = concatenate(mapper1.mappedTypes, mapper2.mappedTypes);
|
||||
return mapper;
|
||||
return t => instantiateType(mapper1(t), mapper2);
|
||||
}
|
||||
|
||||
function createReplacementMapper(source: Type, target: Type, baseMapper: TypeMapper) {
|
||||
const mapper: TypeMapper = t => t === source ? target : baseMapper(t);
|
||||
mapper.mappedTypes = baseMapper.mappedTypes;
|
||||
return mapper;
|
||||
function createReplacementMapper(source: Type, target: Type, baseMapper: TypeMapper): TypeMapper {
|
||||
return t => t === source ? target : baseMapper(t);
|
||||
}
|
||||
|
||||
function cloneTypeParameter(typeParameter: TypeParameter): TypeParameter {
|
||||
@@ -8175,13 +8206,53 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function instantiateAnonymousType(type: AnonymousType, mapper: TypeMapper): AnonymousType {
|
||||
const result = <AnonymousType>createObjectType(ObjectFlags.Anonymous | ObjectFlags.Instantiated, type.symbol);
|
||||
result.target = type.objectFlags & ObjectFlags.Instantiated ? type.target : type;
|
||||
result.mapper = type.objectFlags & ObjectFlags.Instantiated ? combineTypeMappers(type.mapper, mapper) : mapper;
|
||||
result.aliasSymbol = type.aliasSymbol;
|
||||
result.aliasTypeArguments = instantiateTypes(type.aliasTypeArguments, mapper);
|
||||
return result;
|
||||
function getAnonymousTypeInstantiation(type: AnonymousType, mapper: TypeMapper) {
|
||||
const target = type.objectFlags & ObjectFlags.Instantiated ? type.target : type;
|
||||
const symbol = target.symbol;
|
||||
const links = getSymbolLinks(symbol);
|
||||
let typeParameters = links.typeParameters;
|
||||
if (!typeParameters) {
|
||||
// The first time an anonymous type is instantiated we compute and store a list of the type
|
||||
// parameters that are in scope (and therefore potentially referenced). For type literals that
|
||||
// aren't the right hand side of a generic type alias declaration we optimize by reducing the
|
||||
// set of type parameters to those that are actually referenced somewhere in the literal.
|
||||
const declaration = symbol.declarations[0];
|
||||
const outerTypeParameters = getOuterTypeParameters(declaration, /*includeThisTypes*/ true) || emptyArray;
|
||||
typeParameters = symbol.flags & SymbolFlags.TypeLiteral && !target.aliasTypeArguments ?
|
||||
filter(outerTypeParameters, tp => isTypeParameterReferencedWithin(tp, declaration)) :
|
||||
outerTypeParameters;
|
||||
links.typeParameters = typeParameters;
|
||||
if (typeParameters.length) {
|
||||
links.instantiations = createMap<Type>();
|
||||
links.instantiations.set(getTypeListId(typeParameters), target);
|
||||
}
|
||||
}
|
||||
if (typeParameters.length) {
|
||||
// We are instantiating an anonymous type that has one or more type parameters in scope. Apply the
|
||||
// mapper to the type parameters to produce the effective list of type arguments, and compute the
|
||||
// instantiation cache key from the type IDs of the type arguments.
|
||||
const combinedMapper = type.objectFlags & ObjectFlags.Instantiated ? combineTypeMappers(type.mapper, mapper) : mapper;
|
||||
const typeArguments = map(typeParameters, combinedMapper);
|
||||
const id = getTypeListId(typeArguments);
|
||||
let result = links.instantiations.get(id);
|
||||
if (!result) {
|
||||
const newMapper = createTypeMapper(typeParameters, typeArguments);
|
||||
result = target.objectFlags & ObjectFlags.Mapped ? instantiateMappedType(<MappedType>target, newMapper) : instantiateAnonymousType(target, newMapper);
|
||||
links.instantiations.set(id, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
function isTypeParameterReferencedWithin(tp: TypeParameter, node: Node) {
|
||||
return tp.isThisType ? forEachChild(node, checkThis) : forEachChild(node, checkIdentifier);
|
||||
function checkThis(node: Node): boolean {
|
||||
return node.kind === SyntaxKind.ThisType || forEachChild(node, checkThis);
|
||||
}
|
||||
function checkIdentifier(node: Node): boolean {
|
||||
return node.kind === SyntaxKind.Identifier && isPartOfTypeNode(node) && getTypeFromTypeNode(<TypeNode>node) === tp || forEachChild(node, checkIdentifier);
|
||||
}
|
||||
}
|
||||
|
||||
function instantiateMappedType(type: MappedType, mapper: TypeMapper): Type {
|
||||
@@ -8198,164 +8269,64 @@ namespace ts {
|
||||
if (typeVariable !== mappedTypeVariable) {
|
||||
return mapType(mappedTypeVariable, t => {
|
||||
if (isMappableType(t)) {
|
||||
return instantiateMappedObjectType(type, createReplacementMapper(typeVariable, t, mapper));
|
||||
return instantiateAnonymousType(type, createReplacementMapper(typeVariable, t, mapper));
|
||||
}
|
||||
return t;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return instantiateMappedObjectType(type, mapper);
|
||||
return instantiateAnonymousType(type, mapper);
|
||||
}
|
||||
|
||||
function isMappableType(type: Type) {
|
||||
return type.flags & (TypeFlags.TypeParameter | TypeFlags.Object | TypeFlags.Intersection | TypeFlags.IndexedAccess);
|
||||
}
|
||||
|
||||
function instantiateMappedObjectType(type: MappedType, mapper: TypeMapper): Type {
|
||||
const result = <MappedType>createObjectType(ObjectFlags.Mapped | ObjectFlags.Instantiated, type.symbol);
|
||||
result.declaration = type.declaration;
|
||||
result.mapper = type.mapper ? combineTypeMappers(type.mapper, mapper) : mapper;
|
||||
function instantiateAnonymousType(type: AnonymousType, mapper: TypeMapper): AnonymousType {
|
||||
const result = <AnonymousType>createObjectType(type.objectFlags | ObjectFlags.Instantiated, type.symbol);
|
||||
if (type.objectFlags & ObjectFlags.Mapped) {
|
||||
(<MappedType>result).declaration = (<MappedType>type).declaration;
|
||||
}
|
||||
result.target = type;
|
||||
result.mapper = mapper;
|
||||
result.aliasSymbol = type.aliasSymbol;
|
||||
result.aliasTypeArguments = instantiateTypes(type.aliasTypeArguments, mapper);
|
||||
return result;
|
||||
}
|
||||
|
||||
function isSymbolInScopeOfMappedTypeParameter(symbol: Symbol, mapper: TypeMapper) {
|
||||
if (!(symbol.declarations && symbol.declarations.length)) {
|
||||
return false;
|
||||
}
|
||||
const mappedTypes = mapper.mappedTypes;
|
||||
// Starting with the parent of the symbol's declaration, check if the mapper maps any of
|
||||
// the type parameters introduced by enclosing declarations. We just pick the first
|
||||
// declaration since multiple declarations will all have the same parent anyway.
|
||||
return !!findAncestor(symbol.declarations[0], node => {
|
||||
if (node.kind === SyntaxKind.ModuleDeclaration || node.kind === SyntaxKind.SourceFile) {
|
||||
return "quit";
|
||||
}
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.FunctionType:
|
||||
case SyntaxKind.ConstructorType:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.MethodSignature:
|
||||
case SyntaxKind.Constructor:
|
||||
case SyntaxKind.CallSignature:
|
||||
case SyntaxKind.ConstructSignature:
|
||||
case SyntaxKind.IndexSignature:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.ClassExpression:
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
const typeParameters = getEffectiveTypeParameterDeclarations(node as DeclarationWithTypeParameters);
|
||||
if (typeParameters) {
|
||||
for (const d of typeParameters) {
|
||||
if (contains(mappedTypes, getDeclaredTypeOfTypeParameter(getSymbolOfNode(d)))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isClassLike(node) || node.kind === SyntaxKind.InterfaceDeclaration) {
|
||||
const thisType = getDeclaredTypeOfClassOrInterface(getSymbolOfNode(node)).thisType;
|
||||
if (thisType && contains(mappedTypes, thisType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.MappedType:
|
||||
if (contains(mappedTypes, getDeclaredTypeOfTypeParameter(getSymbolOfNode((<MappedTypeNode>node).typeParameter)))) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.JSDocFunctionType:
|
||||
const func = node as JSDocFunctionType;
|
||||
for (const p of func.parameters) {
|
||||
if (contains(mappedTypes, getTypeOfNode(p))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function isTopLevelTypeAlias(symbol: Symbol) {
|
||||
if (symbol.declarations && symbol.declarations.length) {
|
||||
const parentKind = symbol.declarations[0].parent.kind;
|
||||
return parentKind === SyntaxKind.SourceFile || parentKind === SyntaxKind.ModuleBlock;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function instantiateType(type: Type, mapper: TypeMapper): Type {
|
||||
if (type && mapper !== identityMapper) {
|
||||
// If we are instantiating a type that has a top-level type alias, obtain the instantiation through
|
||||
// the type alias instead in order to share instantiations for the same type arguments. This can
|
||||
// dramatically reduce the number of structurally identical types we generate. Note that we can only
|
||||
// perform this optimization for top-level type aliases. Consider:
|
||||
//
|
||||
// function f1<T>(x: T) {
|
||||
// type Foo<X> = { x: X, t: T };
|
||||
// let obj: Foo<T> = { x: x };
|
||||
// return obj;
|
||||
// }
|
||||
// function f2<U>(x: U) { return f1(x); }
|
||||
// let z = f2(42);
|
||||
//
|
||||
// Above, the declaration of f2 has an inferred return type that is an instantiation of f1's Foo<X>
|
||||
// equivalent to { x: U, t: U }. When instantiating this return type, we can't go back to Foo<X>'s
|
||||
// cache because all cached instantiations are of the form { x: ???, t: T }, i.e. they have not been
|
||||
// instantiated for T. Instead, we need to further instantiate the { x: U, t: U } form.
|
||||
if (type.aliasSymbol && isTopLevelTypeAlias(type.aliasSymbol)) {
|
||||
if (type.aliasTypeArguments) {
|
||||
return getTypeAliasInstantiation(type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
|
||||
if (type.flags & TypeFlags.TypeParameter) {
|
||||
return mapper(<TypeParameter>type);
|
||||
}
|
||||
if (type.flags & TypeFlags.Object) {
|
||||
if ((<ObjectType>type).objectFlags & ObjectFlags.Anonymous) {
|
||||
// If the anonymous type originates in a declaration of a function, method, class, or
|
||||
// interface, in an object type literal, or in an object literal expression, we may need
|
||||
// to instantiate the type because it might reference a type parameter.
|
||||
return type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral) && type.symbol.declarations ?
|
||||
getAnonymousTypeInstantiation(<AnonymousType>type, mapper) : type;
|
||||
}
|
||||
if ((<ObjectType>type).objectFlags & ObjectFlags.Mapped) {
|
||||
return getAnonymousTypeInstantiation(<MappedType>type, mapper);
|
||||
}
|
||||
if ((<ObjectType>type).objectFlags & ObjectFlags.Reference) {
|
||||
return createTypeReference((<TypeReference>type).target, instantiateTypes((<TypeReference>type).typeArguments, mapper));
|
||||
}
|
||||
return type;
|
||||
}
|
||||
return instantiateTypeNoAlias(type, mapper);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
function instantiateTypeNoAlias(type: Type, mapper: TypeMapper): Type {
|
||||
if (type.flags & TypeFlags.TypeParameter) {
|
||||
return mapper(<TypeParameter>type);
|
||||
}
|
||||
if (type.flags & TypeFlags.Object) {
|
||||
if ((<ObjectType>type).objectFlags & ObjectFlags.Anonymous) {
|
||||
// If the anonymous type originates in a declaration of a function, method, class, or
|
||||
// interface, in an object type literal, or in an object literal expression, we may need
|
||||
// to instantiate the type because it might reference a type parameter. We skip instantiation
|
||||
// if none of the type parameters that are in scope in the type's declaration are mapped by
|
||||
// the given mapper, however we can only do that analysis if the type isn't itself an
|
||||
// instantiation.
|
||||
return type.symbol &&
|
||||
type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral) &&
|
||||
((<ObjectType>type).objectFlags & ObjectFlags.Instantiated || isSymbolInScopeOfMappedTypeParameter(type.symbol, mapper)) ?
|
||||
instantiateCached(type, mapper, instantiateAnonymousType) : type;
|
||||
if (type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Primitive)) {
|
||||
return getUnionType(instantiateTypes((<UnionType>type).types, mapper), /*subtypeReduction*/ false, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
|
||||
}
|
||||
if ((<ObjectType>type).objectFlags & ObjectFlags.Mapped) {
|
||||
return instantiateCached(type, mapper, instantiateMappedType);
|
||||
if (type.flags & TypeFlags.Intersection) {
|
||||
return getIntersectionType(instantiateTypes((<IntersectionType>type).types, mapper), type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
|
||||
}
|
||||
if ((<ObjectType>type).objectFlags & ObjectFlags.Reference) {
|
||||
return createTypeReference((<TypeReference>type).target, instantiateTypes((<TypeReference>type).typeArguments, mapper));
|
||||
if (type.flags & TypeFlags.Index) {
|
||||
return getIndexType(instantiateType((<IndexType>type).type, mapper));
|
||||
}
|
||||
if (type.flags & TypeFlags.IndexedAccess) {
|
||||
return getIndexedAccessType(instantiateType((<IndexedAccessType>type).objectType, mapper), instantiateType((<IndexedAccessType>type).indexType, mapper));
|
||||
}
|
||||
}
|
||||
if (type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Primitive)) {
|
||||
return getUnionType(instantiateTypes((<UnionType>type).types, mapper), /*subtypeReduction*/ false, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
|
||||
}
|
||||
if (type.flags & TypeFlags.Intersection) {
|
||||
return getIntersectionType(instantiateTypes((<IntersectionType>type).types, mapper), type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
|
||||
}
|
||||
if (type.flags & TypeFlags.Index) {
|
||||
return getIndexType(instantiateType((<IndexType>type).type, mapper));
|
||||
}
|
||||
if (type.flags & TypeFlags.IndexedAccess) {
|
||||
return getIndexedAccessType(instantiateType((<IndexedAccessType>type).objectType, mapper), instantiateType((<IndexedAccessType>type).indexType, mapper));
|
||||
}
|
||||
return type;
|
||||
}
|
||||
@@ -8530,7 +8501,8 @@ namespace ts {
|
||||
return Ternary.False;
|
||||
}
|
||||
|
||||
if (source.typeParameters) {
|
||||
if (source.typeParameters && source.typeParameters !== target.typeParameters) {
|
||||
target = getCanonicalSignature(target);
|
||||
source = instantiateSignatureInContextOf(source, target, /*contextualMapper*/ undefined, compareTypes);
|
||||
}
|
||||
|
||||
@@ -9782,15 +9754,15 @@ namespace ts {
|
||||
return type.flags & TypeFlags.TypeParameter && !getConstraintFromTypeParameter(<TypeParameter>type);
|
||||
}
|
||||
|
||||
function isTypeReferenceWithGenericArguments(type: Type) {
|
||||
return getObjectFlags(type) & ObjectFlags.Reference && some((<TypeReference>type).typeArguments, isUnconstrainedTypeParameter);
|
||||
function isTypeReferenceWithGenericArguments(type: Type): boolean {
|
||||
return getObjectFlags(type) & ObjectFlags.Reference && some((<TypeReference>type).typeArguments, t => isUnconstrainedTypeParameter(t) || isTypeReferenceWithGenericArguments(t));
|
||||
}
|
||||
|
||||
/**
|
||||
* getTypeReferenceId(A<T, number, U>) returns "111=0-12=1"
|
||||
* where A.id=111 and number.id=12
|
||||
*/
|
||||
function getTypeReferenceId(type: TypeReference, typeParameters: Type[]) {
|
||||
function getTypeReferenceId(type: TypeReference, typeParameters: Type[], depth = 0) {
|
||||
let result = "" + type.target.id;
|
||||
for (const t of type.typeArguments) {
|
||||
if (isUnconstrainedTypeParameter(t)) {
|
||||
@@ -9801,6 +9773,9 @@ namespace ts {
|
||||
}
|
||||
result += "=" + index;
|
||||
}
|
||||
else if (depth < 4 && isTypeReferenceWithGenericArguments(t)) {
|
||||
result += "<" + getTypeReferenceId(t as TypeReference, typeParameters, depth + 1) + ">";
|
||||
}
|
||||
else {
|
||||
result += "-" + t.id;
|
||||
}
|
||||
@@ -10368,7 +10343,6 @@ namespace ts {
|
||||
function createInferenceContext(signature: Signature, flags: InferenceFlags, compareTypes?: TypeComparer, baseInferences?: InferenceInfo[]): InferenceContext {
|
||||
const inferences = baseInferences ? map(baseInferences, cloneInferenceInfo) : map(signature.typeParameters, createInferenceInfo);
|
||||
const context = mapper as InferenceContext;
|
||||
context.mappedTypes = signature.typeParameters;
|
||||
context.signature = signature;
|
||||
context.inferences = inferences;
|
||||
context.flags = flags;
|
||||
@@ -13582,6 +13556,7 @@ namespace ts {
|
||||
for (let i = 0; i < node.properties.length; i++) {
|
||||
const memberDecl = node.properties[i];
|
||||
let member = memberDecl.symbol;
|
||||
let literalName: __String | undefined;
|
||||
if (memberDecl.kind === SyntaxKind.PropertyAssignment ||
|
||||
memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment ||
|
||||
isObjectLiteralMethod(memberDecl)) {
|
||||
@@ -13592,6 +13567,12 @@ namespace ts {
|
||||
|
||||
let type: Type;
|
||||
if (memberDecl.kind === SyntaxKind.PropertyAssignment) {
|
||||
if (memberDecl.name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
const t = checkComputedPropertyName(<ComputedPropertyName>memberDecl.name);
|
||||
if (t.flags & TypeFlags.Literal) {
|
||||
literalName = escapeLeadingUnderscores("" + (t as LiteralType).value);
|
||||
}
|
||||
}
|
||||
type = checkPropertyAssignment(<PropertyAssignment>memberDecl, checkMode);
|
||||
}
|
||||
else if (memberDecl.kind === SyntaxKind.MethodDeclaration) {
|
||||
@@ -13608,7 +13589,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
typeFlags |= type.flags;
|
||||
const prop = createSymbol(SymbolFlags.Property | member.flags, member.escapedName);
|
||||
const prop = createSymbol(SymbolFlags.Property | member.flags, literalName || member.escapedName);
|
||||
if (inDestructuringPattern) {
|
||||
// If object literal is an assignment pattern and if the assignment pattern specifies a default value
|
||||
// for the property, make the property optional.
|
||||
@@ -13618,7 +13599,7 @@ namespace ts {
|
||||
if (isOptional) {
|
||||
prop.flags |= SymbolFlags.Optional;
|
||||
}
|
||||
if (hasDynamicName(memberDecl)) {
|
||||
if (!literalName && hasDynamicName(memberDecl)) {
|
||||
patternWithComputedProperties = true;
|
||||
}
|
||||
}
|
||||
@@ -13676,7 +13657,7 @@ namespace ts {
|
||||
checkNodeDeferred(memberDecl);
|
||||
}
|
||||
|
||||
if (hasDynamicName(memberDecl)) {
|
||||
if (!literalName && hasDynamicName(memberDecl)) {
|
||||
if (isNumericName(memberDecl.name)) {
|
||||
hasComputedNumberProperty = true;
|
||||
}
|
||||
@@ -16403,7 +16384,7 @@ namespace ts {
|
||||
// This code-path is called by language service
|
||||
return resolveStatelessJsxOpeningLikeElement(<JsxOpeningLikeElement>node, checkExpression((<JsxOpeningLikeElement>node).tagName), candidatesOutArray);
|
||||
}
|
||||
Debug.fail("Branch in 'resolveSignature' should be unreachable.");
|
||||
Debug.assertNever(node, "Branch in 'resolveSignature' should be unreachable.");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -18078,7 +18059,7 @@ namespace ts {
|
||||
|
||||
function checkParenthesizedExpression(node: ParenthesizedExpression, checkMode?: CheckMode): Type {
|
||||
if (isInJavaScriptFile(node) && node.jsDoc) {
|
||||
const typecasts = flatMap(node.jsDoc, doc => filter(doc.tags, tag => tag.kind === SyntaxKind.JSDocTypeTag));
|
||||
const typecasts = flatMap(node.jsDoc, doc => filter(doc.tags, tag => tag.kind === SyntaxKind.JSDocTypeTag && !!(tag as JSDocTypeTag).typeExpression && !!(tag as JSDocTypeTag).typeExpression.type));
|
||||
if (typecasts && typecasts.length) {
|
||||
// We should have already issued an error if there were multiple type jsdocs
|
||||
const cast = typecasts[0] as JSDocTypeTag;
|
||||
@@ -19214,6 +19195,8 @@ namespace ts {
|
||||
switch (d.kind) {
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
// A jsdoc typedef is, by definition, a type alias
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
return DeclarationSpaces.ExportType;
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
return isAmbientModule(d) || getModuleInstanceState(d) !== ModuleInstanceState.NonInstantiated
|
||||
@@ -19883,7 +19866,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else if (compilerOptions.noUnusedLocals) {
|
||||
forEach(local.declarations, d => errorUnusedLocal(getNameOfDeclaration(d) || d, unescapeLeadingUnderscores(local.escapedName)));
|
||||
forEach(local.declarations, d => errorUnusedLocal(d, unescapeLeadingUnderscores(local.escapedName)));
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -19898,7 +19881,8 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
function errorUnusedLocal(node: Node, name: string) {
|
||||
function errorUnusedLocal(declaration: Declaration, name: string) {
|
||||
const node = getNameOfDeclaration(declaration) || declaration;
|
||||
if (isIdentifierThatStartsWithUnderScore(node)) {
|
||||
const declaration = getRootDeclaration(node.parent);
|
||||
if (declaration.kind === SyntaxKind.VariableDeclaration && isForInOrOfStatement(declaration.parent.parent)) {
|
||||
@@ -19965,7 +19949,7 @@ namespace ts {
|
||||
if (!local.isReferenced && !local.exportSymbol) {
|
||||
for (const declaration of local.declarations) {
|
||||
if (!isAmbientModule(declaration)) {
|
||||
errorUnusedLocal(getNameOfDeclaration(declaration), unescapeLeadingUnderscores(local.escapedName));
|
||||
errorUnusedLocal(declaration, unescapeLeadingUnderscores(local.escapedName));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21580,7 +21564,7 @@ namespace ts {
|
||||
return true;
|
||||
}
|
||||
|
||||
type InheritanceInfoMap = { prop: Symbol; containingType: Type };
|
||||
interface InheritanceInfoMap { prop: Symbol; containingType: Type; }
|
||||
const seen = createUnderscoreEscapedMap<InheritanceInfoMap>();
|
||||
forEach(resolveDeclaredMembers(type).declaredProperties, p => { seen.set(p.escapedName, { prop: p, containingType: type }); });
|
||||
let ok = true;
|
||||
@@ -23052,6 +23036,9 @@ namespace ts {
|
||||
: undefined;
|
||||
return objectType && getPropertyOfType(objectType, escapeLeadingUnderscores((node as StringLiteral | NumericLiteral).text));
|
||||
|
||||
case SyntaxKind.DefaultKeyword:
|
||||
return getSymbolOfNode(node.parent);
|
||||
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
@@ -24584,7 +24571,7 @@ namespace ts {
|
||||
currentKind = SetAccessor;
|
||||
}
|
||||
else {
|
||||
Debug.fail("Unexpected syntax kind:" + (<Node>prop).kind);
|
||||
Debug.assertNever(prop, "Unexpected syntax kind:" + (<Node>prop).kind);
|
||||
}
|
||||
|
||||
const effectiveName = getPropertyNameForPropertyNameNode(name);
|
||||
|
||||
@@ -1057,7 +1057,7 @@ namespace ts {
|
||||
errors.push(createDiagnosticForNodeInSourceFile(sourceFile, element.name, extraKeyDiagnosticMessage, keyText));
|
||||
}
|
||||
const value = convertPropertyValueToJson(element.initializer, option);
|
||||
if (typeof keyText !== "undefined" && typeof value !== "undefined") {
|
||||
if (typeof keyText !== "undefined") {
|
||||
result[keyText] = value;
|
||||
// Notify key value set, if user asked for it
|
||||
if (jsonConversionNotifier &&
|
||||
@@ -1104,7 +1104,7 @@ namespace ts {
|
||||
return false;
|
||||
|
||||
case SyntaxKind.NullKeyword:
|
||||
reportInvalidOptionValue(!!option);
|
||||
reportInvalidOptionValue(option && option.name === "extends"); // "extends" is the only option we don't allow null/undefined for
|
||||
return null; // tslint:disable-line:no-null-keyword
|
||||
|
||||
case SyntaxKind.StringLiteral:
|
||||
@@ -1189,6 +1189,7 @@ namespace ts {
|
||||
|
||||
function isCompilerOptionsValue(option: CommandLineOption, value: any): value is CompilerOptionsValue {
|
||||
if (option) {
|
||||
if (isNullOrUndefined(value)) return true; // All options are undefinable/nullable
|
||||
if (option.type === "list") {
|
||||
return isArray(value);
|
||||
}
|
||||
@@ -1379,6 +1380,17 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function isNullOrUndefined(x: any): x is null | undefined {
|
||||
// tslint:disable-next-line:no-null-keyword
|
||||
return x === undefined || x === null;
|
||||
}
|
||||
|
||||
function directoryOfCombinedPath(fileName: string, basePath: string) {
|
||||
// Use the `identity` function to avoid canonicalizing the path, as it must remain noncanonical
|
||||
// until consistient casing errors are reported
|
||||
return getDirectoryPath(toPath(fileName, basePath, identity));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the contents of a config file from json or json source file (tsconfig.json).
|
||||
* @param json The contents of the config file to parse
|
||||
@@ -1419,7 +1431,7 @@ namespace ts {
|
||||
|
||||
function getFileNames(): ExpandResult {
|
||||
let fileNames: ReadonlyArray<string>;
|
||||
if (hasProperty(raw, "files")) {
|
||||
if (hasProperty(raw, "files") && !isNullOrUndefined(raw["files"])) {
|
||||
if (isArray(raw["files"])) {
|
||||
fileNames = <ReadonlyArray<string>>raw["files"];
|
||||
if (fileNames.length === 0) {
|
||||
@@ -1432,7 +1444,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
let includeSpecs: ReadonlyArray<string>;
|
||||
if (hasProperty(raw, "include")) {
|
||||
if (hasProperty(raw, "include") && !isNullOrUndefined(raw["include"])) {
|
||||
if (isArray(raw["include"])) {
|
||||
includeSpecs = <ReadonlyArray<string>>raw["include"];
|
||||
}
|
||||
@@ -1442,7 +1454,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
let excludeSpecs: ReadonlyArray<string>;
|
||||
if (hasProperty(raw, "exclude")) {
|
||||
if (hasProperty(raw, "exclude") && !isNullOrUndefined(raw["exclude"])) {
|
||||
if (isArray(raw["exclude"])) {
|
||||
excludeSpecs = <ReadonlyArray<string>>raw["exclude"];
|
||||
}
|
||||
@@ -1461,7 +1473,7 @@ namespace ts {
|
||||
includeSpecs = ["**/*"];
|
||||
}
|
||||
|
||||
const result = matchFileNames(fileNames, includeSpecs, excludeSpecs, basePath, options, host, errors, extraFileExtensions, sourceFile);
|
||||
const result = matchFileNames(fileNames, includeSpecs, excludeSpecs, configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath, options, host, errors, extraFileExtensions, sourceFile);
|
||||
|
||||
if (result.fileNames.length === 0 && !hasProperty(raw, "files") && resolutionStack.length === 0) {
|
||||
errors.push(
|
||||
@@ -1552,7 +1564,7 @@ namespace ts {
|
||||
host: ParseConfigHost,
|
||||
basePath: string,
|
||||
getCanonicalFileName: (fileName: string) => string,
|
||||
configFileName: string,
|
||||
configFileName: string | undefined,
|
||||
errors: Push<Diagnostic>
|
||||
): ParsedTsconfig {
|
||||
if (hasProperty(json, "excludes")) {
|
||||
@@ -1571,7 +1583,8 @@ namespace ts {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "extends", "string"));
|
||||
}
|
||||
else {
|
||||
extendedConfigPath = getExtendsConfigPath(json.extends, host, basePath, getCanonicalFileName, errors, createCompilerDiagnostic);
|
||||
const newBase = configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath;
|
||||
extendedConfigPath = getExtendsConfigPath(json.extends, host, newBase, getCanonicalFileName, errors, createCompilerDiagnostic);
|
||||
}
|
||||
}
|
||||
return { raw: json, options, typeAcquisition, extendedConfigPath };
|
||||
@@ -1582,7 +1595,7 @@ namespace ts {
|
||||
host: ParseConfigHost,
|
||||
basePath: string,
|
||||
getCanonicalFileName: (fileName: string) => string,
|
||||
configFileName: string,
|
||||
configFileName: string | undefined,
|
||||
errors: Push<Diagnostic>
|
||||
): ParsedTsconfig {
|
||||
const options = getDefaultCompilerOptions(configFileName);
|
||||
@@ -1603,10 +1616,11 @@ namespace ts {
|
||||
onSetValidOptionKeyValueInRoot(key: string, _keyNode: PropertyName, value: CompilerOptionsValue, valueNode: Expression) {
|
||||
switch (key) {
|
||||
case "extends":
|
||||
const newBase = configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath;
|
||||
extendedConfigPath = getExtendsConfigPath(
|
||||
<string>value,
|
||||
host,
|
||||
basePath,
|
||||
newBase,
|
||||
getCanonicalFileName,
|
||||
errors,
|
||||
(message, arg0) =>
|
||||
@@ -1803,6 +1817,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function normalizeOptionValue(option: CommandLineOption, basePath: string, value: any): CompilerOptionsValue {
|
||||
if (isNullOrUndefined(value)) return undefined;
|
||||
if (option.type === "list") {
|
||||
const listOption = <CommandLineOptionOfListType>option;
|
||||
if (listOption.element.isFilePath || typeof listOption.element.type !== "string") {
|
||||
@@ -1827,6 +1842,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function convertJsonOptionOfCustomType(opt: CommandLineOptionOfCustomType, value: string, errors: Push<Diagnostic>) {
|
||||
if (isNullOrUndefined(value)) return undefined;
|
||||
const key = value.toLowerCase();
|
||||
const val = opt.type.get(key);
|
||||
if (val !== undefined) {
|
||||
@@ -1977,7 +1993,7 @@ namespace ts {
|
||||
// remove a literal file.
|
||||
if (fileNames) {
|
||||
for (const fileName of fileNames) {
|
||||
const file = combinePaths(basePath, fileName);
|
||||
const file = getNormalizedAbsolutePath(fileName, basePath);
|
||||
literalFileMap.set(keyMapper(file), file);
|
||||
}
|
||||
}
|
||||
|
||||
+20
-22
@@ -9,6 +9,15 @@ namespace ts {
|
||||
export const version = `${versionMajorMinor}.0`;
|
||||
}
|
||||
|
||||
namespace ts {
|
||||
export function isExternalModuleNameRelative(moduleName: string): boolean {
|
||||
// TypeScript 1.0 spec (April 2014): 11.2.1
|
||||
// An external module name is "relative" if the first term is "." or "..".
|
||||
// Update: We also consider a path like `C:\foo.ts` "relative" because we do not search for it in `node_modules` or treat it as an ambient module.
|
||||
return pathIsRelative(moduleName) || isRootedDiskPath(moduleName);
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
|
||||
@@ -40,7 +49,6 @@ namespace ts {
|
||||
return new MapCtr<T>() as UnderscoreEscapedMap<T>;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function createSymbolTable(symbols?: ReadonlyArray<Symbol>): SymbolTable {
|
||||
const result = createMap<Symbol>() as SymbolTable;
|
||||
if (symbols) {
|
||||
@@ -1220,6 +1228,9 @@ namespace ts {
|
||||
/** Does nothing. */
|
||||
export function noop(): void {}
|
||||
|
||||
/** Returns its argument. */
|
||||
export function identity<T>(x: T) { return x; }
|
||||
|
||||
/** Throws an error because a function is not implemented. */
|
||||
export function notImplemented(): never {
|
||||
throw new Error("Not implemented");
|
||||
@@ -1283,7 +1294,7 @@ namespace ts {
|
||||
args[i] = arguments[i];
|
||||
}
|
||||
|
||||
return t => reduceLeft<(t: T) => T, T>(args, (u, f) => f(u), t);
|
||||
return t => reduceLeft(args, (u, f) => f(u), t);
|
||||
}
|
||||
else if (d) {
|
||||
return t => d(c(b(a(t))));
|
||||
@@ -1604,18 +1615,10 @@ namespace ts {
|
||||
return path && !isRootedDiskPath(path) && path.indexOf("://") !== -1;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function pathIsRelative(path: string): boolean {
|
||||
return /^\.\.?($|[\\/])/.test(path);
|
||||
}
|
||||
|
||||
export function isExternalModuleNameRelative(moduleName: string): boolean {
|
||||
// TypeScript 1.0 spec (April 2014): 11.2.1
|
||||
// An external module name is "relative" if the first term is "." or "..".
|
||||
// Update: We also consider a path like `C:\foo.ts` "relative" because we do not search for it in `node_modules` or treat it as an ambient module.
|
||||
return pathIsRelative(moduleName) || isRootedDiskPath(moduleName);
|
||||
}
|
||||
|
||||
/** @deprecated Use `!isExternalModuleNameRelative(moduleName)` instead. */
|
||||
export function moduleHasNonRelativeName(moduleName: string): boolean {
|
||||
return !isExternalModuleNameRelative(moduleName);
|
||||
@@ -1639,7 +1642,6 @@ namespace ts {
|
||||
return moduleResolution;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function hasZeroOrOneAsteriskCharacter(str: string): boolean {
|
||||
let seenAsterisk = false;
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
@@ -1864,17 +1866,14 @@ namespace ts {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function startsWith(str: string, prefix: string): boolean {
|
||||
return str.lastIndexOf(prefix, 0) === 0;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function removePrefix(str: string, prefix: string): string {
|
||||
return startsWith(str, prefix) ? str.substr(prefix.length) : str;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function endsWith(str: string, suffix: string): boolean {
|
||||
const expectedPos = str.length - suffix.length;
|
||||
return expectedPos >= 0 && str.indexOf(suffix, expectedPos) === expectedPos;
|
||||
@@ -1888,7 +1887,6 @@ namespace ts {
|
||||
return path.length > extension.length && endsWith(path, extension);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function fileExtensionIsOneOf(path: string, extensions: ReadonlyArray<string>): boolean {
|
||||
for (const extension of extensions) {
|
||||
if (fileExtensionIs(path, extension)) {
|
||||
@@ -1905,7 +1903,6 @@ namespace ts {
|
||||
const reservedCharacterPattern = /[^\w\s\/]/g;
|
||||
const wildcardCharCodes = [CharacterCodes.asterisk, CharacterCodes.question];
|
||||
|
||||
/* @internal */
|
||||
export const commonPackageFolders: ReadonlyArray<string> = ["node_modules", "bower_components", "jspm_packages"];
|
||||
|
||||
const implicitExcludePathRegexPattern = `(?!(${commonPackageFolders.join("|")})(/|$))`;
|
||||
@@ -2447,7 +2444,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function fail(message?: string, stackCrawlMark?: Function): void {
|
||||
export function fail(message?: string, stackCrawlMark?: Function): never {
|
||||
debugger;
|
||||
const e = new Error(message ? `Debug Failure. ${message}` : "Debug Failure.");
|
||||
if ((<any>Error).captureStackTrace) {
|
||||
@@ -2456,6 +2453,10 @@ namespace ts {
|
||||
throw e;
|
||||
}
|
||||
|
||||
export function assertNever(member: never, message?: string, stackCrawlMark?: Function): never {
|
||||
return fail(message || `Illegal value: ${member}`, stackCrawlMark || assertNever);
|
||||
}
|
||||
|
||||
export function getFunctionName(func: Function) {
|
||||
if (typeof func !== "function") {
|
||||
return "";
|
||||
@@ -2523,7 +2524,6 @@ namespace ts {
|
||||
* Return an exact match if possible, or a pattern match, or undefined.
|
||||
* (These are verified by verifyCompilerOptions to have 0 or 1 "*" characters.)
|
||||
*/
|
||||
/* @internal */
|
||||
export function matchPatternOrExact(patternStrings: ReadonlyArray<string>, candidate: string): string | Pattern | undefined {
|
||||
const patterns: Pattern[] = [];
|
||||
for (const patternString of patternStrings) {
|
||||
@@ -2540,7 +2540,6 @@ namespace ts {
|
||||
return findBestPatternMatch(patterns, _ => _, candidate);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function patternText({prefix, suffix}: Pattern): string {
|
||||
return `${prefix}*${suffix}`;
|
||||
}
|
||||
@@ -2549,14 +2548,12 @@ namespace ts {
|
||||
* Given that candidate matches pattern, returns the text matching the '*'.
|
||||
* E.g.: matchedText(tryParsePattern("foo*baz"), "foobarbaz") === "bar"
|
||||
*/
|
||||
/* @internal */
|
||||
export function matchedText(pattern: Pattern, candidate: string): string {
|
||||
Debug.assert(isPatternMatch(pattern, candidate));
|
||||
return candidate.substr(pattern.prefix.length, candidate.length - pattern.suffix.length);
|
||||
}
|
||||
|
||||
/** Return the object corresponding to the best pattern to match `candidate`. */
|
||||
/* @internal */
|
||||
export function findBestPatternMatch<T>(values: ReadonlyArray<T>, getPattern: (value: T) => Pattern, candidate: string): T | undefined {
|
||||
let matchedValue: T | undefined = undefined;
|
||||
// use length of prefix as betterness criteria
|
||||
@@ -2579,7 +2576,6 @@ namespace ts {
|
||||
endsWith(candidate, suffix);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function tryParsePattern(pattern: string): Pattern | undefined {
|
||||
// This should be verified outside of here and a proper error thrown.
|
||||
Debug.assert(hasZeroOrOneAsteriskCharacter(pattern));
|
||||
@@ -2628,4 +2624,6 @@ namespace ts {
|
||||
export function and<T>(f: (arg: T) => boolean, g: (arg: T) => boolean) {
|
||||
return (arg: T) => f(arg) && g(arg);
|
||||
}
|
||||
|
||||
export function assertTypeIsNever(_: never): void {}
|
||||
}
|
||||
|
||||
+65
-62
@@ -406,6 +406,14 @@ namespace ts {
|
||||
setWriter(/*output*/ undefined);
|
||||
}
|
||||
|
||||
// TODO: Should this just be `emit`?
|
||||
// See https://github.com/Microsoft/TypeScript/pull/18284#discussion_r137611034
|
||||
function emitIfPresent(node: Node | undefined) {
|
||||
if (node) {
|
||||
emit(node);
|
||||
}
|
||||
}
|
||||
|
||||
function emit(node: Node) {
|
||||
pipelineEmitWithNotification(EmitHint.Unspecified, node);
|
||||
}
|
||||
@@ -451,6 +459,7 @@ namespace ts {
|
||||
case EmitHint.SourceFile: return pipelineEmitSourceFile(node);
|
||||
case EmitHint.IdentifierName: return pipelineEmitIdentifierName(node);
|
||||
case EmitHint.Expression: return pipelineEmitExpression(node);
|
||||
case EmitHint.MappedTypeParameter: return emitMappedTypeParameter(cast(node, isTypeParameterDeclaration));
|
||||
case EmitHint.Unspecified: return pipelineEmitUnspecified(node);
|
||||
}
|
||||
}
|
||||
@@ -465,6 +474,12 @@ namespace ts {
|
||||
emitIdentifier(<Identifier>node);
|
||||
}
|
||||
|
||||
function emitMappedTypeParameter(node: TypeParameterDeclaration): void {
|
||||
emit(node.name);
|
||||
write(" in ");
|
||||
emit(node.constraint);
|
||||
}
|
||||
|
||||
function pipelineEmitUnspecified(node: Node): void {
|
||||
const kind = node.kind;
|
||||
|
||||
@@ -898,9 +913,9 @@ namespace ts {
|
||||
function emitParameter(node: ParameterDeclaration) {
|
||||
emitDecorators(node, node.decorators);
|
||||
emitModifiers(node, node.modifiers);
|
||||
writeIfPresent(node.dotDotDotToken, "...");
|
||||
emitIfPresent(node.dotDotDotToken);
|
||||
emit(node.name);
|
||||
writeIfPresent(node.questionToken, "?");
|
||||
emitIfPresent(node.questionToken);
|
||||
emitWithPrefix(": ", node.type);
|
||||
emitExpressionWithPrefix(" = ", node.initializer);
|
||||
}
|
||||
@@ -918,7 +933,7 @@ namespace ts {
|
||||
emitDecorators(node, node.decorators);
|
||||
emitModifiers(node, node.modifiers);
|
||||
emit(node.name);
|
||||
writeIfPresent(node.questionToken, "?");
|
||||
emitIfPresent(node.questionToken);
|
||||
emitWithPrefix(": ", node.type);
|
||||
write(";");
|
||||
}
|
||||
@@ -927,7 +942,7 @@ namespace ts {
|
||||
emitDecorators(node, node.decorators);
|
||||
emitModifiers(node, node.modifiers);
|
||||
emit(node.name);
|
||||
writeIfPresent(node.questionToken, "?");
|
||||
emitIfPresent(node.questionToken);
|
||||
emitWithPrefix(": ", node.type);
|
||||
emitExpressionWithPrefix(" = ", node.initializer);
|
||||
write(";");
|
||||
@@ -937,7 +952,7 @@ namespace ts {
|
||||
emitDecorators(node, node.decorators);
|
||||
emitModifiers(node, node.modifiers);
|
||||
emit(node.name);
|
||||
writeIfPresent(node.questionToken, "?");
|
||||
emitIfPresent(node.questionToken);
|
||||
emitTypeParameters(node, node.typeParameters);
|
||||
emitParameters(node, node.parameters);
|
||||
emitWithPrefix(": ", node.type);
|
||||
@@ -947,9 +962,9 @@ namespace ts {
|
||||
function emitMethodDeclaration(node: MethodDeclaration) {
|
||||
emitDecorators(node, node.decorators);
|
||||
emitModifiers(node, node.modifiers);
|
||||
writeIfPresent(node.asteriskToken, "*");
|
||||
emitIfPresent(node.asteriskToken);
|
||||
emit(node.name);
|
||||
writeIfPresent(node.questionToken, "?");
|
||||
emitIfPresent(node.questionToken);
|
||||
emitSignatureAndBody(node, emitSignatureHead);
|
||||
}
|
||||
|
||||
@@ -1035,10 +1050,8 @@ namespace ts {
|
||||
|
||||
function emitTypeLiteral(node: TypeLiteralNode) {
|
||||
write("{");
|
||||
// If the literal is empty, do not add spaces between braces.
|
||||
if (node.members.length > 0) {
|
||||
emitList(node, node.members, getEmitFlags(node) & EmitFlags.SingleLine ? ListFormat.SingleLineTypeLiteralMembers : ListFormat.MultiLineTypeLiteralMembers);
|
||||
}
|
||||
const flags = getEmitFlags(node) & EmitFlags.SingleLine ? ListFormat.SingleLineTypeLiteralMembers : ListFormat.MultiLineTypeLiteralMembers;
|
||||
emitList(node, node.members, flags | ListFormat.NoSpaceIfEmpty);
|
||||
write("}");
|
||||
}
|
||||
|
||||
@@ -1094,13 +1107,16 @@ namespace ts {
|
||||
writeLine();
|
||||
increaseIndent();
|
||||
}
|
||||
writeIfPresent(node.readonlyToken, "readonly ");
|
||||
if (node.readonlyToken) {
|
||||
emit(node.readonlyToken);
|
||||
write(" ");
|
||||
}
|
||||
|
||||
write("[");
|
||||
emit(node.typeParameter.name);
|
||||
write(" in ");
|
||||
emit(node.typeParameter.constraint);
|
||||
pipelineEmitWithNotification(EmitHint.MappedTypeParameter, node.typeParameter);
|
||||
write("]");
|
||||
writeIfPresent(node.questionToken, "?");
|
||||
|
||||
emitIfPresent(node.questionToken);
|
||||
write(": ");
|
||||
emit(node.type);
|
||||
write(";");
|
||||
@@ -1148,7 +1164,7 @@ namespace ts {
|
||||
|
||||
function emitBindingElement(node: BindingElement) {
|
||||
emitWithSuffix(node.propertyName, ": ");
|
||||
writeIfPresent(node.dotDotDotToken, "...");
|
||||
emitIfPresent(node.dotDotDotToken);
|
||||
emit(node.name);
|
||||
emitExpressionWithPrefix(" = ", node.initializer);
|
||||
}
|
||||
@@ -1159,33 +1175,22 @@ namespace ts {
|
||||
|
||||
function emitArrayLiteralExpression(node: ArrayLiteralExpression) {
|
||||
const elements = node.elements;
|
||||
if (elements.length === 0) {
|
||||
write("[]");
|
||||
}
|
||||
else {
|
||||
const preferNewLine = node.multiLine ? ListFormat.PreferNewLine : ListFormat.None;
|
||||
emitExpressionList(node, elements, ListFormat.ArrayLiteralExpressionElements | preferNewLine);
|
||||
}
|
||||
const preferNewLine = node.multiLine ? ListFormat.PreferNewLine : ListFormat.None;
|
||||
emitExpressionList(node, elements, ListFormat.ArrayLiteralExpressionElements | preferNewLine);
|
||||
}
|
||||
|
||||
function emitObjectLiteralExpression(node: ObjectLiteralExpression) {
|
||||
const properties = node.properties;
|
||||
if (properties.length === 0) {
|
||||
write("{}");
|
||||
const indentedFlag = getEmitFlags(node) & EmitFlags.Indented;
|
||||
if (indentedFlag) {
|
||||
increaseIndent();
|
||||
}
|
||||
else {
|
||||
const indentedFlag = getEmitFlags(node) & EmitFlags.Indented;
|
||||
if (indentedFlag) {
|
||||
increaseIndent();
|
||||
}
|
||||
|
||||
const preferNewLine = node.multiLine ? ListFormat.PreferNewLine : ListFormat.None;
|
||||
const allowTrailingComma = currentSourceFile.languageVersion >= ScriptTarget.ES5 ? ListFormat.AllowTrailingComma : ListFormat.None;
|
||||
emitList(node, properties, ListFormat.ObjectLiteralExpressionProperties | allowTrailingComma | preferNewLine);
|
||||
const preferNewLine = node.multiLine ? ListFormat.PreferNewLine : ListFormat.None;
|
||||
const allowTrailingComma = currentSourceFile.languageVersion >= ScriptTarget.ES5 ? ListFormat.AllowTrailingComma : ListFormat.None;
|
||||
emitList(node, node.properties, ListFormat.ObjectLiteralExpressionProperties | allowTrailingComma | preferNewLine);
|
||||
|
||||
if (indentedFlag) {
|
||||
decreaseIndent();
|
||||
}
|
||||
if (indentedFlag) {
|
||||
decreaseIndent();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1286,7 +1291,8 @@ namespace ts {
|
||||
emitTypeParameters(node, node.typeParameters);
|
||||
emitParametersForArrow(node, node.parameters);
|
||||
emitWithPrefix(": ", node.type);
|
||||
write(" =>");
|
||||
write(" ");
|
||||
emit(node.equalsGreaterThanToken);
|
||||
}
|
||||
|
||||
function emitDeleteExpression(node: DeleteExpression) {
|
||||
@@ -1364,13 +1370,13 @@ namespace ts {
|
||||
|
||||
emitExpression(node.condition);
|
||||
increaseIndentIf(indentBeforeQuestion, " ");
|
||||
write("?");
|
||||
emit(node.questionToken);
|
||||
increaseIndentIf(indentAfterQuestion, " ");
|
||||
emitExpression(node.whenTrue);
|
||||
decreaseIndentIf(indentBeforeQuestion, indentAfterQuestion);
|
||||
|
||||
increaseIndentIf(indentBeforeColon, " ");
|
||||
write(":");
|
||||
emit(node.colonToken);
|
||||
increaseIndentIf(indentAfterColon, " ");
|
||||
emitExpression(node.whenFalse);
|
||||
decreaseIndentIf(indentBeforeColon, indentAfterColon);
|
||||
@@ -1382,7 +1388,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
function emitYieldExpression(node: YieldExpression) {
|
||||
write(node.asteriskToken ? "yield*" : "yield");
|
||||
write("yield");
|
||||
emit(node.asteriskToken);
|
||||
emitExpressionWithPrefix(" ", node.expression);
|
||||
}
|
||||
|
||||
@@ -1662,7 +1669,9 @@ namespace ts {
|
||||
function emitFunctionDeclarationOrExpression(node: FunctionDeclaration | FunctionExpression) {
|
||||
emitDecorators(node, node.decorators);
|
||||
emitModifiers(node, node.modifiers);
|
||||
write(node.asteriskToken ? "function* " : "function ");
|
||||
write("function");
|
||||
emitIfPresent(node.asteriskToken);
|
||||
write(" ");
|
||||
emitIdentifierName(node.name);
|
||||
emitSignatureAndBody(node, emitSignatureHead);
|
||||
}
|
||||
@@ -2068,9 +2077,7 @@ namespace ts {
|
||||
function emitJsxExpression(node: JsxExpression) {
|
||||
if (node.expression) {
|
||||
write("{");
|
||||
if (node.dotDotDotToken) {
|
||||
write("...");
|
||||
}
|
||||
emitIfPresent(node.dotDotDotToken);
|
||||
emitExpression(node.expression);
|
||||
write("}");
|
||||
}
|
||||
@@ -2128,13 +2135,12 @@ namespace ts {
|
||||
emitTrailingCommentsOfPosition(statements.pos);
|
||||
}
|
||||
|
||||
let format = ListFormat.CaseOrDefaultClauseStatements;
|
||||
if (emitAsSingleStatement) {
|
||||
write(" ");
|
||||
emit(statements[0]);
|
||||
}
|
||||
else {
|
||||
emitList(parentNode, statements, ListFormat.CaseOrDefaultClauseStatements);
|
||||
format &= ~(ListFormat.MultiLine | ListFormat.Indented);
|
||||
}
|
||||
emitList(parentNode, statements, format);
|
||||
}
|
||||
|
||||
function emitHeritageClause(node: HeritageClause) {
|
||||
@@ -2384,7 +2390,7 @@ namespace ts {
|
||||
|
||||
function emitParametersForArrow(parentNode: FunctionTypeNode | ArrowFunction, parameters: NodeArray<ParameterDeclaration>) {
|
||||
if (canEmitSimpleArrowHead(parentNode, parameters)) {
|
||||
emit(parameters[0]);
|
||||
emitList(parentNode, parameters, ListFormat.Parameters & ~ListFormat.Parenthesis);
|
||||
}
|
||||
else {
|
||||
emitParameters(parentNode, parameters);
|
||||
@@ -2409,7 +2415,7 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
|
||||
const isEmpty = isUndefined || children.length === 0 || start >= children.length || count === 0;
|
||||
const isEmpty = isUndefined || start >= children.length || count === 0;
|
||||
if (isEmpty && format & ListFormat.OptionalIfEmpty) {
|
||||
return;
|
||||
}
|
||||
@@ -2427,7 +2433,7 @@ namespace ts {
|
||||
if (format & ListFormat.MultiLine) {
|
||||
writeLine();
|
||||
}
|
||||
else if (format & ListFormat.SpaceBetweenBraces) {
|
||||
else if (format & ListFormat.SpaceBetweenBraces && !(format & ListFormat.NoSpaceIfEmpty)) {
|
||||
write(" ");
|
||||
}
|
||||
}
|
||||
@@ -2519,7 +2525,7 @@ namespace ts {
|
||||
// 2
|
||||
// /* end of element 2 */
|
||||
// ];
|
||||
if (previousSibling && delimiter && previousSibling.end !== parentNode.end) {
|
||||
if (previousSibling && delimiter && previousSibling.end !== parentNode.end && !(getEmitFlags(previousSibling) & EmitFlags.NoTrailingComments)) {
|
||||
emitLeadingCommentsOfPosition(previousSibling.end);
|
||||
}
|
||||
|
||||
@@ -2568,12 +2574,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function writeIfPresent(node: Node, text: string) {
|
||||
if (node) {
|
||||
write(text);
|
||||
}
|
||||
}
|
||||
|
||||
function writeToken(token: SyntaxKind, pos: number, contextNode?: Node) {
|
||||
return onEmitSourceMapOfToken
|
||||
? onEmitSourceMapOfToken(contextNode, token, pos, writeTokenText)
|
||||
@@ -2584,7 +2584,7 @@ namespace ts {
|
||||
if (onBeforeEmitToken) {
|
||||
onBeforeEmitToken(node);
|
||||
}
|
||||
writeTokenText(node.kind);
|
||||
write(tokenToString(node.kind));
|
||||
if (onAfterEmitToken) {
|
||||
onAfterEmitToken(node);
|
||||
}
|
||||
@@ -3107,6 +3107,9 @@ namespace ts {
|
||||
NoTrailingNewLine = 1 << 16, // Do not emit a trailing NewLine for a MultiLine list.
|
||||
NoInterveningComments = 1 << 17, // Do not emit comments between each node
|
||||
|
||||
NoSpaceIfEmpty = 1 << 18, // If the literal is empty, do not add spaces between braces.
|
||||
SingleElement = 1 << 19,
|
||||
|
||||
// Precomputed Formats
|
||||
Modifiers = SingleLine | SpaceBetweenSiblings | NoInterveningComments,
|
||||
HeritageClauses = SingleLine | SpaceBetweenSiblings,
|
||||
@@ -3118,7 +3121,7 @@ namespace ts {
|
||||
IntersectionTypeConstituents = AmpersandDelimited | SpaceBetweenSiblings | SingleLine,
|
||||
ObjectBindingPatternElements = SingleLine | AllowTrailingComma | SpaceBetweenBraces | CommaDelimited | SpaceBetweenSiblings,
|
||||
ArrayBindingPatternElements = SingleLine | AllowTrailingComma | CommaDelimited | SpaceBetweenSiblings,
|
||||
ObjectLiteralExpressionProperties = PreserveLines | CommaDelimited | SpaceBetweenSiblings | SpaceBetweenBraces | Indented | Braces,
|
||||
ObjectLiteralExpressionProperties = PreserveLines | CommaDelimited | SpaceBetweenSiblings | SpaceBetweenBraces | Indented | Braces | NoSpaceIfEmpty,
|
||||
ArrayLiteralExpressionElements = PreserveLines | CommaDelimited | SpaceBetweenSiblings | AllowTrailingComma | Indented | SquareBrackets,
|
||||
CommaListElements = CommaDelimited | SpaceBetweenSiblings | SingleLine,
|
||||
CallExpressionArguments = CommaDelimited | SpaceBetweenSiblings | SingleLine | Parenthesis,
|
||||
|
||||
+55
-5
@@ -281,7 +281,7 @@ namespace ts {
|
||||
|| node.questionToken !== questionToken
|
||||
|| node.type !== type
|
||||
|| node.initializer !== initializer
|
||||
? updateNode(createParameter(decorators, modifiers, dotDotDotToken, name, node.questionToken, type, initializer), node)
|
||||
? updateNode(createParameter(decorators, modifiers, dotDotDotToken, name, questionToken, type, initializer), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
@@ -1016,19 +1016,49 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
/* @deprecated */ export function updateArrowFunction(
|
||||
node: ArrowFunction,
|
||||
modifiers: ReadonlyArray<Modifier> | undefined,
|
||||
typeParameters: ReadonlyArray<TypeParameterDeclaration> | undefined,
|
||||
parameters: ReadonlyArray<ParameterDeclaration>,
|
||||
type: TypeNode | undefined,
|
||||
body: ConciseBody): ArrowFunction;
|
||||
export function updateArrowFunction(
|
||||
node: ArrowFunction,
|
||||
modifiers: ReadonlyArray<Modifier> | undefined,
|
||||
typeParameters: ReadonlyArray<TypeParameterDeclaration> | undefined,
|
||||
parameters: ReadonlyArray<ParameterDeclaration>,
|
||||
type: TypeNode | undefined,
|
||||
body: ConciseBody) {
|
||||
equalsGreaterThanToken: Token<SyntaxKind.EqualsGreaterThanToken>,
|
||||
body: ConciseBody): ArrowFunction;
|
||||
export function updateArrowFunction(
|
||||
node: ArrowFunction,
|
||||
modifiers: ReadonlyArray<Modifier> | undefined,
|
||||
typeParameters: ReadonlyArray<TypeParameterDeclaration> | undefined,
|
||||
parameters: ReadonlyArray<ParameterDeclaration>,
|
||||
type: TypeNode | undefined,
|
||||
equalsGreaterThanTokenOrBody: Token<SyntaxKind.EqualsGreaterThanToken> | ConciseBody,
|
||||
bodyOrUndefined?: ConciseBody,
|
||||
): ArrowFunction {
|
||||
let equalsGreaterThanToken: Token<SyntaxKind.EqualsGreaterThanToken>;
|
||||
let body: ConciseBody;
|
||||
if (bodyOrUndefined === undefined) {
|
||||
equalsGreaterThanToken = node.equalsGreaterThanToken;
|
||||
body = cast(equalsGreaterThanTokenOrBody, isConciseBody);
|
||||
}
|
||||
else {
|
||||
equalsGreaterThanToken = cast(equalsGreaterThanTokenOrBody, (n): n is Token<SyntaxKind.EqualsGreaterThanToken> =>
|
||||
n.kind === SyntaxKind.EqualsGreaterThanToken);
|
||||
body = bodyOrUndefined;
|
||||
}
|
||||
|
||||
return node.modifiers !== modifiers
|
||||
|| node.typeParameters !== typeParameters
|
||||
|| node.parameters !== parameters
|
||||
|| node.type !== type
|
||||
|| node.equalsGreaterThanToken !== equalsGreaterThanToken
|
||||
|| node.body !== body
|
||||
? updateNode(createArrowFunction(modifiers, typeParameters, parameters, type, node.equalsGreaterThanToken, body), node)
|
||||
? updateNode(createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
@@ -1135,11 +1165,31 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateConditional(node: ConditionalExpression, condition: Expression, whenTrue: Expression, whenFalse: Expression) {
|
||||
/* @deprecated */ export function updateConditional(
|
||||
node: ConditionalExpression,
|
||||
condition: Expression,
|
||||
whenTrue: Expression,
|
||||
whenFalse: Expression): ConditionalExpression;
|
||||
export function updateConditional(
|
||||
node: ConditionalExpression,
|
||||
condition: Expression,
|
||||
questionToken: Token<SyntaxKind.QuestionToken>,
|
||||
whenTrue: Expression,
|
||||
colonToken: Token<SyntaxKind.ColonToken>,
|
||||
whenFalse: Expression): ConditionalExpression;
|
||||
export function updateConditional(node: ConditionalExpression, condition: Expression, ...args: any[]) {
|
||||
if (args.length === 2) {
|
||||
const [whenTrue, whenFalse] = args;
|
||||
return updateConditional(node, condition, node.questionToken, whenTrue, node.colonToken, whenFalse);
|
||||
}
|
||||
Debug.assert(args.length === 4);
|
||||
const [questionToken, whenTrue, colonToken, whenFalse] = args;
|
||||
return node.condition !== condition
|
||||
|| node.questionToken !== questionToken
|
||||
|| node.whenTrue !== whenTrue
|
||||
|| node.colonToken !== colonToken
|
||||
|| node.whenFalse !== whenFalse
|
||||
? updateNode(createConditional(condition, node.questionToken, whenTrue, node.colonToken, whenFalse), node)
|
||||
? updateNode(createConditional(condition, questionToken, whenTrue, colonToken, whenFalse), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,13 +51,17 @@ namespace ts {
|
||||
DtsOnly /** Only '.d.ts' */
|
||||
}
|
||||
|
||||
interface PathAndPackageId {
|
||||
readonly fileName: string;
|
||||
readonly packageId: PackageId;
|
||||
}
|
||||
/** Used with `Extensions.DtsOnly` to extract the path from TypeScript results. */
|
||||
function resolvedTypeScriptOnly(resolved: Resolved | undefined): string | undefined {
|
||||
function resolvedTypeScriptOnly(resolved: Resolved | undefined): PathAndPackageId | undefined {
|
||||
if (!resolved) {
|
||||
return undefined;
|
||||
}
|
||||
Debug.assert(extensionIsTypeScript(resolved.extension));
|
||||
return resolved.path;
|
||||
return { fileName: resolved.path, packageId: resolved.packageId };
|
||||
}
|
||||
|
||||
function createResolvedModuleWithFailedLookupLocations(resolved: Resolved | undefined, isExternalLibraryImport: boolean, failedLookupLocations: string[]): ResolvedModuleWithFailedLookupLocations {
|
||||
@@ -201,18 +205,18 @@ namespace ts {
|
||||
let resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective | undefined;
|
||||
if (resolved) {
|
||||
if (!options.preserveSymlinks) {
|
||||
resolved = realPath(resolved, host, traceEnabled);
|
||||
resolved = { ...resolved, fileName: realPath(resolved.fileName, host, traceEnabled) };
|
||||
}
|
||||
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolved, primary);
|
||||
trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolved.fileName, primary);
|
||||
}
|
||||
resolvedTypeReferenceDirective = { primary, resolvedFileName: resolved };
|
||||
resolvedTypeReferenceDirective = { primary, resolvedFileName: resolved.fileName, packageId: resolved.packageId };
|
||||
}
|
||||
|
||||
return { resolvedTypeReferenceDirective, failedLookupLocations };
|
||||
|
||||
function primaryLookup(): string | undefined {
|
||||
function primaryLookup(): PathAndPackageId | undefined {
|
||||
// Check primary library paths
|
||||
if (typeRoots && typeRoots.length) {
|
||||
if (traceEnabled) {
|
||||
@@ -237,8 +241,8 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function secondaryLookup(): string | undefined {
|
||||
let resolvedFile: string;
|
||||
function secondaryLookup(): PathAndPackageId | undefined {
|
||||
let resolvedFile: PathAndPackageId;
|
||||
const initialLocationForSecondaryLookup = containingFile && getDirectoryPath(containingFile);
|
||||
|
||||
if (initialLocationForSecondaryLookup !== undefined) {
|
||||
@@ -675,7 +679,7 @@ namespace ts {
|
||||
if (extension !== undefined) {
|
||||
const path = tryFile(candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state);
|
||||
if (path !== undefined) {
|
||||
return { path, extension, packageId: undefined };
|
||||
return noPackageId({ path, ext: extension });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -875,38 +879,49 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function loadNodeModuleFromDirectory(extensions: Extensions, candidate: string, failedLookupLocations: Push<string>, onlyRecordFailures: boolean, state: ModuleResolutionState, considerPackageJson = true): Resolved | undefined {
|
||||
const directoryExists = !onlyRecordFailures && directoryProbablyExists(candidate, state.host);
|
||||
function loadNodeModuleFromDirectory(extensions: Extensions, candidate: string, failedLookupLocations: Push<string>, onlyRecordFailures: boolean, state: ModuleResolutionState, considerPackageJson = true) {
|
||||
const { packageJsonContent, packageId } = considerPackageJson
|
||||
? getPackageJsonInfo(candidate, "", failedLookupLocations, onlyRecordFailures, state)
|
||||
: { packageJsonContent: undefined, packageId: undefined };
|
||||
return withPackageId(packageId, loadNodeModuleFromDirectoryWorker(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, packageJsonContent));
|
||||
}
|
||||
|
||||
let packageId: PackageId | undefined;
|
||||
|
||||
if (considerPackageJson) {
|
||||
const packageJsonPath = pathToPackageJson(candidate);
|
||||
if (directoryExists && state.host.fileExists(packageJsonPath)) {
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.Found_package_json_at_0, packageJsonPath);
|
||||
}
|
||||
const jsonContent = readJson(packageJsonPath, state.host);
|
||||
|
||||
if (typeof jsonContent.name === "string" && typeof jsonContent.version === "string") {
|
||||
packageId = { name: jsonContent.name, version: jsonContent.version };
|
||||
}
|
||||
|
||||
const fromPackageJson = loadModuleFromPackageJson(jsonContent, extensions, candidate, failedLookupLocations, state);
|
||||
if (fromPackageJson) {
|
||||
return withPackageId(packageId, fromPackageJson);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (directoryExists && state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.File_0_does_not_exist, packageJsonPath);
|
||||
}
|
||||
// record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results
|
||||
failedLookupLocations.push(packageJsonPath);
|
||||
}
|
||||
function loadNodeModuleFromDirectoryWorker(extensions: Extensions, candidate: string, failedLookupLocations: Push<string>, onlyRecordFailures: boolean, state: ModuleResolutionState, packageJsonContent: PackageJson | undefined): PathAndExtension | undefined {
|
||||
const fromPackageJson = packageJsonContent && loadModuleFromPackageJson(packageJsonContent, extensions, candidate, failedLookupLocations, state);
|
||||
if (fromPackageJson) {
|
||||
return fromPackageJson;
|
||||
}
|
||||
const directoryExists = !onlyRecordFailures && directoryProbablyExists(candidate, state.host);
|
||||
return loadModuleFromFile(extensions, combinePaths(candidate, "index"), failedLookupLocations, !directoryExists, state);
|
||||
}
|
||||
|
||||
return withPackageId(packageId, loadModuleFromFile(extensions, combinePaths(candidate, "index"), failedLookupLocations, !directoryExists, state));
|
||||
function getPackageJsonInfo(
|
||||
nodeModuleDirectory: string,
|
||||
subModuleName: string,
|
||||
failedLookupLocations: Push<string>,
|
||||
onlyRecordFailures: boolean,
|
||||
{ host, traceEnabled }: ModuleResolutionState,
|
||||
): { packageJsonContent: PackageJson | undefined, packageId: PackageId | undefined } {
|
||||
const directoryExists = !onlyRecordFailures && directoryProbablyExists(nodeModuleDirectory, host);
|
||||
const packageJsonPath = pathToPackageJson(nodeModuleDirectory);
|
||||
if (directoryExists && host.fileExists(packageJsonPath)) {
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Found_package_json_at_0, packageJsonPath);
|
||||
}
|
||||
const packageJsonContent = readJson(packageJsonPath, host);
|
||||
const packageId: PackageId = typeof packageJsonContent.name === "string" && typeof packageJsonContent.version === "string"
|
||||
? { name: packageJsonContent.name, subModuleName, version: packageJsonContent.version }
|
||||
: undefined;
|
||||
return { packageJsonContent, packageId };
|
||||
}
|
||||
else {
|
||||
if (directoryExists && traceEnabled) {
|
||||
trace(host, Diagnostics.File_0_does_not_exist, packageJsonPath);
|
||||
}
|
||||
// record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results
|
||||
failedLookupLocations.push(packageJsonPath);
|
||||
return { packageJsonContent: undefined, packageId: undefined };
|
||||
}
|
||||
}
|
||||
|
||||
function loadModuleFromPackageJson(jsonContent: PackageJson, extensions: Extensions, candidate: string, failedLookupLocations: Push<string>, state: ModuleResolutionState): PathAndExtension | undefined {
|
||||
@@ -961,10 +976,18 @@ namespace ts {
|
||||
}
|
||||
|
||||
function loadModuleFromNodeModulesFolder(extensions: Extensions, moduleName: string, nodeModulesFolder: string, nodeModulesFolderExists: boolean, failedLookupLocations: Push<string>, state: ModuleResolutionState): Resolved | undefined {
|
||||
const { top, rest } = getNameOfTopDirectory(moduleName);
|
||||
const packageRootPath = combinePaths(nodeModulesFolder, top);
|
||||
const { packageJsonContent, packageId } = getPackageJsonInfo(packageRootPath, rest, failedLookupLocations, !nodeModulesFolderExists, state);
|
||||
const candidate = normalizePath(combinePaths(nodeModulesFolder, moduleName));
|
||||
const pathAndExtension = loadModuleFromFile(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state) ||
|
||||
loadNodeModuleFromDirectoryWorker(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state, packageJsonContent);
|
||||
return withPackageId(packageId, pathAndExtension);
|
||||
}
|
||||
|
||||
return loadModuleFromFileNoPackageId(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state) ||
|
||||
loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state);
|
||||
function getNameOfTopDirectory(name: string): { top: string, rest: string } {
|
||||
const idx = name.indexOf(directorySeparator);
|
||||
return idx === -1 ? { top: name, rest: "" } : { top: name.slice(0, idx), rest: name.slice(idx + 1) };
|
||||
}
|
||||
|
||||
function loadModuleFromNodeModules(extensions: Extensions, moduleName: string, directory: string, failedLookupLocations: Push<string>, state: ModuleResolutionState, cache: NonRelativeModuleNameResolutionCache): SearchResult<Resolved> {
|
||||
|
||||
+70
-86
@@ -438,8 +438,10 @@ namespace ts {
|
||||
visitNode(cbNode, (<JSDocTypedefTag>node).typeExpression);
|
||||
}
|
||||
case SyntaxKind.JSDocTypeLiteral:
|
||||
for (const tag of (node as JSDocTypeLiteral).jsDocPropertyTags) {
|
||||
visitNode(cbNode, tag);
|
||||
if ((node as JSDocTypeLiteral).jsDocPropertyTags) {
|
||||
for (const tag of (node as JSDocTypeLiteral).jsDocPropertyTags) {
|
||||
visitNode(cbNode, tag);
|
||||
}
|
||||
}
|
||||
return;
|
||||
case SyntaxKind.PartiallyEmittedExpression:
|
||||
@@ -729,7 +731,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
|
||||
function addJSDocComment<T extends Node>(node: T): T {
|
||||
function addJSDocComment<T extends HasJSDoc>(node: T): T {
|
||||
const comments = getJSDocCommentRanges(node, sourceFile.text);
|
||||
if (comments) {
|
||||
for (const comment of comments) {
|
||||
@@ -768,7 +770,7 @@ namespace ts {
|
||||
const saveParent = parent;
|
||||
parent = n;
|
||||
forEachChild(n, visitNode);
|
||||
if (n.jsDoc) {
|
||||
if (hasJSDocNodes(n)) {
|
||||
for (const jsDoc of n.jsDoc) {
|
||||
jsDoc.parent = n;
|
||||
parent = jsDoc;
|
||||
@@ -940,10 +942,6 @@ namespace ts {
|
||||
return scanner.getStartPos();
|
||||
}
|
||||
|
||||
function getNodeEnd(): number {
|
||||
return scanner.getStartPos();
|
||||
}
|
||||
|
||||
// Use this function to access the current token instead of reading the currentToken
|
||||
// variable. Since function results aren't narrowed in control flow analysis, this ensures
|
||||
// that the type checker doesn't make wrong assumptions about the type of the current
|
||||
@@ -1135,13 +1133,14 @@ namespace ts {
|
||||
new TokenConstructor(kind, pos, pos);
|
||||
}
|
||||
|
||||
function createNodeArray<T extends Node>(elements?: T[], pos?: number): MutableNodeArray<T> {
|
||||
const array = <MutableNodeArray<T>>(elements || []);
|
||||
if (!(pos >= 0)) {
|
||||
pos = getNodePos();
|
||||
}
|
||||
function createNodeArray<T extends Node>(elements: T[], pos: number, end?: number): NodeArray<T> {
|
||||
// Since the element list of a node array is typically created by starting with an empty array and
|
||||
// repeatedly calling push(), the list may not have the optimal memory layout. We invoke slice() for
|
||||
// small arrays (1 to 4 elements) to give the VM a chance to allocate an optimal representation.
|
||||
const length = elements.length;
|
||||
const array = <MutableNodeArray<T>>(length >= 1 && length <= 4 ? elements.slice() : elements);
|
||||
array.pos = pos;
|
||||
array.end = pos;
|
||||
array.end = end === undefined ? scanner.getStartPos() : end;
|
||||
return array;
|
||||
}
|
||||
|
||||
@@ -1527,12 +1526,13 @@ namespace ts {
|
||||
function parseList<T extends Node>(kind: ParsingContext, parseElement: () => T): NodeArray<T> {
|
||||
const saveParsingContext = parsingContext;
|
||||
parsingContext |= 1 << kind;
|
||||
const result = createNodeArray<T>();
|
||||
const list = [];
|
||||
const listPos = getNodePos();
|
||||
|
||||
while (!isListTerminator(kind)) {
|
||||
if (isListElement(kind, /*inErrorRecovery*/ false)) {
|
||||
const element = parseListElement(kind, parseElement);
|
||||
result.push(element);
|
||||
list.push(element);
|
||||
|
||||
continue;
|
||||
}
|
||||
@@ -1542,9 +1542,8 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
result.end = getNodeEnd();
|
||||
parsingContext = saveParsingContext;
|
||||
return result;
|
||||
return createNodeArray(list, listPos);
|
||||
}
|
||||
|
||||
function parseListElement<T extends Node>(parsingContext: ParsingContext, parseElement: () => T): T {
|
||||
@@ -1874,13 +1873,14 @@ namespace ts {
|
||||
function parseDelimitedList<T extends Node>(kind: ParsingContext, parseElement: () => T, considerSemicolonAsDelimiter?: boolean): NodeArray<T> {
|
||||
const saveParsingContext = parsingContext;
|
||||
parsingContext |= 1 << kind;
|
||||
const result = createNodeArray<T>();
|
||||
const list = [];
|
||||
const listPos = getNodePos();
|
||||
|
||||
let commaStart = -1; // Meaning the previous token was not a comma
|
||||
while (true) {
|
||||
if (isListElement(kind, /*inErrorRecovery*/ false)) {
|
||||
const startPos = scanner.getStartPos();
|
||||
result.push(parseListElement(kind, parseElement));
|
||||
list.push(parseListElement(kind, parseElement));
|
||||
commaStart = scanner.getTokenPos();
|
||||
|
||||
if (parseOptional(SyntaxKind.CommaToken)) {
|
||||
@@ -1924,6 +1924,8 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
parsingContext = saveParsingContext;
|
||||
const result = createNodeArray(list, listPos);
|
||||
// Recording the trailing comma is deliberately done after the previous
|
||||
// loop, and not just if we see a list terminator. This is because the list
|
||||
// may have ended incorrectly, but it is still important to know if there
|
||||
@@ -1933,14 +1935,11 @@ namespace ts {
|
||||
// Always preserve a trailing comma by marking it on the NodeArray
|
||||
result.hasTrailingComma = true;
|
||||
}
|
||||
|
||||
result.end = getNodeEnd();
|
||||
parsingContext = saveParsingContext;
|
||||
return result;
|
||||
}
|
||||
|
||||
function createMissingList<T extends Node>(): NodeArray<T> {
|
||||
return createNodeArray<T>();
|
||||
return createNodeArray<T>([], getNodePos());
|
||||
}
|
||||
|
||||
function parseBracketedList<T extends Node>(kind: ParsingContext, parseElement: () => T, open: SyntaxKind, close: SyntaxKind): NodeArray<T> {
|
||||
@@ -2015,15 +2014,15 @@ namespace ts {
|
||||
template.head = parseTemplateHead();
|
||||
Debug.assert(template.head.kind === SyntaxKind.TemplateHead, "Template head has wrong token kind");
|
||||
|
||||
const templateSpans = createNodeArray<TemplateSpan>();
|
||||
const list = [];
|
||||
const listPos = getNodePos();
|
||||
|
||||
do {
|
||||
templateSpans.push(parseTemplateSpan());
|
||||
list.push(parseTemplateSpan());
|
||||
}
|
||||
while (lastOrUndefined(templateSpans).literal.kind === SyntaxKind.TemplateMiddle);
|
||||
while (lastOrUndefined(list).literal.kind === SyntaxKind.TemplateMiddle);
|
||||
|
||||
templateSpans.end = getNodeEnd();
|
||||
template.templateSpans = templateSpans;
|
||||
template.templateSpans = createNodeArray(list, listPos);
|
||||
|
||||
return finishNode(template);
|
||||
}
|
||||
@@ -2158,7 +2157,7 @@ namespace ts {
|
||||
const result = <JSDocFunctionType>createNode(SyntaxKind.JSDocFunctionType);
|
||||
nextToken();
|
||||
fillSignature(SyntaxKind.ColonToken, SignatureFlags.Type | SignatureFlags.JSDoc, result);
|
||||
return finishNode(result);
|
||||
return addJSDocComment(finishNode(result));
|
||||
}
|
||||
const node = <TypeReferenceNode>createNode(SyntaxKind.TypeReference);
|
||||
node.typeName = parseIdentifierName();
|
||||
@@ -2237,7 +2236,8 @@ namespace ts {
|
||||
return token() === SyntaxKind.DotDotDotToken ||
|
||||
isIdentifierOrPattern() ||
|
||||
isModifierKind(token()) ||
|
||||
token() === SyntaxKind.AtToken || isStartOfType();
|
||||
token() === SyntaxKind.AtToken ||
|
||||
isStartOfType(/*inStartOfParameter*/ true);
|
||||
}
|
||||
|
||||
function parseParameter(): ParameterDeclaration {
|
||||
@@ -2365,7 +2365,7 @@ namespace ts {
|
||||
parseSemicolon();
|
||||
}
|
||||
|
||||
function parseSignatureMember(kind: SyntaxKind): CallSignatureDeclaration | ConstructSignatureDeclaration {
|
||||
function parseSignatureMember(kind: SyntaxKind.CallSignature | SyntaxKind.ConstructSignature): CallSignatureDeclaration | ConstructSignatureDeclaration {
|
||||
const node = <CallSignatureDeclaration | ConstructSignatureDeclaration>createNode(kind);
|
||||
if (kind === SyntaxKind.ConstructSignature) {
|
||||
parseExpected(SyntaxKind.NewKeyword);
|
||||
@@ -2445,7 +2445,7 @@ namespace ts {
|
||||
node.parameters = parseBracketedList(ParsingContext.Parameters, parseParameter, SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken);
|
||||
node.type = parseTypeAnnotation();
|
||||
parseTypeMemberSemicolon();
|
||||
return finishNode(node);
|
||||
return addJSDocComment(finishNode(node));
|
||||
}
|
||||
|
||||
function parsePropertyOrMethodSignature(fullStart: number, modifiers: NodeArray<Modifier>): PropertySignature | MethodSignature {
|
||||
@@ -2605,7 +2605,7 @@ namespace ts {
|
||||
parseExpected(SyntaxKind.NewKeyword);
|
||||
}
|
||||
fillSignature(SyntaxKind.EqualsGreaterThanToken, SignatureFlags.Type, node);
|
||||
return finishNode(node);
|
||||
return addJSDocComment(finishNode(node));
|
||||
}
|
||||
|
||||
function parseKeywordAndNoDot(): TypeNode | undefined {
|
||||
@@ -2698,7 +2698,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function isStartOfType(): boolean {
|
||||
function isStartOfType(inStartOfParameter?: boolean): boolean {
|
||||
switch (token()) {
|
||||
case SyntaxKind.AnyKeyword:
|
||||
case SyntaxKind.StringKeyword:
|
||||
@@ -2728,11 +2728,11 @@ namespace ts {
|
||||
case SyntaxKind.DotDotDotToken:
|
||||
return true;
|
||||
case SyntaxKind.MinusToken:
|
||||
return lookAhead(nextTokenIsNumericLiteral);
|
||||
return !inStartOfParameter && lookAhead(nextTokenIsNumericLiteral);
|
||||
case SyntaxKind.OpenParenToken:
|
||||
// Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier,
|
||||
// or something that starts a type. We don't want to consider things like '(1)' a type.
|
||||
return lookAhead(isStartOfParenthesizedOrFunctionType);
|
||||
return !inStartOfParameter && lookAhead(isStartOfParenthesizedOrFunctionType);
|
||||
default:
|
||||
return isIdentifier();
|
||||
}
|
||||
@@ -2806,13 +2806,12 @@ namespace ts {
|
||||
parseOptional(operator);
|
||||
let type = parseConstituentType();
|
||||
if (token() === operator) {
|
||||
const types = createNodeArray<TypeNode>([type], type.pos);
|
||||
const types = [type];
|
||||
while (parseOptional(operator)) {
|
||||
types.push(parseConstituentType());
|
||||
}
|
||||
types.end = getNodeEnd();
|
||||
const node = <UnionOrIntersectionTypeNode>createNode(kind, type.pos);
|
||||
node.types = types;
|
||||
node.types = createNodeArray(types, type.pos);
|
||||
type = finishNode(node);
|
||||
}
|
||||
return type;
|
||||
@@ -3178,8 +3177,7 @@ namespace ts {
|
||||
parameter.name = identifier;
|
||||
finishNode(parameter);
|
||||
|
||||
node.parameters = createNodeArray<ParameterDeclaration>([parameter], parameter.pos);
|
||||
node.parameters.end = parameter.end;
|
||||
node.parameters = createNodeArray<ParameterDeclaration>([parameter], parameter.pos, parameter.end);
|
||||
|
||||
node.equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, "=>");
|
||||
node.body = parseArrowFunctionExpressionBody(/*isAsync*/ !!asyncModifier);
|
||||
@@ -4029,7 +4027,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
function parseJsxChildren(openingTagName: LeftHandSideExpression): NodeArray<JsxChild> {
|
||||
const result = createNodeArray<JsxChild>();
|
||||
const list = [];
|
||||
const listPos = getNodePos();
|
||||
const saveParsingContext = parsingContext;
|
||||
parsingContext |= 1 << ParsingContext.JsxChildren;
|
||||
|
||||
@@ -4050,15 +4049,13 @@ namespace ts {
|
||||
}
|
||||
const child = parseJsxChild();
|
||||
if (child) {
|
||||
result.push(child);
|
||||
list.push(child);
|
||||
}
|
||||
}
|
||||
|
||||
result.end = scanner.getTokenPos();
|
||||
|
||||
parsingContext = saveParsingContext;
|
||||
|
||||
return result;
|
||||
return createNodeArray(list, listPos);
|
||||
}
|
||||
|
||||
function parseJsxAttributes(): JsxAttributes {
|
||||
@@ -5451,27 +5448,19 @@ namespace ts {
|
||||
}
|
||||
|
||||
function parseDecorators(): NodeArray<Decorator> {
|
||||
let decorators: NodeArray<Decorator> & Decorator[];
|
||||
let list: Decorator[];
|
||||
const listPos = getNodePos();
|
||||
while (true) {
|
||||
const decoratorStart = getNodePos();
|
||||
if (!parseOptional(SyntaxKind.AtToken)) {
|
||||
break;
|
||||
}
|
||||
|
||||
const decorator = <Decorator>createNode(SyntaxKind.Decorator, decoratorStart);
|
||||
decorator.expression = doInDecoratorContext(parseLeftHandSideExpressionOrHigher);
|
||||
finishNode(decorator);
|
||||
if (!decorators) {
|
||||
decorators = createNodeArray<Decorator>([decorator], decoratorStart);
|
||||
}
|
||||
else {
|
||||
decorators.push(decorator);
|
||||
}
|
||||
(list || (list = [])).push(decorator);
|
||||
}
|
||||
if (decorators) {
|
||||
decorators.end = getNodeEnd();
|
||||
}
|
||||
return decorators;
|
||||
return list && createNodeArray(list, listPos);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -5482,7 +5471,8 @@ namespace ts {
|
||||
* In such situations, 'permitInvalidConstAsModifier' should be set to true.
|
||||
*/
|
||||
function parseModifiers(permitInvalidConstAsModifier?: boolean): NodeArray<Modifier> | undefined {
|
||||
let modifiers: MutableNodeArray<Modifier> | undefined;
|
||||
let list: Modifier[];
|
||||
const listPos = getNodePos();
|
||||
while (true) {
|
||||
const modifierStart = scanner.getStartPos();
|
||||
const modifierKind = token();
|
||||
@@ -5501,17 +5491,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
const modifier = finishNode(<Modifier>createNode(modifierKind, modifierStart));
|
||||
if (!modifiers) {
|
||||
modifiers = createNodeArray<Modifier>([modifier], modifierStart);
|
||||
}
|
||||
else {
|
||||
modifiers.push(modifier);
|
||||
}
|
||||
(list || (list = [])).push(modifier);
|
||||
}
|
||||
if (modifiers) {
|
||||
modifiers.end = scanner.getStartPos();
|
||||
}
|
||||
return modifiers;
|
||||
return list && createNodeArray(list, listPos);
|
||||
}
|
||||
|
||||
function parseModifiersForArrowFunction(): NodeArray<Modifier> {
|
||||
@@ -5522,9 +5504,7 @@ namespace ts {
|
||||
nextToken();
|
||||
const modifier = finishNode(<Modifier>createNode(modifierKind, modifierStart));
|
||||
modifiers = createNodeArray<Modifier>([modifier], modifierStart);
|
||||
modifiers.end = scanner.getStartPos();
|
||||
}
|
||||
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
@@ -6182,7 +6162,7 @@ namespace ts {
|
||||
return jsDoc ? { jsDoc, diagnostics } : undefined;
|
||||
}
|
||||
|
||||
export function parseJSDocComment(parent: Node, start: number, length: number): JSDoc {
|
||||
export function parseJSDocComment(parent: HasJSDoc, start: number, length: number): JSDoc {
|
||||
const saveToken = currentToken;
|
||||
const saveParseDiagnosticsLength = parseDiagnostics.length;
|
||||
const saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode;
|
||||
@@ -6226,7 +6206,9 @@ namespace ts {
|
||||
Debug.assert(start <= end);
|
||||
Debug.assert(end <= content.length);
|
||||
|
||||
let tags: MutableNodeArray<JSDocTag>;
|
||||
let tags: JSDocTag[];
|
||||
let tagsPos: number;
|
||||
let tagsEnd: number;
|
||||
const comments: string[] = [];
|
||||
let result: JSDoc;
|
||||
|
||||
@@ -6359,7 +6341,7 @@ namespace ts {
|
||||
|
||||
function createJSDocComment(): JSDoc {
|
||||
const result = <JSDoc>createNode(SyntaxKind.JSDocComment, start);
|
||||
result.tags = tags;
|
||||
result.tags = tags && createNodeArray(tags, tagsPos, tagsEnd);
|
||||
result.comment = comments.length ? comments.join("") : undefined;
|
||||
return finishNode(result, end);
|
||||
}
|
||||
@@ -6499,12 +6481,13 @@ namespace ts {
|
||||
tag.comment = comments.join("");
|
||||
|
||||
if (!tags) {
|
||||
tags = createNodeArray([tag], tag.pos);
|
||||
tags = [tag];
|
||||
tagsPos = tag.pos;
|
||||
}
|
||||
else {
|
||||
tags.push(tag);
|
||||
}
|
||||
tags.end = tag.end;
|
||||
tagsEnd = tag.end;
|
||||
}
|
||||
|
||||
function tryParseTypeExpression(): JSDocTypeExpression | undefined {
|
||||
@@ -6671,19 +6654,18 @@ namespace ts {
|
||||
if (!typeExpression || isObjectOrObjectArrayTypeReference(typeExpression.type)) {
|
||||
let child: JSDocTypeTag | JSDocPropertyTag | false;
|
||||
let jsdocTypeLiteral: JSDocTypeLiteral;
|
||||
let alreadyHasTypeTag = false;
|
||||
let childTypeTag: JSDocTypeTag;
|
||||
const start = scanner.getStartPos();
|
||||
while (child = tryParse(() => parseChildParameterOrPropertyTag(PropertyLikeParse.Property))) {
|
||||
if (!jsdocTypeLiteral) {
|
||||
jsdocTypeLiteral = <JSDocTypeLiteral>createNode(SyntaxKind.JSDocTypeLiteral, start);
|
||||
}
|
||||
if (child.kind === SyntaxKind.JSDocTypeTag) {
|
||||
if (alreadyHasTypeTag) {
|
||||
if (childTypeTag) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
jsdocTypeLiteral.jsDocTypeTag = child;
|
||||
alreadyHasTypeTag = true;
|
||||
childTypeTag = child;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -6697,7 +6679,9 @@ namespace ts {
|
||||
if (typeExpression && typeExpression.type.kind === SyntaxKind.ArrayType) {
|
||||
jsdocTypeLiteral.isArrayType = true;
|
||||
}
|
||||
typedefTag.typeExpression = finishNode(jsdocTypeLiteral);
|
||||
typedefTag.typeExpression = childTypeTag && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type) ?
|
||||
childTypeTag.typeExpression :
|
||||
finishNode(jsdocTypeLiteral);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6804,7 +6788,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Type parameter list looks like '@template T,U,V'
|
||||
const typeParameters = createNodeArray<TypeParameterDeclaration>();
|
||||
const typeParameters = [];
|
||||
const typeParametersPos = getNodePos();
|
||||
|
||||
while (true) {
|
||||
const name = parseJSDocIdentifierName();
|
||||
@@ -6832,9 +6817,8 @@ namespace ts {
|
||||
const result = <JSDocTemplateTag>createNode(SyntaxKind.JSDocTemplateTag, atToken.pos);
|
||||
result.atToken = atToken;
|
||||
result.tagName = tagName;
|
||||
result.typeParameters = typeParameters;
|
||||
result.typeParameters = createNodeArray(typeParameters, typeParametersPos);
|
||||
finishNode(result);
|
||||
typeParameters.end = result.end;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -6997,7 +6981,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
forEachChild(node, visitNode, visitArray);
|
||||
if (node.jsDoc) {
|
||||
if (hasJSDocNodes(node)) {
|
||||
for (const jsDocComment of node.jsDoc) {
|
||||
forEachChild(jsDocComment, visitNode, visitArray);
|
||||
}
|
||||
|
||||
+16
-16
@@ -245,7 +245,7 @@ namespace ts {
|
||||
const redForegroundEscapeSequence = "\u001b[91m";
|
||||
const yellowForegroundEscapeSequence = "\u001b[93m";
|
||||
const blueForegroundEscapeSequence = "\u001b[93m";
|
||||
const gutterStyleSequence = "\u001b[100;30m";
|
||||
const gutterStyleSequence = "\u001b[30;47m";
|
||||
const gutterSeparator = " ";
|
||||
const resetEscapeSequence = "\u001b[0m";
|
||||
const ellipsis = "...";
|
||||
@@ -268,7 +268,7 @@ namespace ts {
|
||||
return s;
|
||||
}
|
||||
|
||||
export function formatDiagnosticsWithColorAndContext(diagnostics: Diagnostic[], host: FormatDiagnosticsHost): string {
|
||||
export function formatDiagnosticsWithColorAndContext(diagnostics: ReadonlyArray<Diagnostic>, host: FormatDiagnosticsHost): string {
|
||||
let output = "";
|
||||
for (const diagnostic of diagnostics) {
|
||||
if (diagnostic.file) {
|
||||
@@ -284,12 +284,12 @@ namespace ts {
|
||||
gutterWidth = Math.max(ellipsis.length, gutterWidth);
|
||||
}
|
||||
|
||||
output += sys.newLine;
|
||||
output += host.getNewLine();
|
||||
for (let i = firstLine; i <= lastLine; i++) {
|
||||
// If the error spans over 5 lines, we'll only show the first 2 and last 2 lines,
|
||||
// so we'll skip ahead to the second-to-last line.
|
||||
if (hasMoreThanFiveLines && firstLine + 1 < i && i < lastLine - 1) {
|
||||
output += formatAndReset(padLeft(ellipsis, gutterWidth), gutterStyleSequence) + gutterSeparator + sys.newLine;
|
||||
output += formatAndReset(padLeft(ellipsis, gutterWidth), gutterStyleSequence) + gutterSeparator + host.getNewLine();
|
||||
i = lastLine - 1;
|
||||
}
|
||||
|
||||
@@ -301,7 +301,7 @@ namespace ts {
|
||||
|
||||
// Output the gutter and the actual contents of the line.
|
||||
output += formatAndReset(padLeft(i + 1 + "", gutterWidth), gutterStyleSequence) + gutterSeparator;
|
||||
output += lineContent + sys.newLine;
|
||||
output += lineContent + host.getNewLine();
|
||||
|
||||
// Output the gutter and the error span for the line using tildes.
|
||||
output += formatAndReset(padLeft("", gutterWidth), gutterStyleSequence) + gutterSeparator;
|
||||
@@ -323,17 +323,17 @@ namespace ts {
|
||||
}
|
||||
output += resetEscapeSequence;
|
||||
|
||||
output += sys.newLine;
|
||||
output += host.getNewLine();
|
||||
}
|
||||
|
||||
output += sys.newLine;
|
||||
output += host.getNewLine();
|
||||
output += `${ relativeFileName }(${ firstLine + 1 },${ firstLineChar + 1 }): `;
|
||||
}
|
||||
|
||||
const categoryColor = getCategoryFormat(diagnostic.category);
|
||||
const category = DiagnosticCategory[diagnostic.category].toLowerCase();
|
||||
output += `${ formatAndReset(category, categoryColor) } TS${ diagnostic.code }: ${ flattenDiagnosticMessageText(diagnostic.messageText, sys.newLine) }`;
|
||||
output += sys.newLine;
|
||||
output += `${ formatAndReset(category, categoryColor) } TS${ diagnostic.code }: ${ flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine()) }`;
|
||||
output += host.getNewLine();
|
||||
}
|
||||
return output;
|
||||
}
|
||||
@@ -1427,7 +1427,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function processRootFile(fileName: string, isDefaultLib: boolean) {
|
||||
processSourceFile(normalizePath(fileName), isDefaultLib);
|
||||
processSourceFile(normalizePath(fileName), isDefaultLib, /*packageId*/ undefined);
|
||||
}
|
||||
|
||||
function fileReferenceIsEqualTo(a: FileReference, b: FileReference): boolean {
|
||||
@@ -1591,9 +1591,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
/** This has side effects through `findSourceFile`. */
|
||||
function processSourceFile(fileName: string, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number): void {
|
||||
function processSourceFile(fileName: string, isDefaultLib: boolean, packageId: PackageId | undefined, refFile?: SourceFile, refPos?: number, refEnd?: number): void {
|
||||
getSourceFileFromReferenceWorker(fileName,
|
||||
fileName => findSourceFile(fileName, toPath(fileName), isDefaultLib, refFile, refPos, refEnd, /*packageId*/ undefined),
|
||||
fileName => findSourceFile(fileName, toPath(fileName), isDefaultLib, refFile, refPos, refEnd, packageId),
|
||||
(diagnostic, ...args) => {
|
||||
fileProcessingDiagnostics.add(refFile !== undefined && refEnd !== undefined && refPos !== undefined
|
||||
? createFileDiagnostic(refFile, refPos, refEnd - refPos, diagnostic, ...args)
|
||||
@@ -1675,7 +1675,7 @@ namespace ts {
|
||||
});
|
||||
|
||||
if (packageId) {
|
||||
const packageIdKey = `${packageId.name}@${packageId.version}`;
|
||||
const packageIdKey = `${packageId.name}/${packageId.subModuleName}@${packageId.version}`;
|
||||
const fileFromPackageId = packageIdToSourceFile.get(packageIdKey);
|
||||
if (fileFromPackageId) {
|
||||
// Some other SourceFile already exists with this package name and version.
|
||||
@@ -1735,7 +1735,7 @@ namespace ts {
|
||||
function processReferencedFiles(file: SourceFile, isDefaultLib: boolean) {
|
||||
forEach(file.referencedFiles, ref => {
|
||||
const referencedFileName = resolveTripleslashReference(ref.fileName, file.fileName);
|
||||
processSourceFile(referencedFileName, isDefaultLib, file, ref.pos, ref.end);
|
||||
processSourceFile(referencedFileName, isDefaultLib, /*packageId*/ undefined, file, ref.pos, ref.end);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1766,7 +1766,7 @@ namespace ts {
|
||||
if (resolvedTypeReferenceDirective) {
|
||||
if (resolvedTypeReferenceDirective.primary) {
|
||||
// resolved from the primary path
|
||||
processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, refFile, refPos, refEnd);
|
||||
processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, resolvedTypeReferenceDirective.packageId, refFile, refPos, refEnd);
|
||||
}
|
||||
else {
|
||||
// If we already resolved to this file, it must have been a secondary reference. Check file contents
|
||||
@@ -1789,7 +1789,7 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
// First resolution of this library
|
||||
processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, refFile, refPos, refEnd);
|
||||
processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, resolvedTypeReferenceDirective.packageId, refFile, refPos, refEnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,7 +337,7 @@ namespace ts {
|
||||
Debug.assert(res < lineStarts[line + 1]);
|
||||
}
|
||||
else if (debugText !== undefined) {
|
||||
Debug.assert(res < debugText.length);
|
||||
Debug.assert(res <= debugText.length); // Allow single character overflow for trailing newline
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -197,9 +197,10 @@ namespace ts {
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
node.equalsGreaterThanToken,
|
||||
getFunctionFlags(node) & FunctionFlags.Async
|
||||
? transformAsyncFunctionBody(node)
|
||||
: visitFunctionBody(node.body, visitor, context)
|
||||
: visitFunctionBody(node.body, visitor, context),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -595,7 +595,8 @@ namespace ts {
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
transformFunctionBody(node)
|
||||
node.equalsGreaterThanToken,
|
||||
transformFunctionBody(node),
|
||||
);
|
||||
enclosingFunctionFlags = savedEnclosingFunctionFlags;
|
||||
return updated;
|
||||
|
||||
@@ -1132,7 +1132,8 @@ namespace ts {
|
||||
*/
|
||||
function createExportExpression(name: Identifier | StringLiteral, value: Expression) {
|
||||
const exportName = isIdentifier(name) ? createLiteral(name) : name;
|
||||
return createCall(exportFunction, /*typeArguments*/ undefined, [exportName, value]);
|
||||
setEmitFlags(value, getEmitFlags(value) | EmitFlags.NoComments);
|
||||
return setCommentRange(createCall(exportFunction, /*typeArguments*/ undefined, [exportName, value]), value);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -208,6 +208,24 @@ namespace ts {
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function sourceElementVisitorWorker(node: Node): VisitResult<Node> {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
case SyntaxKind.ExportAssignment:
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
return visitEllidableStatement(<ImportDeclaration | ImportEqualsDeclaration | ExportAssignment | ExportDeclaration>node);
|
||||
default:
|
||||
return visitorWorker(node);
|
||||
}
|
||||
}
|
||||
|
||||
function visitEllidableStatement(node: ImportDeclaration | ImportEqualsDeclaration | ExportAssignment | ExportDeclaration): VisitResult<Node> {
|
||||
const parsed = getParseTreeNode(node);
|
||||
if (parsed !== node) {
|
||||
// If the node has been transformed by a `before` transformer, perform no ellision on it
|
||||
// As the type information we would attempt to lookup to perform ellision is potentially unavailable for the synthesized nodes
|
||||
return node;
|
||||
}
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
return visitImportDeclaration(<ImportDeclaration>node);
|
||||
@@ -218,7 +236,7 @@ namespace ts {
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
return visitExportDeclaration(<ExportDeclaration>node);
|
||||
default:
|
||||
return visitorWorker(node);
|
||||
Debug.fail("Unhandled ellided statement");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2291,7 +2309,8 @@ namespace ts {
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
visitFunctionBody(node.body, visitor, context)
|
||||
node.equalsGreaterThanToken,
|
||||
visitFunctionBody(node.body, visitor, context),
|
||||
);
|
||||
return updated;
|
||||
}
|
||||
|
||||
+114
-63
@@ -516,8 +516,6 @@ namespace ts {
|
||||
parent?: Node; // Parent node (initialized by binding)
|
||||
/* @internal */ original?: Node; // The original node if this is an updated node.
|
||||
/* @internal */ startsOnNewLine?: boolean; // Whether a synthesized node should start on a new line (used by transforms).
|
||||
/* @internal */ jsDoc?: JSDoc[]; // JSDoc that directly precedes this node
|
||||
/* @internal */ jsDocCache?: ReadonlyArray<JSDocTag>; // Cache for getJSDocTags
|
||||
/* @internal */ symbol?: Symbol; // Symbol declared by node (initialized by binding)
|
||||
/* @internal */ locals?: SymbolTable; // Locals associated with node (initialized by binding)
|
||||
/* @internal */ nextContainer?: Node; // Next container in declaration order (initialized by binding)
|
||||
@@ -528,6 +526,44 @@ namespace ts {
|
||||
/* @internal */ contextualMapper?: TypeMapper; // Mapper for contextual type
|
||||
}
|
||||
|
||||
export interface JSDocContainer {
|
||||
/* @internal */ jsDoc?: JSDoc[]; // JSDoc that directly precedes this node
|
||||
/* @internal */ jsDocCache?: ReadonlyArray<JSDocTag>; // Cache for getJSDocTags
|
||||
}
|
||||
|
||||
export type HasJSDoc =
|
||||
| ParameterDeclaration
|
||||
| CallSignatureDeclaration
|
||||
| ConstructSignatureDeclaration
|
||||
| MethodSignature
|
||||
| PropertySignature
|
||||
| ArrowFunction
|
||||
| ParenthesizedExpression
|
||||
| SpreadAssignment
|
||||
| ShorthandPropertyAssignment
|
||||
| PropertyAssignment
|
||||
| FunctionExpression
|
||||
| LabeledStatement
|
||||
| ExpressionStatement
|
||||
| VariableStatement
|
||||
| FunctionDeclaration
|
||||
| ConstructorDeclaration
|
||||
| MethodDeclaration
|
||||
| PropertyDeclaration
|
||||
| AccessorDeclaration
|
||||
| ClassLikeDeclaration
|
||||
| InterfaceDeclaration
|
||||
| TypeAliasDeclaration
|
||||
| EnumMember
|
||||
| EnumDeclaration
|
||||
| ModuleDeclaration
|
||||
| ImportEqualsDeclaration
|
||||
| IndexSignatureDeclaration
|
||||
| FunctionTypeNode
|
||||
| ConstructorTypeNode
|
||||
| JSDocFunctionType
|
||||
| EndOfFileToken;
|
||||
|
||||
/* @internal */
|
||||
export type MutableNodeArray<T extends Node> = NodeArray<T> & T[];
|
||||
|
||||
@@ -546,7 +582,7 @@ namespace ts {
|
||||
export type EqualsToken = Token<SyntaxKind.EqualsToken>;
|
||||
export type AsteriskToken = Token<SyntaxKind.AsteriskToken>;
|
||||
export type EqualsGreaterThanToken = Token<SyntaxKind.EqualsGreaterThanToken>;
|
||||
export type EndOfFileToken = Token<SyntaxKind.EndOfFileToken>;
|
||||
export type EndOfFileToken = Token<SyntaxKind.EndOfFileToken> & JSDocContainer;
|
||||
export type AtToken = Token<SyntaxKind.AtToken>;
|
||||
export type ReadonlyToken = Token<SyntaxKind.ReadonlyKeyword>;
|
||||
export type AwaitKeywordToken = Token<SyntaxKind.AwaitKeyword>;
|
||||
@@ -636,6 +672,7 @@ namespace ts {
|
||||
|
||||
export interface Decorator extends Node {
|
||||
kind: SyntaxKind.Decorator;
|
||||
parent?: NamedDeclaration;
|
||||
expression: LeftHandSideExpression;
|
||||
}
|
||||
|
||||
@@ -650,32 +687,34 @@ namespace ts {
|
||||
expression?: Expression;
|
||||
}
|
||||
|
||||
export interface SignatureDeclaration extends NamedDeclaration {
|
||||
kind: SyntaxKind.CallSignature
|
||||
| SyntaxKind.ConstructSignature
|
||||
| SyntaxKind.MethodSignature
|
||||
| SyntaxKind.IndexSignature
|
||||
| SyntaxKind.FunctionType
|
||||
| SyntaxKind.ConstructorType
|
||||
| SyntaxKind.JSDocFunctionType
|
||||
| SyntaxKind.FunctionDeclaration
|
||||
| SyntaxKind.MethodDeclaration
|
||||
| SyntaxKind.Constructor
|
||||
| SyntaxKind.GetAccessor
|
||||
| SyntaxKind.SetAccessor
|
||||
| SyntaxKind.FunctionExpression
|
||||
| SyntaxKind.ArrowFunction;
|
||||
export interface SignatureDeclarationBase extends NamedDeclaration, JSDocContainer {
|
||||
kind: SignatureDeclaration["kind"];
|
||||
name?: PropertyName;
|
||||
typeParameters?: NodeArray<TypeParameterDeclaration>;
|
||||
parameters: NodeArray<ParameterDeclaration>;
|
||||
type: TypeNode | undefined;
|
||||
}
|
||||
|
||||
export interface CallSignatureDeclaration extends SignatureDeclaration, TypeElement {
|
||||
export type SignatureDeclaration =
|
||||
| CallSignatureDeclaration
|
||||
| ConstructSignatureDeclaration
|
||||
| MethodSignature
|
||||
| IndexSignatureDeclaration
|
||||
| FunctionTypeNode
|
||||
| ConstructorTypeNode
|
||||
| JSDocFunctionType
|
||||
| FunctionDeclaration
|
||||
| MethodDeclaration
|
||||
| ConstructorDeclaration
|
||||
| AccessorDeclaration
|
||||
| FunctionExpression
|
||||
| ArrowFunction;
|
||||
|
||||
export interface CallSignatureDeclaration extends SignatureDeclarationBase, TypeElement {
|
||||
kind: SyntaxKind.CallSignature;
|
||||
}
|
||||
|
||||
export interface ConstructSignatureDeclaration extends SignatureDeclaration, TypeElement {
|
||||
export interface ConstructSignatureDeclaration extends SignatureDeclarationBase, TypeElement {
|
||||
kind: SyntaxKind.ConstructSignature;
|
||||
}
|
||||
|
||||
@@ -695,7 +734,7 @@ namespace ts {
|
||||
declarations: NodeArray<VariableDeclaration>;
|
||||
}
|
||||
|
||||
export interface ParameterDeclaration extends NamedDeclaration {
|
||||
export interface ParameterDeclaration extends NamedDeclaration, JSDocContainer {
|
||||
kind: SyntaxKind.Parameter;
|
||||
parent?: SignatureDeclaration;
|
||||
dotDotDotToken?: DotDotDotToken; // Present on rest parameter
|
||||
@@ -714,7 +753,7 @@ namespace ts {
|
||||
initializer?: Expression; // Optional initializer
|
||||
}
|
||||
|
||||
export interface PropertySignature extends TypeElement {
|
||||
export interface PropertySignature extends TypeElement, JSDocContainer {
|
||||
kind: SyntaxKind.PropertySignature;
|
||||
name: PropertyName; // Declared property name
|
||||
questionToken?: QuestionToken; // Present on optional property
|
||||
@@ -722,7 +761,7 @@ namespace ts {
|
||||
initializer?: Expression; // Optional initializer
|
||||
}
|
||||
|
||||
export interface PropertyDeclaration extends ClassElement {
|
||||
export interface PropertyDeclaration extends ClassElement, JSDocContainer {
|
||||
kind: SyntaxKind.PropertyDeclaration;
|
||||
questionToken?: QuestionToken; // Present for use with reporting a grammar error
|
||||
name: PropertyName;
|
||||
@@ -743,14 +782,16 @@ namespace ts {
|
||||
| AccessorDeclaration
|
||||
;
|
||||
|
||||
export interface PropertyAssignment extends ObjectLiteralElement {
|
||||
export interface PropertyAssignment extends ObjectLiteralElement, JSDocContainer {
|
||||
parent: ObjectLiteralExpression;
|
||||
kind: SyntaxKind.PropertyAssignment;
|
||||
name: PropertyName;
|
||||
questionToken?: QuestionToken;
|
||||
initializer: Expression;
|
||||
}
|
||||
|
||||
export interface ShorthandPropertyAssignment extends ObjectLiteralElement {
|
||||
export interface ShorthandPropertyAssignment extends ObjectLiteralElement, JSDocContainer {
|
||||
parent: ObjectLiteralExpression;
|
||||
kind: SyntaxKind.ShorthandPropertyAssignment;
|
||||
name: Identifier;
|
||||
questionToken?: QuestionToken;
|
||||
@@ -760,7 +801,8 @@ namespace ts {
|
||||
objectAssignmentInitializer?: Expression;
|
||||
}
|
||||
|
||||
export interface SpreadAssignment extends ObjectLiteralElement {
|
||||
export interface SpreadAssignment extends ObjectLiteralElement, JSDocContainer {
|
||||
parent: ObjectLiteralExpression;
|
||||
kind: SyntaxKind.SpreadAssignment;
|
||||
expression: Expression;
|
||||
}
|
||||
@@ -778,7 +820,7 @@ namespace ts {
|
||||
export interface VariableLikeDeclaration extends NamedDeclaration {
|
||||
propertyName?: PropertyName;
|
||||
dotDotDotToken?: DotDotDotToken;
|
||||
name?: DeclarationName; // May be missing for ParameterDeclaration, see comment there
|
||||
name: DeclarationName;
|
||||
questionToken?: QuestionToken;
|
||||
type?: TypeNode;
|
||||
initializer?: Expression;
|
||||
@@ -812,7 +854,7 @@ namespace ts {
|
||||
* - MethodDeclaration
|
||||
* - AccessorDeclaration
|
||||
*/
|
||||
export interface FunctionLikeDeclarationBase extends SignatureDeclaration {
|
||||
export interface FunctionLikeDeclarationBase extends SignatureDeclarationBase {
|
||||
_functionLikeDeclarationBrand: any;
|
||||
|
||||
asteriskToken?: AsteriskToken;
|
||||
@@ -843,7 +885,7 @@ namespace ts {
|
||||
body?: FunctionBody;
|
||||
}
|
||||
|
||||
export interface MethodSignature extends SignatureDeclaration, TypeElement {
|
||||
export interface MethodSignature extends SignatureDeclarationBase, TypeElement {
|
||||
kind: SyntaxKind.MethodSignature;
|
||||
name: PropertyName;
|
||||
}
|
||||
@@ -857,13 +899,13 @@ namespace ts {
|
||||
// Because of this, it may be necessary to determine what sort of MethodDeclaration you have
|
||||
// at later stages of the compiler pipeline. In that case, you can either check the parent kind
|
||||
// of the method, or use helpers like isObjectLiteralMethodDeclaration
|
||||
export interface MethodDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement {
|
||||
export interface MethodDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer {
|
||||
kind: SyntaxKind.MethodDeclaration;
|
||||
name: PropertyName;
|
||||
body?: FunctionBody;
|
||||
}
|
||||
|
||||
export interface ConstructorDeclaration extends FunctionLikeDeclarationBase, ClassElement {
|
||||
export interface ConstructorDeclaration extends FunctionLikeDeclarationBase, ClassElement, JSDocContainer {
|
||||
kind: SyntaxKind.Constructor;
|
||||
parent?: ClassDeclaration | ClassExpression;
|
||||
body?: FunctionBody;
|
||||
@@ -877,7 +919,7 @@ namespace ts {
|
||||
|
||||
// See the comment on MethodDeclaration for the intuition behind GetAccessorDeclaration being a
|
||||
// ClassElement and an ObjectLiteralElement.
|
||||
export interface GetAccessorDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement {
|
||||
export interface GetAccessorDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer {
|
||||
kind: SyntaxKind.GetAccessor;
|
||||
parent?: ClassDeclaration | ClassExpression | ObjectLiteralExpression;
|
||||
name: PropertyName;
|
||||
@@ -886,7 +928,7 @@ namespace ts {
|
||||
|
||||
// See the comment on MethodDeclaration for the intuition behind SetAccessorDeclaration being a
|
||||
// ClassElement and an ObjectLiteralElement.
|
||||
export interface SetAccessorDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement {
|
||||
export interface SetAccessorDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer {
|
||||
kind: SyntaxKind.SetAccessor;
|
||||
parent?: ClassDeclaration | ClassExpression | ObjectLiteralExpression;
|
||||
name: PropertyName;
|
||||
@@ -895,7 +937,7 @@ namespace ts {
|
||||
|
||||
export type AccessorDeclaration = GetAccessorDeclaration | SetAccessorDeclaration;
|
||||
|
||||
export interface IndexSignatureDeclaration extends SignatureDeclaration, ClassElement, TypeElement {
|
||||
export interface IndexSignatureDeclaration extends SignatureDeclarationBase, ClassElement, TypeElement {
|
||||
kind: SyntaxKind.IndexSignature;
|
||||
parent?: ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeLiteralNode;
|
||||
}
|
||||
@@ -924,11 +966,11 @@ namespace ts {
|
||||
|
||||
export type FunctionOrConstructorTypeNode = FunctionTypeNode | ConstructorTypeNode;
|
||||
|
||||
export interface FunctionTypeNode extends TypeNode, SignatureDeclaration {
|
||||
export interface FunctionTypeNode extends TypeNode, SignatureDeclarationBase {
|
||||
kind: SyntaxKind.FunctionType;
|
||||
}
|
||||
|
||||
export interface ConstructorTypeNode extends TypeNode, SignatureDeclaration {
|
||||
export interface ConstructorTypeNode extends TypeNode, SignatureDeclarationBase {
|
||||
kind: SyntaxKind.ConstructorType;
|
||||
}
|
||||
|
||||
@@ -942,6 +984,7 @@ namespace ts {
|
||||
|
||||
export interface TypePredicateNode extends TypeNode {
|
||||
kind: SyntaxKind.TypePredicate;
|
||||
parent?: SignatureDeclaration;
|
||||
parameterName: Identifier | ThisTypeNode;
|
||||
type: TypeNode;
|
||||
}
|
||||
@@ -998,7 +1041,6 @@ namespace ts {
|
||||
|
||||
export interface MappedTypeNode extends TypeNode, Declaration {
|
||||
kind: SyntaxKind.MappedType;
|
||||
parent?: TypeAliasDeclaration;
|
||||
readonlyToken?: ReadonlyToken;
|
||||
typeParameter: TypeParameterDeclaration;
|
||||
questionToken?: QuestionToken;
|
||||
@@ -1351,13 +1393,13 @@ namespace ts {
|
||||
export type FunctionBody = Block;
|
||||
export type ConciseBody = FunctionBody | Expression;
|
||||
|
||||
export interface FunctionExpression extends PrimaryExpression, FunctionLikeDeclarationBase {
|
||||
export interface FunctionExpression extends PrimaryExpression, FunctionLikeDeclarationBase, JSDocContainer {
|
||||
kind: SyntaxKind.FunctionExpression;
|
||||
name?: Identifier;
|
||||
body: FunctionBody; // Required, whereas the member inherited from FunctionDeclaration is optional
|
||||
}
|
||||
|
||||
export interface ArrowFunction extends Expression, FunctionLikeDeclarationBase {
|
||||
export interface ArrowFunction extends Expression, FunctionLikeDeclarationBase, JSDocContainer {
|
||||
kind: SyntaxKind.ArrowFunction;
|
||||
equalsGreaterThanToken: EqualsGreaterThanToken;
|
||||
body: ConciseBody;
|
||||
@@ -1436,7 +1478,7 @@ namespace ts {
|
||||
literal: TemplateMiddle | TemplateTail;
|
||||
}
|
||||
|
||||
export interface ParenthesizedExpression extends PrimaryExpression {
|
||||
export interface ParenthesizedExpression extends PrimaryExpression, JSDocContainer {
|
||||
kind: SyntaxKind.ParenthesizedExpression;
|
||||
expression: Expression;
|
||||
}
|
||||
@@ -1450,6 +1492,7 @@ namespace ts {
|
||||
|
||||
export interface SpreadElement extends Expression {
|
||||
kind: SyntaxKind.SpreadElement;
|
||||
parent?: ArrayLiteralExpression | CallExpression | NewExpression;
|
||||
expression: Expression;
|
||||
}
|
||||
|
||||
@@ -1691,12 +1734,12 @@ namespace ts {
|
||||
/*@internal*/ multiLine?: boolean;
|
||||
}
|
||||
|
||||
export interface VariableStatement extends Statement {
|
||||
export interface VariableStatement extends Statement, JSDocContainer {
|
||||
kind: SyntaxKind.VariableStatement;
|
||||
declarationList: VariableDeclarationList;
|
||||
}
|
||||
|
||||
export interface ExpressionStatement extends Statement {
|
||||
export interface ExpressionStatement extends Statement, JSDocContainer {
|
||||
kind: SyntaxKind.ExpressionStatement;
|
||||
expression: Expression;
|
||||
}
|
||||
@@ -1802,7 +1845,7 @@ namespace ts {
|
||||
|
||||
export type CaseOrDefaultClause = CaseClause | DefaultClause;
|
||||
|
||||
export interface LabeledStatement extends Statement {
|
||||
export interface LabeledStatement extends Statement, JSDocContainer {
|
||||
kind: SyntaxKind.LabeledStatement;
|
||||
label: Identifier;
|
||||
statement: Statement;
|
||||
@@ -1829,7 +1872,7 @@ namespace ts {
|
||||
|
||||
export type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag;
|
||||
|
||||
export interface ClassLikeDeclaration extends NamedDeclaration {
|
||||
export interface ClassLikeDeclarationBase extends NamedDeclaration, JSDocContainer {
|
||||
kind: SyntaxKind.ClassDeclaration | SyntaxKind.ClassExpression;
|
||||
name?: Identifier;
|
||||
typeParameters?: NodeArray<TypeParameterDeclaration>;
|
||||
@@ -1837,15 +1880,17 @@ namespace ts {
|
||||
members: NodeArray<ClassElement>;
|
||||
}
|
||||
|
||||
export interface ClassDeclaration extends ClassLikeDeclaration, DeclarationStatement {
|
||||
export interface ClassDeclaration extends ClassLikeDeclarationBase, DeclarationStatement {
|
||||
kind: SyntaxKind.ClassDeclaration;
|
||||
name?: Identifier;
|
||||
}
|
||||
|
||||
export interface ClassExpression extends ClassLikeDeclaration, PrimaryExpression {
|
||||
export interface ClassExpression extends ClassLikeDeclarationBase, PrimaryExpression {
|
||||
kind: SyntaxKind.ClassExpression;
|
||||
}
|
||||
|
||||
export type ClassLikeDeclaration = ClassDeclaration | ClassExpression;
|
||||
|
||||
export interface ClassElement extends NamedDeclaration {
|
||||
_classElementBrand: any;
|
||||
name?: PropertyName;
|
||||
@@ -1857,7 +1902,7 @@ namespace ts {
|
||||
questionToken?: QuestionToken;
|
||||
}
|
||||
|
||||
export interface InterfaceDeclaration extends DeclarationStatement {
|
||||
export interface InterfaceDeclaration extends DeclarationStatement, JSDocContainer {
|
||||
kind: SyntaxKind.InterfaceDeclaration;
|
||||
name: Identifier;
|
||||
typeParameters?: NodeArray<TypeParameterDeclaration>;
|
||||
@@ -1872,14 +1917,14 @@ namespace ts {
|
||||
types: NodeArray<ExpressionWithTypeArguments>;
|
||||
}
|
||||
|
||||
export interface TypeAliasDeclaration extends DeclarationStatement {
|
||||
export interface TypeAliasDeclaration extends DeclarationStatement, JSDocContainer {
|
||||
kind: SyntaxKind.TypeAliasDeclaration;
|
||||
name: Identifier;
|
||||
typeParameters?: NodeArray<TypeParameterDeclaration>;
|
||||
type: TypeNode;
|
||||
}
|
||||
|
||||
export interface EnumMember extends NamedDeclaration {
|
||||
export interface EnumMember extends NamedDeclaration, JSDocContainer {
|
||||
kind: SyntaxKind.EnumMember;
|
||||
parent?: EnumDeclaration;
|
||||
// This does include ComputedPropertyName, but the parser will give an error
|
||||
@@ -1888,7 +1933,7 @@ namespace ts {
|
||||
initializer?: Expression;
|
||||
}
|
||||
|
||||
export interface EnumDeclaration extends DeclarationStatement {
|
||||
export interface EnumDeclaration extends DeclarationStatement, JSDocContainer {
|
||||
kind: SyntaxKind.EnumDeclaration;
|
||||
name: Identifier;
|
||||
members: NodeArray<EnumMember>;
|
||||
@@ -1898,7 +1943,7 @@ namespace ts {
|
||||
|
||||
export type ModuleBody = NamespaceBody | JSDocNamespaceBody;
|
||||
|
||||
export interface ModuleDeclaration extends DeclarationStatement {
|
||||
export interface ModuleDeclaration extends DeclarationStatement, JSDocContainer {
|
||||
kind: SyntaxKind.ModuleDeclaration;
|
||||
parent?: ModuleBody | SourceFile;
|
||||
name: ModuleName;
|
||||
@@ -1932,7 +1977,7 @@ namespace ts {
|
||||
* - import x = require("mod");
|
||||
* - import x = M.x;
|
||||
*/
|
||||
export interface ImportEqualsDeclaration extends DeclarationStatement {
|
||||
export interface ImportEqualsDeclaration extends DeclarationStatement, JSDocContainer {
|
||||
kind: SyntaxKind.ImportEqualsDeclaration;
|
||||
parent?: SourceFile | ModuleBlock;
|
||||
name: Identifier;
|
||||
@@ -2085,7 +2130,7 @@ namespace ts {
|
||||
type: TypeNode;
|
||||
}
|
||||
|
||||
export interface JSDocFunctionType extends JSDocType, SignatureDeclaration {
|
||||
export interface JSDocFunctionType extends JSDocType, SignatureDeclarationBase {
|
||||
kind: SyntaxKind.JSDocFunctionType;
|
||||
}
|
||||
|
||||
@@ -2098,6 +2143,7 @@ namespace ts {
|
||||
|
||||
export interface JSDoc extends Node {
|
||||
kind: SyntaxKind.JSDocComment;
|
||||
parent?: HasJSDoc;
|
||||
tags: NodeArray<JSDocTag> | undefined;
|
||||
comment: string | undefined;
|
||||
}
|
||||
@@ -2165,7 +2211,6 @@ namespace ts {
|
||||
export interface JSDocTypeLiteral extends JSDocType {
|
||||
kind: SyntaxKind.JSDocTypeLiteral;
|
||||
jsDocPropertyTags?: ReadonlyArray<JSDocPropertyLikeTag>;
|
||||
jsDocTypeTag?: JSDocTypeTag;
|
||||
/** If true, then this type literal represents an *array* of its type. */
|
||||
isArrayType?: boolean;
|
||||
}
|
||||
@@ -3331,13 +3376,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface MappedType extends ObjectType {
|
||||
export interface MappedType extends AnonymousType {
|
||||
declaration: MappedTypeNode;
|
||||
typeParameter?: TypeParameter;
|
||||
constraintType?: Type;
|
||||
templateType?: Type;
|
||||
modifiersType?: Type;
|
||||
mapper?: TypeMapper; // Instantiation mapper
|
||||
}
|
||||
|
||||
export interface EvolvingArrayType extends ObjectType {
|
||||
@@ -3448,6 +3492,8 @@ namespace ts {
|
||||
/* @internal */
|
||||
erasedSignatureCache?: Signature; // Erased version of signature (deferred)
|
||||
/* @internal */
|
||||
canonicalSignatureCache?: Signature; // Canonical version of signature (deferred)
|
||||
/* @internal */
|
||||
isolatedSignatureType?: ObjectType; // A manufactured type that just contains the signature for purposes of signature comparison
|
||||
/* @internal */
|
||||
typePredicate?: TypePredicate;
|
||||
@@ -3469,8 +3515,6 @@ namespace ts {
|
||||
/* @internal */
|
||||
export interface TypeMapper {
|
||||
(t: TypeParameter): Type;
|
||||
mappedTypes?: TypeParameter[]; // Types mapped by this mapper
|
||||
instantiations?: Type[]; // Cache of instantiations created using this type mapper.
|
||||
}
|
||||
|
||||
export const enum InferencePriority {
|
||||
@@ -3584,7 +3628,7 @@ namespace ts {
|
||||
name: string;
|
||||
}
|
||||
|
||||
export type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike<string[]> | PluginImport[];
|
||||
export type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike<string[]> | PluginImport[] | null | undefined;
|
||||
|
||||
export interface CompilerOptions {
|
||||
/*@internal*/ all?: boolean;
|
||||
@@ -4010,6 +4054,11 @@ namespace ts {
|
||||
* If accessing a non-index file, this should include its name e.g. "foo/bar".
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Name of a submodule within this package.
|
||||
* May be "".
|
||||
*/
|
||||
subModuleName: string;
|
||||
/** Version of the package, e.g. "1.2.3" */
|
||||
version: string;
|
||||
}
|
||||
@@ -4033,6 +4082,7 @@ namespace ts {
|
||||
primary: boolean;
|
||||
// The location of the .d.ts file we located, or undefined if resolution failed
|
||||
resolvedFileName?: string;
|
||||
packageId?: PackageId;
|
||||
}
|
||||
|
||||
export interface ResolvedTypeReferenceDirectiveWithFailedLookupLocations {
|
||||
@@ -4254,10 +4304,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
export const enum EmitHint {
|
||||
SourceFile, // Emitting a SourceFile
|
||||
Expression, // Emitting an Expression
|
||||
IdentifierName, // Emitting an IdentifierName
|
||||
Unspecified, // Emitting an otherwise unspecified node
|
||||
SourceFile, // Emitting a SourceFile
|
||||
Expression, // Emitting an Expression
|
||||
IdentifierName, // Emitting an IdentifierName
|
||||
MappedTypeParameter, // Emitting a TypeParameterDeclaration inside of a MappedTypeNode
|
||||
Unspecified, // Emitting an otherwise unspecified node
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
|
||||
+80
-13
@@ -32,7 +32,6 @@ namespace ts {
|
||||
}
|
||||
|
||||
const stringWriter = createSingleLineStringWriter();
|
||||
let stringWriterAcquired = false;
|
||||
|
||||
function createSingleLineStringWriter(): StringSymbolWriter {
|
||||
let str = "";
|
||||
@@ -62,15 +61,14 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function usingSingleLineStringWriter(action: (writer: StringSymbolWriter) => void): string {
|
||||
const oldString = stringWriter.string();
|
||||
try {
|
||||
Debug.assert(!stringWriterAcquired);
|
||||
stringWriterAcquired = true;
|
||||
action(stringWriter);
|
||||
return stringWriter.string();
|
||||
}
|
||||
finally {
|
||||
stringWriter.clear();
|
||||
stringWriterAcquired = false;
|
||||
stringWriter.writeKeyword(oldString);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,7 +104,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function packageIdIsEqual(a: PackageId | undefined, b: PackageId | undefined): boolean {
|
||||
return a === b || a && b && a.name === b.name && a.version === b.version;
|
||||
return a === b || a && b && a.name === b.name && a.subModuleName === b.subModuleName && a.version === b.version;
|
||||
}
|
||||
|
||||
export function typeDirectiveIsEqualTo(oldResolution: ResolvedTypeReferenceDirective, newResolution: ResolvedTypeReferenceDirective): boolean {
|
||||
@@ -279,7 +277,7 @@ namespace ts {
|
||||
return skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos, /*stopAfterLineBreak*/ false, /*stopAtComments*/ true);
|
||||
}
|
||||
|
||||
if (includeJsDoc && node.jsDoc && node.jsDoc.length > 0) {
|
||||
if (includeJsDoc && hasJSDocNodes(node)) {
|
||||
return getTokenPosOfNode(node.jsDoc[0]);
|
||||
}
|
||||
|
||||
@@ -1512,10 +1510,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function getJSDocTags(node: Node): ReadonlyArray<JSDocTag> | undefined {
|
||||
let tags = node.jsDocCache;
|
||||
let tags = (node as JSDocContainer).jsDocCache;
|
||||
// If cache is 'null', that means we did the work of searching for JSDoc tags and came up with nothing.
|
||||
if (tags === undefined) {
|
||||
node.jsDocCache = tags = flatMap(getJSDocCommentsAndTags(node), j => isJSDoc(j) ? j.tags : j);
|
||||
(node as JSDocContainer).jsDocCache = tags = flatMap(getJSDocCommentsAndTags(node), j => isJSDoc(j) ? j.tags : j);
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
@@ -1569,11 +1567,13 @@ namespace ts {
|
||||
result = addRange(result, getJSDocParameterTags(node as ParameterDeclaration));
|
||||
}
|
||||
|
||||
if (isVariableLike(node) && node.initializer) {
|
||||
if (isVariableLike(node) && node.initializer && hasJSDocNodes(node.initializer)) {
|
||||
result = addRange(result, node.initializer.jsDoc);
|
||||
}
|
||||
|
||||
result = addRange(result, node.jsDoc);
|
||||
if (hasJSDocNodes(node)) {
|
||||
result = addRange(result, node.jsDoc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3960,7 +3960,66 @@ namespace ts {
|
||||
return id;
|
||||
}
|
||||
|
||||
export function getNameOfDeclaration(declaration: Declaration): DeclarationName | undefined {
|
||||
/**
|
||||
* A JSDocTypedef tag has an _optional_ name field - if a name is not directly present, we should
|
||||
* attempt to draw the name from the node the declaration is on (as that declaration is what its' symbol
|
||||
* will be merged with)
|
||||
*/
|
||||
function nameForNamelessJSDocTypedef(declaration: JSDocTypedefTag): Identifier | undefined {
|
||||
const hostNode = declaration.parent.parent;
|
||||
if (!hostNode) {
|
||||
return undefined;
|
||||
}
|
||||
// Covers classes, functions - any named declaration host node
|
||||
if (isDeclaration(hostNode)) {
|
||||
return getDeclarationIdentifier(hostNode);
|
||||
}
|
||||
// Covers remaining cases
|
||||
switch (hostNode.kind) {
|
||||
case SyntaxKind.VariableStatement:
|
||||
if ((hostNode as VariableStatement).declarationList &&
|
||||
(hostNode as VariableStatement).declarationList.declarations[0]) {
|
||||
return getDeclarationIdentifier((hostNode as VariableStatement).declarationList.declarations[0]);
|
||||
}
|
||||
return undefined;
|
||||
case SyntaxKind.ExpressionStatement:
|
||||
const expr = (hostNode as ExpressionStatement).expression;
|
||||
switch (expr.kind) {
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
return (expr as PropertyAccessExpression).name;
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
const arg = (expr as ElementAccessExpression).argumentExpression;
|
||||
if (isIdentifier(arg)) {
|
||||
return arg;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
case SyntaxKind.EndOfFileToken:
|
||||
return undefined;
|
||||
case SyntaxKind.ParenthesizedExpression: {
|
||||
return getDeclarationIdentifier(hostNode.expression);
|
||||
}
|
||||
case SyntaxKind.LabeledStatement: {
|
||||
if (isDeclaration(hostNode.statement) || isExpression(hostNode.statement)) {
|
||||
return getDeclarationIdentifier(hostNode.statement);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
default:
|
||||
Debug.assertNever(hostNode, "Found typedef tag attached to node which it should not be!");
|
||||
}
|
||||
}
|
||||
|
||||
function getDeclarationIdentifier(node: Declaration | Expression) {
|
||||
const name = getNameOfDeclaration(node);
|
||||
return isIdentifier(name) ? name : undefined;
|
||||
}
|
||||
|
||||
export function getNameOfJSDocTypedef(declaration: JSDocTypedefTag): Identifier | undefined {
|
||||
return declaration.name || nameForNamelessJSDocTypedef(declaration as JSDocTypedefTag);
|
||||
}
|
||||
|
||||
export function getNameOfDeclaration(declaration: Declaration | Expression): DeclarationName | undefined {
|
||||
if (!declaration) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -3979,6 +4038,9 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
else if (declaration.kind === SyntaxKind.JSDocTypedefTag) {
|
||||
return getNameOfJSDocTypedef(declaration as JSDocTypedefTag);
|
||||
}
|
||||
else {
|
||||
return (declaration as NamedDeclaration).name;
|
||||
}
|
||||
@@ -4666,8 +4728,7 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
export function isNodeArray<T extends Node>(array: ReadonlyArray<T>): array is NodeArray<T> {
|
||||
return array.hasOwnProperty("pos")
|
||||
&& array.hasOwnProperty("end");
|
||||
return array.hasOwnProperty("pos") && array.hasOwnProperty("end");
|
||||
}
|
||||
|
||||
// Literals
|
||||
@@ -5372,4 +5433,10 @@ namespace ts {
|
||||
export function isJSDocTag(node: Node): boolean {
|
||||
return node.kind >= SyntaxKind.FirstJSDocTagNode && node.kind <= SyntaxKind.LastJSDocTagNode;
|
||||
}
|
||||
|
||||
/** True if has jsdoc nodes attached to it. */
|
||||
/* @internal */
|
||||
export function hasJSDocNodes(node: Node): node is HasJSDoc {
|
||||
return !!(node as JSDocContainer).jsDoc && (node as JSDocContainer).jsDoc.length > 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -488,6 +488,7 @@ namespace ts {
|
||||
nodesVisitor((<ArrowFunction>node).typeParameters, visitor, isTypeParameterDeclaration),
|
||||
visitParameterList((<ArrowFunction>node).parameters, visitor, context, nodesVisitor),
|
||||
visitNode((<ArrowFunction>node).type, visitor, isTypeNode),
|
||||
visitNode((<ArrowFunction>node).equalsGreaterThanToken, visitor, isToken),
|
||||
visitFunctionBody((<ArrowFunction>node).body, visitor, context));
|
||||
|
||||
case SyntaxKind.DeleteExpression:
|
||||
@@ -523,7 +524,9 @@ namespace ts {
|
||||
case SyntaxKind.ConditionalExpression:
|
||||
return updateConditional(<ConditionalExpression>node,
|
||||
visitNode((<ConditionalExpression>node).condition, visitor, isExpression),
|
||||
visitNode((<ConditionalExpression>node).questionToken, visitor, isToken),
|
||||
visitNode((<ConditionalExpression>node).whenTrue, visitor, isExpression),
|
||||
visitNode((<ConditionalExpression>node).colonToken, visitor, isToken),
|
||||
visitNode((<ConditionalExpression>node).whenFalse, visitor, isExpression));
|
||||
|
||||
case SyntaxKind.TemplateExpression:
|
||||
|
||||
@@ -141,7 +141,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
|
||||
// check errors
|
||||
it("Correct errors for " + fileName, () => {
|
||||
Harness.Compiler.doErrorBaseline(justName, tsConfigFiles.concat(toBeCompiled, otherFiles), result.errors);
|
||||
Harness.Compiler.doErrorBaseline(justName, tsConfigFiles.concat(toBeCompiled, otherFiles), result.errors, !!options.pretty);
|
||||
});
|
||||
|
||||
it (`Correct module resolution tracing for ${fileName}`, () => {
|
||||
|
||||
@@ -762,7 +762,7 @@ namespace FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
public verifyCompletionsAt(markerName: string, expected: string[]) {
|
||||
public verifyCompletionsAt(markerName: string, expected: string[], options?: FourSlashInterface.CompletionsAtOptions) {
|
||||
this.goToMarker(markerName);
|
||||
|
||||
const actualCompletions = this.getCompletionListAtCaret();
|
||||
@@ -770,6 +770,10 @@ namespace FourSlash {
|
||||
this.raiseError(`No completions at position '${this.currentCaretPosition}'.`);
|
||||
}
|
||||
|
||||
if (options && options.isNewIdentifierLocation !== undefined && actualCompletions.isNewIdentifierLocation !== options.isNewIdentifierLocation) {
|
||||
this.raiseError(`Expected 'isNewIdentifierLocation' to be ${options.isNewIdentifierLocation}, got ${actualCompletions.isNewIdentifierLocation}`);
|
||||
}
|
||||
|
||||
const actual = actualCompletions.entries;
|
||||
|
||||
if (actual.length !== expected.length) {
|
||||
@@ -2410,7 +2414,7 @@ namespace FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
public verifyDocCommentTemplate(expected?: ts.TextInsertion) {
|
||||
public verifyDocCommentTemplate(expected: ts.TextInsertion | undefined) {
|
||||
const name = "verifyDocCommentTemplate";
|
||||
const actual = this.languageService.getDocCommentTemplateAtPosition(this.activeFile.fileName, this.currentCaretPosition);
|
||||
|
||||
@@ -3705,8 +3709,8 @@ namespace FourSlashInterface {
|
||||
super(state);
|
||||
}
|
||||
|
||||
public completionsAt(markerName: string, completions: string[]) {
|
||||
this.state.verifyCompletionsAt(markerName, completions);
|
||||
public completionsAt(markerName: string, completions: string[], options?: CompletionsAtOptions) {
|
||||
this.state.verifyCompletionsAt(markerName, completions, options);
|
||||
}
|
||||
|
||||
public quickInfoIs(expectedText: string, expectedDocumentation?: string) {
|
||||
@@ -3904,12 +3908,14 @@ namespace FourSlashInterface {
|
||||
this.state.verifyNoMatchingBracePosition(bracePosition);
|
||||
}
|
||||
|
||||
public DocCommentTemplate(expectedText: string, expectedOffset: number, empty?: boolean) {
|
||||
this.state.verifyDocCommentTemplate(empty ? undefined : { newText: expectedText, caretOffset: expectedOffset });
|
||||
public docCommentTemplateAt(marker: string | FourSlash.Marker, expectedOffset: number, expectedText: string) {
|
||||
this.state.goToMarker(marker);
|
||||
this.state.verifyDocCommentTemplate({ newText: expectedText.replace(/\r?\n/g, "\r\n"), caretOffset: expectedOffset });
|
||||
}
|
||||
|
||||
public noDocCommentTemplate() {
|
||||
this.DocCommentTemplate(/*expectedText*/ undefined, /*expectedOffset*/ undefined, /*empty*/ true);
|
||||
public noDocCommentTemplateAt(marker: string | FourSlash.Marker) {
|
||||
this.state.goToMarker(marker);
|
||||
this.state.verifyDocCommentTemplate(/*expected*/ undefined);
|
||||
}
|
||||
|
||||
public rangeAfterCodeFix(expectedText: string, includeWhiteSpace?: boolean, errorCode?: number, index?: number): void {
|
||||
@@ -4314,4 +4320,8 @@ namespace FourSlashInterface {
|
||||
actionName: string;
|
||||
actionDescription: string;
|
||||
}
|
||||
|
||||
export interface CompletionsAtOptions {
|
||||
isNewIdentifierLocation?: boolean;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1284,11 +1284,12 @@ namespace Harness {
|
||||
return normalized;
|
||||
}
|
||||
|
||||
export function minimalDiagnosticsToString(diagnostics: ReadonlyArray<ts.Diagnostic>) {
|
||||
return ts.formatDiagnostics(diagnostics, { getCanonicalFileName, getCurrentDirectory: () => "", getNewLine: () => Harness.IO.newLine() });
|
||||
export function minimalDiagnosticsToString(diagnostics: ReadonlyArray<ts.Diagnostic>, pretty?: boolean) {
|
||||
const host = { getCanonicalFileName, getCurrentDirectory: () => "", getNewLine: () => Harness.IO.newLine() };
|
||||
return (pretty ? ts.formatDiagnosticsWithColorAndContext : ts.formatDiagnostics)(diagnostics, host);
|
||||
}
|
||||
|
||||
export function getErrorBaseline(inputFiles: ReadonlyArray<TestFile>, diagnostics: ReadonlyArray<ts.Diagnostic>) {
|
||||
export function getErrorBaseline(inputFiles: ReadonlyArray<TestFile>, diagnostics: ReadonlyArray<ts.Diagnostic>, pretty?: boolean) {
|
||||
diagnostics = diagnostics.slice().sort(ts.compareDiagnostics);
|
||||
let outputLines = "";
|
||||
// Count up all errors that were found in files other than lib.d.ts so we don't miss any
|
||||
@@ -1408,18 +1409,18 @@ namespace Harness {
|
||||
// Verify we didn't miss any errors in total
|
||||
assert.equal(totalErrorsReportedInNonLibraryFiles + numLibraryDiagnostics + numTest262HarnessDiagnostics, diagnostics.length, "total number of errors");
|
||||
|
||||
return minimalDiagnosticsToString(diagnostics) +
|
||||
return minimalDiagnosticsToString(diagnostics, pretty) +
|
||||
Harness.IO.newLine() + Harness.IO.newLine() + outputLines;
|
||||
}
|
||||
|
||||
export function doErrorBaseline(baselinePath: string, inputFiles: TestFile[], errors: ts.Diagnostic[]) {
|
||||
export function doErrorBaseline(baselinePath: string, inputFiles: TestFile[], errors: ts.Diagnostic[], pretty?: boolean) {
|
||||
Harness.Baseline.runBaseline(baselinePath.replace(/\.tsx?$/, ".errors.txt"), (): string => {
|
||||
if (!errors || (errors.length === 0)) {
|
||||
/* tslint:disable:no-null-keyword */
|
||||
return null;
|
||||
/* tslint:enable:no-null-keyword */
|
||||
}
|
||||
return getErrorBaseline(inputFiles, errors);
|
||||
return getErrorBaseline(inputFiles, errors, pretty);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -128,6 +128,7 @@
|
||||
"./unittests/extractMethods.ts",
|
||||
"./unittests/textChanges.ts",
|
||||
"./unittests/telemetry.ts",
|
||||
"./unittests/languageService.ts",
|
||||
"./unittests/programMissingFiles.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -78,6 +78,23 @@ namespace ts {
|
||||
},
|
||||
include: ["../supplemental.*"]
|
||||
},
|
||||
"/dev/configs/third.json": {
|
||||
extends: "./second",
|
||||
compilerOptions: {
|
||||
// tslint:disable-next-line:no-null-keyword
|
||||
module: null
|
||||
},
|
||||
include: ["../supplemental.*"]
|
||||
},
|
||||
"/dev/configs/fourth.json": {
|
||||
extends: "./third",
|
||||
compilerOptions: {
|
||||
module: "system"
|
||||
},
|
||||
// tslint:disable-next-line:no-null-keyword
|
||||
include: null,
|
||||
files: ["../main.ts"]
|
||||
},
|
||||
"/dev/extends.json": { extends: 42 },
|
||||
"/dev/extends2.json": { extends: "configs/base" },
|
||||
"/dev/main.ts": "",
|
||||
@@ -106,7 +123,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
describe("Configuration Extension", () => {
|
||||
describe("configurationExtension", () => {
|
||||
forEach<[string, string, Utils.MockParseConfigHost], void>([
|
||||
["under a case insensitive host", caseInsensitiveBasePath, caseInsensitiveHost],
|
||||
["under a case sensitive host", caseSensitiveBasePath, caseSensitiveHost]
|
||||
@@ -206,6 +223,24 @@ namespace ts {
|
||||
category: DiagnosticCategory.Error,
|
||||
messageText: `A path in an 'extends' option must be relative or rooted, but 'configs/base' is not.`
|
||||
}]);
|
||||
|
||||
testSuccess("can overwrite compiler options using extended 'null'", "configs/third.json", {
|
||||
allowJs: true,
|
||||
noImplicitAny: true,
|
||||
strictNullChecks: true,
|
||||
module: undefined // Technically, this is distinct from the key never being set; but within the compiler we don't make the distinction
|
||||
}, [
|
||||
combinePaths(basePath, "supplemental.ts")
|
||||
]);
|
||||
|
||||
testSuccess("can overwrite top-level options using extended 'null'", "configs/fourth.json", {
|
||||
allowJs: true,
|
||||
noImplicitAny: true,
|
||||
strictNullChecks: true,
|
||||
module: ModuleKind.System
|
||||
}, [
|
||||
combinePaths(basePath, "main.ts")
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/// <reference path="..\..\compiler\commandLineParser.ts" />
|
||||
|
||||
namespace ts {
|
||||
type ExpectedResult = { typeAcquisition: TypeAcquisition, errors: Diagnostic[] };
|
||||
interface ExpectedResult { typeAcquisition: TypeAcquisition; errors: Diagnostic[]; }
|
||||
describe("convertTypeAcquisitionFromJson", () => {
|
||||
function assertTypeAcquisition(json: any, configFileName: string, expectedResult: ExpectedResult) {
|
||||
assertTypeAcquisitionWithJson(json, configFileName, expectedResult);
|
||||
|
||||
@@ -378,6 +378,32 @@ namespace A {
|
||||
"Cannot extract range containing conditional return statement."
|
||||
]);
|
||||
|
||||
testExtractRangeFailed("extractRangeFailed7",
|
||||
`
|
||||
function test(x: number) {
|
||||
while (x) {
|
||||
x--;
|
||||
[#|break;|]
|
||||
}
|
||||
}
|
||||
`,
|
||||
[
|
||||
"Cannot extract range containing conditional break or continue statements."
|
||||
]);
|
||||
|
||||
testExtractRangeFailed("extractRangeFailed8",
|
||||
`
|
||||
function test(x: number) {
|
||||
switch (x) {
|
||||
case 1:
|
||||
[#|break;|]
|
||||
}
|
||||
}
|
||||
`,
|
||||
[
|
||||
"Cannot extract range containing conditional break or continue statements."
|
||||
]);
|
||||
|
||||
testExtractMethod("extractMethod1",
|
||||
`namespace A {
|
||||
let x = 1;
|
||||
@@ -613,6 +639,22 @@ namespace A {
|
||||
[#|let a1 = { x: 1 };
|
||||
return a1.x + 10;|]
|
||||
}
|
||||
}`);
|
||||
// Write + void return
|
||||
testExtractMethod("extractMethod21",
|
||||
`function foo() {
|
||||
let x = 10;
|
||||
[#|x++;
|
||||
return;|]
|
||||
}`);
|
||||
// Return in finally block
|
||||
testExtractMethod("extractMethod22",
|
||||
`function test() {
|
||||
try {
|
||||
}
|
||||
finally {
|
||||
[#|return 1;|]
|
||||
}
|
||||
}`);
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/// <reference path="..\harness.ts" />
|
||||
|
||||
namespace ts {
|
||||
describe("languageService", () => {
|
||||
const files: {[index: string]: string} = {
|
||||
"foo.ts": `import Vue from "./vue";
|
||||
import Component from "./vue-class-component";
|
||||
import { vueTemplateHtml } from "./variables";
|
||||
|
||||
@Component({
|
||||
template: vueTemplateHtml,
|
||||
})
|
||||
class Carousel<T> extends Vue {
|
||||
}`,
|
||||
"variables.ts": `export const vueTemplateHtml = \`<div></div>\`;`,
|
||||
"vue.d.ts": `export namespace Vue { export type Config = { template: string }; }`,
|
||||
"vue-class-component.d.ts": `import Vue from "./vue";
|
||||
export function Component(x: Config): any;`
|
||||
};
|
||||
// Regression test for GH #18245 - bug in single line comment writer caused a debug assertion when attempting
|
||||
// to write an alias to a module's default export was referrenced across files and had no default export
|
||||
it("should be able to create a language service which can respond to deinition requests without throwing", () => {
|
||||
const languageService = ts.createLanguageService({
|
||||
getCompilationSettings() {
|
||||
return {};
|
||||
},
|
||||
getScriptFileNames() {
|
||||
return ["foo.ts", "variables.ts", "vue.d.ts", "vue-class-component.d.ts"];
|
||||
},
|
||||
getScriptVersion(_fileName) {
|
||||
return "";
|
||||
},
|
||||
getScriptSnapshot(fileName) {
|
||||
if (fileName === ".ts") {
|
||||
return ts.ScriptSnapshot.fromString("");
|
||||
}
|
||||
return ts.ScriptSnapshot.fromString(files[fileName] || "");
|
||||
},
|
||||
getCurrentDirectory: () => ".",
|
||||
getDefaultLibFileName(options) {
|
||||
return ts.getDefaultLibFilePath(options);
|
||||
},
|
||||
fileExists: noop as any,
|
||||
readFile: noop as any,
|
||||
readDirectory: noop as any,
|
||||
});
|
||||
const definitions = languageService.getDefinitionAtPosition("foo.ts", 160); // 160 is the latter `vueTemplateHtml` position
|
||||
expect(definitions).to.exist;
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -198,33 +198,34 @@ namespace ts {
|
||||
const moduleFile = { name: "/a/b/node_modules/foo.ts" };
|
||||
const resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
|
||||
checkResolvedModuleWithFailedLookupLocations(resolution, createResolvedModule(moduleFile.name, /*isExternalLibraryImport*/ true), [
|
||||
"/a/b/c/d/node_modules/foo/package.json",
|
||||
"/a/b/c/d/node_modules/foo.ts",
|
||||
"/a/b/c/d/node_modules/foo.tsx",
|
||||
"/a/b/c/d/node_modules/foo.d.ts",
|
||||
"/a/b/c/d/node_modules/foo/package.json",
|
||||
|
||||
"/a/b/c/d/node_modules/foo/index.ts",
|
||||
"/a/b/c/d/node_modules/foo/index.tsx",
|
||||
"/a/b/c/d/node_modules/foo/index.d.ts",
|
||||
|
||||
"/a/b/c/d/node_modules/@types/foo.d.ts",
|
||||
"/a/b/c/d/node_modules/@types/foo/package.json",
|
||||
"/a/b/c/d/node_modules/@types/foo.d.ts",
|
||||
|
||||
"/a/b/c/d/node_modules/@types/foo/index.d.ts",
|
||||
|
||||
"/a/b/c/node_modules/foo/package.json",
|
||||
"/a/b/c/node_modules/foo.ts",
|
||||
"/a/b/c/node_modules/foo.tsx",
|
||||
"/a/b/c/node_modules/foo.d.ts",
|
||||
"/a/b/c/node_modules/foo/package.json",
|
||||
|
||||
"/a/b/c/node_modules/foo/index.ts",
|
||||
"/a/b/c/node_modules/foo/index.tsx",
|
||||
"/a/b/c/node_modules/foo/index.d.ts",
|
||||
|
||||
"/a/b/c/node_modules/@types/foo.d.ts",
|
||||
"/a/b/c/node_modules/@types/foo/package.json",
|
||||
"/a/b/c/node_modules/@types/foo.d.ts",
|
||||
|
||||
"/a/b/c/node_modules/@types/foo/index.d.ts",
|
||||
"/a/b/node_modules/foo/package.json",
|
||||
]);
|
||||
}
|
||||
});
|
||||
@@ -250,52 +251,52 @@ namespace ts {
|
||||
const moduleFile: File = { name: "/a/node_modules/foo/index.d.ts" };
|
||||
const resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
|
||||
checkResolvedModuleWithFailedLookupLocations(resolution, createResolvedModule(moduleFile.name, /*isExternalLibraryImport*/ true), [
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo/package.json",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo.ts",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo.tsx",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo.d.ts",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo/package.json",
|
||||
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo/index.ts",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo/index.tsx",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo/index.d.ts",
|
||||
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/@types/foo.d.ts",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/@types/foo/package.json",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/@types/foo.d.ts",
|
||||
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/@types/foo/index.d.ts",
|
||||
|
||||
"/a/node_modules/b/c/node_modules/foo/package.json",
|
||||
"/a/node_modules/b/c/node_modules/foo.ts",
|
||||
"/a/node_modules/b/c/node_modules/foo.tsx",
|
||||
"/a/node_modules/b/c/node_modules/foo.d.ts",
|
||||
"/a/node_modules/b/c/node_modules/foo/package.json",
|
||||
|
||||
"/a/node_modules/b/c/node_modules/foo/index.ts",
|
||||
"/a/node_modules/b/c/node_modules/foo/index.tsx",
|
||||
"/a/node_modules/b/c/node_modules/foo/index.d.ts",
|
||||
|
||||
"/a/node_modules/b/c/node_modules/@types/foo.d.ts",
|
||||
"/a/node_modules/b/c/node_modules/@types/foo/package.json",
|
||||
"/a/node_modules/b/c/node_modules/@types/foo.d.ts",
|
||||
|
||||
"/a/node_modules/b/c/node_modules/@types/foo/index.d.ts",
|
||||
|
||||
"/a/node_modules/b/node_modules/foo/package.json",
|
||||
"/a/node_modules/b/node_modules/foo.ts",
|
||||
"/a/node_modules/b/node_modules/foo.tsx",
|
||||
"/a/node_modules/b/node_modules/foo.d.ts",
|
||||
"/a/node_modules/b/node_modules/foo/package.json",
|
||||
|
||||
"/a/node_modules/b/node_modules/foo/index.ts",
|
||||
"/a/node_modules/b/node_modules/foo/index.tsx",
|
||||
"/a/node_modules/b/node_modules/foo/index.d.ts",
|
||||
|
||||
"/a/node_modules/b/node_modules/@types/foo.d.ts",
|
||||
"/a/node_modules/b/node_modules/@types/foo/package.json",
|
||||
"/a/node_modules/b/node_modules/@types/foo.d.ts",
|
||||
|
||||
"/a/node_modules/b/node_modules/@types/foo/index.d.ts",
|
||||
|
||||
"/a/node_modules/foo/package.json",
|
||||
"/a/node_modules/foo.ts",
|
||||
"/a/node_modules/foo.tsx",
|
||||
"/a/node_modules/foo.d.ts",
|
||||
"/a/node_modules/foo/package.json",
|
||||
|
||||
"/a/node_modules/foo/index.ts",
|
||||
"/a/node_modules/foo/index.tsx"
|
||||
@@ -707,21 +708,23 @@ import b = require("./moduleB");
|
||||
"/root/generated/file6/index.d.ts",
|
||||
|
||||
// fallback to standard node behavior
|
||||
"/root/folder1/node_modules/file6/package.json",
|
||||
|
||||
// load from file
|
||||
"/root/folder1/node_modules/file6.ts",
|
||||
"/root/folder1/node_modules/file6.tsx",
|
||||
"/root/folder1/node_modules/file6.d.ts",
|
||||
|
||||
// load from folder
|
||||
"/root/folder1/node_modules/file6/package.json",
|
||||
"/root/folder1/node_modules/file6/index.ts",
|
||||
"/root/folder1/node_modules/file6/index.tsx",
|
||||
"/root/folder1/node_modules/file6/index.d.ts",
|
||||
|
||||
"/root/folder1/node_modules/@types/file6.d.ts",
|
||||
|
||||
"/root/folder1/node_modules/@types/file6/package.json",
|
||||
"/root/folder1/node_modules/@types/file6.d.ts",
|
||||
"/root/folder1/node_modules/@types/file6/index.d.ts",
|
||||
|
||||
"/root/node_modules/file6/package.json",
|
||||
// success on /root/node_modules/file6.ts
|
||||
], /*isExternalLibraryImport*/ true);
|
||||
|
||||
|
||||
@@ -441,20 +441,20 @@ namespace ts {
|
||||
"======== Resolving module 'a' from 'file1.ts'. ========",
|
||||
"Explicitly specified module resolution kind: 'NodeJs'.",
|
||||
"Loading module 'a' from 'node_modules' folder, target file type 'TypeScript'.",
|
||||
"File 'node_modules/a/package.json' does not exist.",
|
||||
"File 'node_modules/a.ts' does not exist.",
|
||||
"File 'node_modules/a.tsx' does not exist.",
|
||||
"File 'node_modules/a.d.ts' does not exist.",
|
||||
"File 'node_modules/a/package.json' does not exist.",
|
||||
"File 'node_modules/a/index.ts' does not exist.",
|
||||
"File 'node_modules/a/index.tsx' does not exist.",
|
||||
"File 'node_modules/a/index.d.ts' does not exist.",
|
||||
"File 'node_modules/@types/a.d.ts' does not exist.",
|
||||
"File 'node_modules/@types/a/package.json' does not exist.",
|
||||
"File 'node_modules/@types/a.d.ts' does not exist.",
|
||||
"File 'node_modules/@types/a/index.d.ts' does not exist.",
|
||||
"Loading module 'a' from 'node_modules' folder, target file type 'JavaScript'.",
|
||||
"File 'node_modules/a/package.json' does not exist.",
|
||||
"File 'node_modules/a.js' does not exist.",
|
||||
"File 'node_modules/a.jsx' does not exist.",
|
||||
"File 'node_modules/a/package.json' does not exist.",
|
||||
"File 'node_modules/a/index.js' does not exist.",
|
||||
"File 'node_modules/a/index.jsx' does not exist.",
|
||||
"======== Module name 'a' was not resolved. ========"
|
||||
@@ -474,10 +474,10 @@ namespace ts {
|
||||
"======== Resolving module 'a' from 'file1.ts'. ========",
|
||||
"Explicitly specified module resolution kind: 'NodeJs'.",
|
||||
"Loading module 'a' from 'node_modules' folder, target file type 'TypeScript'.",
|
||||
"File 'node_modules/a/package.json' does not exist.",
|
||||
"File 'node_modules/a.ts' does not exist.",
|
||||
"File 'node_modules/a.tsx' does not exist.",
|
||||
"File 'node_modules/a.d.ts' does not exist.",
|
||||
"File 'node_modules/a/package.json' does not exist.",
|
||||
"File 'node_modules/a/index.ts' does not exist.",
|
||||
"File 'node_modules/a/index.tsx' does not exist.",
|
||||
"File 'node_modules/a/index.d.ts' exist - use it as a name resolution result.",
|
||||
@@ -510,14 +510,14 @@ namespace ts {
|
||||
"File '/fs.ts' does not exist.",
|
||||
"File '/fs.tsx' does not exist.",
|
||||
"File '/fs.d.ts' does not exist.",
|
||||
"File '/a/b/node_modules/@types/fs.d.ts' does not exist.",
|
||||
"File '/a/b/node_modules/@types/fs/package.json' does not exist.",
|
||||
"File '/a/b/node_modules/@types/fs.d.ts' does not exist.",
|
||||
"File '/a/b/node_modules/@types/fs/index.d.ts' does not exist.",
|
||||
"File '/a/node_modules/@types/fs.d.ts' does not exist.",
|
||||
"File '/a/node_modules/@types/fs/package.json' does not exist.",
|
||||
"File '/a/node_modules/@types/fs.d.ts' does not exist.",
|
||||
"File '/a/node_modules/@types/fs/index.d.ts' does not exist.",
|
||||
"File '/node_modules/@types/fs.d.ts' does not exist.",
|
||||
"File '/node_modules/@types/fs/package.json' does not exist.",
|
||||
"File '/node_modules/@types/fs.d.ts' does not exist.",
|
||||
"File '/node_modules/@types/fs/index.d.ts' does not exist.",
|
||||
"File '/a/b/fs.js' does not exist.",
|
||||
"File '/a/b/fs.jsx' does not exist.",
|
||||
@@ -552,14 +552,14 @@ namespace ts {
|
||||
"File '/fs.ts' does not exist.",
|
||||
"File '/fs.tsx' does not exist.",
|
||||
"File '/fs.d.ts' does not exist.",
|
||||
"File '/a/b/node_modules/@types/fs.d.ts' does not exist.",
|
||||
"File '/a/b/node_modules/@types/fs/package.json' does not exist.",
|
||||
"File '/a/b/node_modules/@types/fs.d.ts' does not exist.",
|
||||
"File '/a/b/node_modules/@types/fs/index.d.ts' does not exist.",
|
||||
"File '/a/node_modules/@types/fs.d.ts' does not exist.",
|
||||
"File '/a/node_modules/@types/fs/package.json' does not exist.",
|
||||
"File '/a/node_modules/@types/fs.d.ts' does not exist.",
|
||||
"File '/a/node_modules/@types/fs/index.d.ts' does not exist.",
|
||||
"File '/node_modules/@types/fs.d.ts' does not exist.",
|
||||
"File '/node_modules/@types/fs/package.json' does not exist.",
|
||||
"File '/node_modules/@types/fs.d.ts' does not exist.",
|
||||
"File '/node_modules/@types/fs/index.d.ts' does not exist.",
|
||||
"File '/a/b/fs.js' does not exist.",
|
||||
"File '/a/b/fs.jsx' does not exist.",
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace ts {
|
||||
|
||||
testBaseline("types", () => {
|
||||
return transformSourceFile(`let a: () => void`, [
|
||||
context => file => visitNode(file, function visitor(node: Node): VisitResult<Node> {
|
||||
context => file => visitNode(file, function visitor(node: Node): VisitResult<Node> {
|
||||
return visitEachChild(node, visitor, context);
|
||||
})
|
||||
]);
|
||||
@@ -91,14 +91,14 @@ namespace ts {
|
||||
class C { foo = 10; static bar = 20 }
|
||||
namespace C { export let x = 10; }
|
||||
`, {
|
||||
transformers: {
|
||||
before: [forceNamespaceRewrite],
|
||||
},
|
||||
compilerOptions: {
|
||||
target: ts.ScriptTarget.ESNext,
|
||||
newLine: NewLineKind.CarriageReturnLineFeed,
|
||||
}
|
||||
}).outputText;
|
||||
transformers: {
|
||||
before: [forceNamespaceRewrite],
|
||||
},
|
||||
compilerOptions: {
|
||||
target: ts.ScriptTarget.ESNext,
|
||||
newLine: NewLineKind.CarriageReturnLineFeed,
|
||||
}
|
||||
}).outputText;
|
||||
});
|
||||
|
||||
testBaseline("synthesizedClassAndNamespaceCombination", () => {
|
||||
@@ -138,6 +138,37 @@ namespace ts {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
testBaseline("transformAwayExportStar", () => {
|
||||
return ts.transpileModule("export * from './helper';", {
|
||||
transformers: {
|
||||
before: [expandExportStar],
|
||||
},
|
||||
compilerOptions: {
|
||||
target: ts.ScriptTarget.ESNext,
|
||||
newLine: NewLineKind.CarriageReturnLineFeed,
|
||||
}
|
||||
}).outputText;
|
||||
|
||||
function expandExportStar(context: ts.TransformationContext) {
|
||||
return (sourceFile: ts.SourceFile): ts.SourceFile => {
|
||||
return visitNode(sourceFile);
|
||||
|
||||
function visitNode<T extends ts.Node>(node: T): T {
|
||||
if (node.kind === ts.SyntaxKind.ExportDeclaration) {
|
||||
const ed = node as ts.Node as ts.ExportDeclaration;
|
||||
const exports = [{ name: "x" }];
|
||||
const exportSpecifiers = exports.map(e => ts.createExportSpecifier(e.name, e.name));
|
||||
const exportClause = ts.createNamedExports(exportSpecifiers);
|
||||
const newEd = ts.updateExportDeclaration(ed, ed.decorators, ed.modifiers, exportClause, ed.moduleSpecifier);
|
||||
|
||||
return newEd as ts.Node as T;
|
||||
}
|
||||
return ts.visitEachChild(node, visitNode, context);
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -2510,8 +2510,8 @@ namespace ts.projectSystem {
|
||||
"======== Module name 'lib' was not resolved. ========",
|
||||
`Auto discovery for typings is enabled in project '${proj.getProjectName()}'. Running extra resolution pass for module 'lib' using cache location '/a/cache'.`,
|
||||
"File '/a/cache/node_modules/lib.d.ts' does not exist.",
|
||||
"File '/a/cache/node_modules/@types/lib.d.ts' does not exist.",
|
||||
"File '/a/cache/node_modules/@types/lib/package.json' does not exist.",
|
||||
"File '/a/cache/node_modules/@types/lib.d.ts' does not exist.",
|
||||
"File '/a/cache/node_modules/@types/lib/index.d.ts' exist - use it as a name resolution result.",
|
||||
]);
|
||||
checkProjectActualFiles(proj, [file1.path, lib.path]);
|
||||
|
||||
Vendored
+1
-1
@@ -327,7 +327,7 @@ interface ObjectConstructor {
|
||||
* @param o Object that contains the property.
|
||||
* @param p Name of the property.
|
||||
*/
|
||||
getOwnPropertyDescriptor(o: any, propertyKey: PropertyKey): PropertyDescriptor;
|
||||
getOwnPropertyDescriptor(o: any, propertyKey: PropertyKey): PropertyDescriptor | undefined;
|
||||
|
||||
/**
|
||||
* Adds a property to an object, or modifies attributes of an existing property.
|
||||
|
||||
Vendored
+1
-1
@@ -4,7 +4,7 @@ declare namespace Reflect {
|
||||
function defineProperty(target: object, propertyKey: PropertyKey, attributes: PropertyDescriptor): boolean;
|
||||
function deleteProperty(target: object, propertyKey: PropertyKey): boolean;
|
||||
function get(target: object, propertyKey: PropertyKey, receiver?: any): any;
|
||||
function getOwnPropertyDescriptor(target: object, propertyKey: PropertyKey): PropertyDescriptor;
|
||||
function getOwnPropertyDescriptor(target: object, propertyKey: PropertyKey): PropertyDescriptor | undefined;
|
||||
function getPrototypeOf(target: object): object;
|
||||
function has(target: object, propertyKey: PropertyKey): boolean;
|
||||
function isExtensible(target: object): boolean;
|
||||
|
||||
Vendored
+6
@@ -22,4 +22,10 @@ interface ObjectConstructor {
|
||||
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
|
||||
*/
|
||||
entries(o: any): [string, any][];
|
||||
|
||||
/**
|
||||
* Returns an object containing all own property descriptors of an object
|
||||
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
|
||||
*/
|
||||
getOwnPropertyDescriptors<T>(o: T): {[P in keyof T]: TypedPropertyDescriptor<T[P]>} & { [x: string]: PropertyDescriptor };
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -127,7 +127,7 @@ interface ObjectConstructor {
|
||||
* @param o Object that contains the property.
|
||||
* @param p Name of the property.
|
||||
*/
|
||||
getOwnPropertyDescriptor(o: any, p: string): PropertyDescriptor;
|
||||
getOwnPropertyDescriptor(o: any, p: string): PropertyDescriptor | undefined;
|
||||
|
||||
/**
|
||||
* Returns the names of the own properties of an object. The own properties of an object are those that are defined directly
|
||||
|
||||
@@ -1686,11 +1686,13 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
private closeConfiguredProject(configFile: NormalizedPath): void {
|
||||
private closeConfiguredProject(configFile: NormalizedPath): boolean {
|
||||
const configuredProject = this.findConfiguredProjectByProjectName(configFile);
|
||||
if (configuredProject && configuredProject.deleteOpenRef() === 0) {
|
||||
this.removeProject(configuredProject);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
closeExternalProject(uncheckedFileName: string, suppressRefresh = false): void {
|
||||
|
||||
+20
-21
@@ -547,33 +547,32 @@ namespace ts.server {
|
||||
this.cachedUnresolvedImportsPerFile.remove(file);
|
||||
}
|
||||
|
||||
// 1. no changes in structure, no changes in unresolved imports - do nothing
|
||||
// 2. no changes in structure, unresolved imports were changed - collect unresolved imports for all files
|
||||
// (can reuse cached imports for files that were not changed)
|
||||
// 3. new files were added/removed, but compilation settings stays the same - collect unresolved imports for all new/modified files
|
||||
// (can reuse cached imports for files that were not changed)
|
||||
// 4. compilation settings were changed in the way that might affect module resolution - drop all caches and collect all data from the scratch
|
||||
let unresolvedImports: SortedReadonlyArray<string>;
|
||||
if (hasChanges || changedFiles.length) {
|
||||
const result: string[] = [];
|
||||
for (const sourceFile of this.program.getSourceFiles()) {
|
||||
this.extractUnresolvedImportsFromSourceFile(sourceFile, result);
|
||||
}
|
||||
this.lastCachedUnresolvedImportsList = toDeduplicatedSortedArray(result);
|
||||
}
|
||||
unresolvedImports = this.lastCachedUnresolvedImportsList;
|
||||
|
||||
const cachedTypings = this.projectService.typingsCache.getTypingsForProject(this, unresolvedImports, hasChanges);
|
||||
if (this.setTypings(cachedTypings)) {
|
||||
hasChanges = this.updateGraphWorker() || hasChanges;
|
||||
}
|
||||
|
||||
// update builder only if language service is enabled
|
||||
// otherwise tell it to drop its internal state
|
||||
if (this.languageServiceEnabled) {
|
||||
// 1. no changes in structure, no changes in unresolved imports - do nothing
|
||||
// 2. no changes in structure, unresolved imports were changed - collect unresolved imports for all files
|
||||
// (can reuse cached imports for files that were not changed)
|
||||
// 3. new files were added/removed, but compilation settings stays the same - collect unresolved imports for all new/modified files
|
||||
// (can reuse cached imports for files that were not changed)
|
||||
// 4. compilation settings were changed in the way that might affect module resolution - drop all caches and collect all data from the scratch
|
||||
if (hasChanges || changedFiles.length) {
|
||||
const result: string[] = [];
|
||||
for (const sourceFile of this.program.getSourceFiles()) {
|
||||
this.extractUnresolvedImportsFromSourceFile(sourceFile, result);
|
||||
}
|
||||
this.lastCachedUnresolvedImportsList = toDeduplicatedSortedArray(result);
|
||||
}
|
||||
|
||||
const cachedTypings = this.projectService.typingsCache.getTypingsForProject(this, this.lastCachedUnresolvedImportsList, hasChanges);
|
||||
if (this.setTypings(cachedTypings)) {
|
||||
hasChanges = this.updateGraphWorker() || hasChanges;
|
||||
}
|
||||
|
||||
this.builder.onProjectUpdateGraph();
|
||||
}
|
||||
else {
|
||||
this.lastCachedUnresolvedImportsList = undefined;
|
||||
this.builder.clear();
|
||||
}
|
||||
|
||||
|
||||
@@ -466,7 +466,7 @@ namespace ts.server.protocol {
|
||||
* Represents a single refactoring action - for example, the "Extract Method..." refactor might
|
||||
* offer several actions, each corresponding to a surround class or closure to extract into.
|
||||
*/
|
||||
export type RefactorActionInfo = {
|
||||
export interface RefactorActionInfo {
|
||||
/**
|
||||
* The programmatic name of the refactoring action
|
||||
*/
|
||||
@@ -478,7 +478,7 @@ namespace ts.server.protocol {
|
||||
* so this description should make sense by itself if the parent is inlineable=true
|
||||
*/
|
||||
description: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface GetEditsForRefactorRequest extends Request {
|
||||
command: CommandTypes.GetEditsForRefactor;
|
||||
@@ -501,7 +501,7 @@ namespace ts.server.protocol {
|
||||
body?: RefactorEditInfo;
|
||||
}
|
||||
|
||||
export type RefactorEditInfo = {
|
||||
export interface RefactorEditInfo {
|
||||
edits: FileCodeEdits[];
|
||||
|
||||
/**
|
||||
@@ -510,7 +510,7 @@ namespace ts.server.protocol {
|
||||
*/
|
||||
renameLocation?: Location;
|
||||
renameFilename?: string;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Request for the available codefixes at a specific position.
|
||||
|
||||
+62
-5
@@ -236,25 +236,40 @@ namespace ts.server {
|
||||
return `${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}.${d.getMilliseconds()}`;
|
||||
}
|
||||
|
||||
interface QueuedOperation {
|
||||
operationId: string;
|
||||
operation: () => void;
|
||||
}
|
||||
|
||||
class NodeTypingsInstaller implements ITypingsInstaller {
|
||||
private installer: NodeChildProcess;
|
||||
private installerPidReported = false;
|
||||
private socket: NodeSocket;
|
||||
private projectService: ProjectService;
|
||||
private throttledOperations: ThrottledOperations;
|
||||
private eventSender: EventSender;
|
||||
private activeRequestCount = 0;
|
||||
private requestQueue: QueuedOperation[] = [];
|
||||
private requestMap = createMap<QueuedOperation>(); // Maps operation ID to newest requestQueue entry with that ID
|
||||
|
||||
// This number is essentially arbitrary. Processing more than one typings request
|
||||
// at a time makes sense, but having too many in the pipe results in a hang
|
||||
// (see https://github.com/nodejs/node/issues/7657).
|
||||
// It would be preferable to base our limit on the amount of space left in the
|
||||
// buffer, but we have yet to find a way to retrieve that value.
|
||||
private static readonly maxActiveRequestCount = 10;
|
||||
private static readonly requestDelayMillis = 100;
|
||||
|
||||
|
||||
constructor(
|
||||
private readonly telemetryEnabled: boolean,
|
||||
private readonly logger: server.Logger,
|
||||
host: ServerHost,
|
||||
private readonly host: ServerHost,
|
||||
eventPort: number,
|
||||
readonly globalTypingsCacheLocation: string,
|
||||
readonly typingSafeListLocation: string,
|
||||
readonly typesMapLocation: string,
|
||||
private readonly npmLocation: string | undefined,
|
||||
private newLine: string) {
|
||||
this.throttledOperations = new ThrottledOperations(host);
|
||||
if (eventPort) {
|
||||
const s = net.connect({ port: eventPort }, () => {
|
||||
this.socket = s;
|
||||
@@ -338,12 +353,26 @@ namespace ts.server {
|
||||
this.logger.info(`Scheduling throttled operation: ${JSON.stringify(request)}`);
|
||||
}
|
||||
}
|
||||
this.throttledOperations.schedule(project.getProjectName(), /*ms*/ 250, () => {
|
||||
|
||||
const operationId = project.getProjectName();
|
||||
const operation = () => {
|
||||
if (this.logger.hasLevel(LogLevel.verbose)) {
|
||||
this.logger.info(`Sending request: ${JSON.stringify(request)}`);
|
||||
}
|
||||
this.installer.send(request);
|
||||
});
|
||||
};
|
||||
const queuedRequest: QueuedOperation = { operationId, operation };
|
||||
|
||||
if (this.activeRequestCount < NodeTypingsInstaller.maxActiveRequestCount) {
|
||||
this.scheduleRequest(queuedRequest);
|
||||
}
|
||||
else {
|
||||
if (this.logger.hasLevel(LogLevel.verbose)) {
|
||||
this.logger.info(`Deferring request for: ${operationId}`);
|
||||
}
|
||||
this.requestQueue.push(queuedRequest);
|
||||
this.requestMap.set(operationId, queuedRequest);
|
||||
}
|
||||
}
|
||||
|
||||
private handleMessage(response: SetTypings | InvalidateCachedTypings | BeginInstallTypes | EndInstallTypes | InitializationFailedResponse) {
|
||||
@@ -404,11 +433,39 @@ namespace ts.server {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.activeRequestCount > 0) {
|
||||
this.activeRequestCount--;
|
||||
}
|
||||
else {
|
||||
Debug.fail("Received too many responses");
|
||||
}
|
||||
|
||||
while (this.requestQueue.length > 0) {
|
||||
const queuedRequest = this.requestQueue.shift();
|
||||
if (this.requestMap.get(queuedRequest.operationId) === queuedRequest) {
|
||||
this.requestMap.delete(queuedRequest.operationId);
|
||||
this.scheduleRequest(queuedRequest);
|
||||
break;
|
||||
}
|
||||
|
||||
if (this.logger.hasLevel(LogLevel.verbose)) {
|
||||
this.logger.info(`Skipping defunct request for: ${queuedRequest.operationId}`);
|
||||
}
|
||||
}
|
||||
|
||||
this.projectService.updateTypingsForProject(response);
|
||||
if (response.kind === ActionSet && this.socket) {
|
||||
this.sendEvent(0, "setTypings", response);
|
||||
}
|
||||
}
|
||||
|
||||
private scheduleRequest(request: QueuedOperation) {
|
||||
if (this.logger.hasLevel(LogLevel.verbose)) {
|
||||
this.logger.info(`Scheduling request for: ${request.operationId}`);
|
||||
}
|
||||
this.activeRequestCount++;
|
||||
this.host.setTimeout(request.operation, NodeTypingsInstaller.requestDelayMillis);
|
||||
}
|
||||
}
|
||||
|
||||
class IOSession extends Session {
|
||||
|
||||
@@ -73,12 +73,12 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
|
||||
export type RequestCompletedAction = (success: boolean) => void;
|
||||
type PendingRequest = {
|
||||
interface PendingRequest {
|
||||
requestId: number;
|
||||
args: string[];
|
||||
cwd: string;
|
||||
onRequestCompleted: RequestCompletedAction;
|
||||
};
|
||||
}
|
||||
|
||||
export abstract class TypingsInstaller {
|
||||
private readonly packageNameToTypingLocation: Map<string> = createMap<string>();
|
||||
|
||||
@@ -179,6 +179,12 @@ namespace ts.server {
|
||||
constructor(private readonly host: ServerHost) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait `number` milliseconds and then invoke `cb`. If, while waiting, schedule
|
||||
* is called again with the same `operationId`, cancel this operation in favor
|
||||
* of the new one. (Note that the amount of time the canceled operation had been
|
||||
* waiting does not affect the amount of time that the new operation waits.)
|
||||
*/
|
||||
public schedule(operationId: string, delay: number, cb: () => void) {
|
||||
const pendingTimeout = this.pendingTimeouts.get(operationId);
|
||||
if (pendingTimeout) {
|
||||
|
||||
@@ -699,7 +699,8 @@ namespace ts {
|
||||
// specially.
|
||||
const docCommentAndDiagnostics = parseIsolatedJSDocComment(sourceFile.text, start, width);
|
||||
if (docCommentAndDiagnostics && docCommentAndDiagnostics.jsDoc) {
|
||||
docCommentAndDiagnostics.jsDoc.parent = token;
|
||||
// TODO: This should be predicated on `token["kind"]` being compatible with `HasJSDoc["kind"]`
|
||||
docCommentAndDiagnostics.jsDoc.parent = token as HasJSDoc;
|
||||
classifyJSDocComment(docCommentAndDiagnostics.jsDoc);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace ts.codefix {
|
||||
const replacement = createIndexedAccessTypeNode(
|
||||
createTypeReferenceNode(qualifiedName.left, /*typeArguments*/ undefined),
|
||||
createLiteralTypeNode(createLiteral(rightText)));
|
||||
const changeTracker = textChanges.ChangeTracker.fromCodeFixContext(context);
|
||||
const changeTracker = textChanges.ChangeTracker.fromContext(context);
|
||||
changeTracker.replaceNode(sourceFile, qualifiedName, replacement);
|
||||
|
||||
return [{
|
||||
|
||||
@@ -87,7 +87,7 @@ namespace ts.codefix {
|
||||
createPropertyAccess(createIdentifier(className), tokenName),
|
||||
createIdentifier("undefined")));
|
||||
|
||||
const staticInitializationChangeTracker = textChanges.ChangeTracker.fromCodeFixContext(context);
|
||||
const staticInitializationChangeTracker = textChanges.ChangeTracker.fromContext(context);
|
||||
staticInitializationChangeTracker.insertNodeAfter(
|
||||
classDeclarationSourceFile,
|
||||
classDeclaration,
|
||||
@@ -111,7 +111,7 @@ namespace ts.codefix {
|
||||
createPropertyAccess(createThis(), tokenName),
|
||||
createIdentifier("undefined")));
|
||||
|
||||
const propertyInitializationChangeTracker = textChanges.ChangeTracker.fromCodeFixContext(context);
|
||||
const propertyInitializationChangeTracker = textChanges.ChangeTracker.fromContext(context);
|
||||
propertyInitializationChangeTracker.insertNodeAt(
|
||||
classDeclarationSourceFile,
|
||||
classConstructor.body.getEnd() - 1,
|
||||
@@ -153,7 +153,7 @@ namespace ts.codefix {
|
||||
/*questionToken*/ undefined,
|
||||
typeNode,
|
||||
/*initializer*/ undefined);
|
||||
const propertyChangeTracker = textChanges.ChangeTracker.fromCodeFixContext(context);
|
||||
const propertyChangeTracker = textChanges.ChangeTracker.fromContext(context);
|
||||
propertyChangeTracker.insertNodeAfter(classDeclarationSourceFile, classOpenBrace, property, { suffix: context.newLineCharacter });
|
||||
|
||||
(actions || (actions = [])).push({
|
||||
@@ -178,7 +178,7 @@ namespace ts.codefix {
|
||||
[indexingParameter],
|
||||
typeNode);
|
||||
|
||||
const indexSignatureChangeTracker = textChanges.ChangeTracker.fromCodeFixContext(context);
|
||||
const indexSignatureChangeTracker = textChanges.ChangeTracker.fromContext(context);
|
||||
indexSignatureChangeTracker.insertNodeAfter(classDeclarationSourceFile, classOpenBrace, indexSignature, { suffix: context.newLineCharacter });
|
||||
|
||||
actions.push({
|
||||
@@ -195,7 +195,7 @@ namespace ts.codefix {
|
||||
const callExpression = <CallExpression>token.parent.parent;
|
||||
const methodDeclaration = createMethodFromCallExpression(callExpression, tokenName, includeTypeScriptSyntax, makeStatic);
|
||||
|
||||
const methodDeclarationChangeTracker = textChanges.ChangeTracker.fromCodeFixContext(context);
|
||||
const methodDeclarationChangeTracker = textChanges.ChangeTracker.fromContext(context);
|
||||
methodDeclarationChangeTracker.insertNodeAfter(classDeclarationSourceFile, classOpenBrace, methodDeclaration, { suffix: context.newLineCharacter });
|
||||
return {
|
||||
description: formatStringFromArgs(getLocaleSpecificMessage(makeStatic ?
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace ts.codefix {
|
||||
}
|
||||
}
|
||||
}
|
||||
const changeTracker = textChanges.ChangeTracker.fromCodeFixContext(context);
|
||||
const changeTracker = textChanges.ChangeTracker.fromContext(context);
|
||||
changeTracker.insertNodeAfter(sourceFile, getOpenBrace(<ConstructorDeclaration>constructor, sourceFile), superCall, { suffix: context.newLineCharacter });
|
||||
changeTracker.deleteNode(sourceFile, superCall);
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace ts.codefix {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const changeTracker = textChanges.ChangeTracker.fromCodeFixContext(context);
|
||||
const changeTracker = textChanges.ChangeTracker.fromContext(context);
|
||||
const superCall = createStatement(createCall(createSuper(), /*typeArguments*/ undefined, /*argumentsArray*/ emptyArray));
|
||||
changeTracker.insertNodeAfter(sourceFile, getOpenBrace(<ConstructorDeclaration>token.parent, sourceFile), superCall, { suffix: context.newLineCharacter });
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace ts.codefix {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const changeTracker = textChanges.ChangeTracker.fromCodeFixContext(context);
|
||||
const changeTracker = textChanges.ChangeTracker.fromContext(context);
|
||||
changeTracker.replaceNode(sourceFile, extendsToken, createToken(SyntaxKind.ImplementsKeyword));
|
||||
|
||||
// We replace existing keywords with commas.
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace ts.codefix {
|
||||
if (token.kind !== SyntaxKind.Identifier) {
|
||||
return undefined;
|
||||
}
|
||||
const changeTracker = textChanges.ChangeTracker.fromCodeFixContext(context);
|
||||
const changeTracker = textChanges.ChangeTracker.fromContext(context);
|
||||
changeTracker.replaceNode(sourceFile, token, createPropertyAccess(createThis(), <Identifier>token));
|
||||
|
||||
return [{
|
||||
|
||||
@@ -8,11 +8,32 @@ namespace ts.codefix {
|
||||
function getActionsForJSDocTypes(context: CodeFixContext): CodeAction[] | undefined {
|
||||
const sourceFile = context.sourceFile;
|
||||
const node = getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false);
|
||||
const decl = ts.findAncestor(node, n => n.kind === SyntaxKind.VariableDeclaration);
|
||||
|
||||
// NOTE: Some locations are not handled yet:
|
||||
// MappedTypeNode.typeParameters and SignatureDeclaration.typeParameters, as well as CallExpression.typeArguments
|
||||
const decl = ts.findAncestor(node,
|
||||
n =>
|
||||
n.kind === SyntaxKind.AsExpression ||
|
||||
n.kind === SyntaxKind.CallSignature ||
|
||||
n.kind === SyntaxKind.ConstructSignature ||
|
||||
n.kind === SyntaxKind.FunctionDeclaration ||
|
||||
n.kind === SyntaxKind.GetAccessor ||
|
||||
n.kind === SyntaxKind.IndexSignature ||
|
||||
n.kind === SyntaxKind.MappedType ||
|
||||
n.kind === SyntaxKind.MethodDeclaration ||
|
||||
n.kind === SyntaxKind.MethodSignature ||
|
||||
n.kind === SyntaxKind.Parameter ||
|
||||
n.kind === SyntaxKind.PropertyDeclaration ||
|
||||
n.kind === SyntaxKind.PropertySignature ||
|
||||
n.kind === SyntaxKind.SetAccessor ||
|
||||
n.kind === SyntaxKind.TypeAliasDeclaration ||
|
||||
n.kind === SyntaxKind.TypeAssertionExpression ||
|
||||
n.kind === SyntaxKind.VariableDeclaration);
|
||||
if (!decl) return;
|
||||
const checker = context.program.getTypeChecker();
|
||||
|
||||
const jsdocType = (decl as VariableDeclaration).type;
|
||||
if (!jsdocType) return;
|
||||
const original = getTextOfNode(jsdocType);
|
||||
const type = checker.getTypeFromTypeNode(jsdocType);
|
||||
const actions = [createAction(jsdocType, sourceFile.fileName, original, checker.typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.NoTruncation))];
|
||||
|
||||
@@ -175,23 +175,23 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
function deleteNode(n: Node) {
|
||||
return makeChange(textChanges.ChangeTracker.fromCodeFixContext(context).deleteNode(sourceFile, n));
|
||||
return makeChange(textChanges.ChangeTracker.fromContext(context).deleteNode(sourceFile, n));
|
||||
}
|
||||
|
||||
function deleteRange(range: TextRange) {
|
||||
return makeChange(textChanges.ChangeTracker.fromCodeFixContext(context).deleteRange(sourceFile, range));
|
||||
return makeChange(textChanges.ChangeTracker.fromContext(context).deleteRange(sourceFile, range));
|
||||
}
|
||||
|
||||
function deleteNodeInList(n: Node) {
|
||||
return makeChange(textChanges.ChangeTracker.fromCodeFixContext(context).deleteNodeInList(sourceFile, n));
|
||||
return makeChange(textChanges.ChangeTracker.fromContext(context).deleteNodeInList(sourceFile, n));
|
||||
}
|
||||
|
||||
function deleteNodeRange(start: Node, end: Node) {
|
||||
return makeChange(textChanges.ChangeTracker.fromCodeFixContext(context).deleteNodeRange(sourceFile, start, end));
|
||||
return makeChange(textChanges.ChangeTracker.fromContext(context).deleteNodeRange(sourceFile, start, end));
|
||||
}
|
||||
|
||||
function replaceNode(n: Node, newNode: Node) {
|
||||
return makeChange(textChanges.ChangeTracker.fromCodeFixContext(context).replaceNode(sourceFile, n, newNode));
|
||||
return makeChange(textChanges.ChangeTracker.fromContext(context).replaceNode(sourceFile, n, newNode));
|
||||
}
|
||||
|
||||
function makeChange(changeTracker: textChanges.ChangeTracker): CodeAction {
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace ts.codefix {
|
||||
export function newNodesToChanges(newNodes: Node[], insertAfter: Node, context: CodeFixContext) {
|
||||
const sourceFile = context.sourceFile;
|
||||
|
||||
const changeTracker = textChanges.ChangeTracker.fromCodeFixContext(context);
|
||||
const changeTracker = textChanges.ChangeTracker.fromContext(context);
|
||||
|
||||
for (const newNode of newNodes) {
|
||||
changeTracker.insertNodeAfter(sourceFile, insertAfter, newNode, { suffix: context.newLineCharacter });
|
||||
|
||||
@@ -692,7 +692,7 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
function createChangeTracker() {
|
||||
return textChanges.ChangeTracker.fromCodeFixContext(context);
|
||||
return textChanges.ChangeTracker.fromContext(context);
|
||||
}
|
||||
|
||||
function createCodeAction(
|
||||
|
||||
+29
-21
@@ -24,7 +24,7 @@ namespace ts.Completions {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, request, keywordFilters } = completionData;
|
||||
const { symbols, isGlobalCompletion, isMemberCompletion, allowStringLiteral, isNewIdentifierLocation, location, request, keywordFilters } = completionData;
|
||||
|
||||
if (sourceFile.languageVariant === LanguageVariant.JSX &&
|
||||
location && location.parent && location.parent.kind === SyntaxKind.JsxClosingElement) {
|
||||
@@ -56,7 +56,7 @@ namespace ts.Completions {
|
||||
const entries: CompletionEntry[] = [];
|
||||
|
||||
if (isSourceFileJavaScript(sourceFile)) {
|
||||
const uniqueNames = getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ true, typeChecker, compilerOptions.target, log);
|
||||
const uniqueNames = getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ true, typeChecker, compilerOptions.target, log, allowStringLiteral);
|
||||
getJavaScriptCompletionEntries(sourceFile, location.pos, uniqueNames, compilerOptions.target, entries);
|
||||
}
|
||||
else {
|
||||
@@ -64,7 +64,7 @@ namespace ts.Completions {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ true, typeChecker, compilerOptions.target, log);
|
||||
getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ true, typeChecker, compilerOptions.target, log, allowStringLiteral);
|
||||
}
|
||||
|
||||
// TODO add filter for keyword based on type/value/namespace and also location
|
||||
@@ -97,7 +97,7 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
uniqueNames.set(realName, true);
|
||||
const displayName = getCompletionEntryDisplayName(realName, target, /*performCharacterChecks*/ true);
|
||||
const displayName = getCompletionEntryDisplayName(realName, target, /*performCharacterChecks*/ true, /*allowStringLiteral*/ false);
|
||||
if (displayName) {
|
||||
entries.push({
|
||||
name: displayName,
|
||||
@@ -109,11 +109,11 @@ namespace ts.Completions {
|
||||
});
|
||||
}
|
||||
|
||||
function createCompletionEntry(symbol: Symbol, location: Node, performCharacterChecks: boolean, typeChecker: TypeChecker, target: ScriptTarget): CompletionEntry {
|
||||
function createCompletionEntry(symbol: Symbol, location: Node, performCharacterChecks: boolean, typeChecker: TypeChecker, target: ScriptTarget, allowStringLiteral: boolean): CompletionEntry {
|
||||
// Try to get a valid display name for this symbol, if we could not find one, then ignore it.
|
||||
// We would like to only show things that can be added after a dot, so for instance numeric properties can
|
||||
// not be accessed with a dot (a.1 <- invalid)
|
||||
const displayName = getCompletionEntryDisplayNameForSymbol(symbol, target, performCharacterChecks);
|
||||
const displayName = getCompletionEntryDisplayNameForSymbol(symbol, target, performCharacterChecks, allowStringLiteral);
|
||||
if (!displayName) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -134,12 +134,12 @@ namespace ts.Completions {
|
||||
};
|
||||
}
|
||||
|
||||
function getCompletionEntriesFromSymbols(symbols: Symbol[], entries: Push<CompletionEntry>, location: Node, performCharacterChecks: boolean, typeChecker: TypeChecker, target: ScriptTarget, log: Log): Map<true> {
|
||||
function getCompletionEntriesFromSymbols(symbols: Symbol[], entries: Push<CompletionEntry>, location: Node, performCharacterChecks: boolean, typeChecker: TypeChecker, target: ScriptTarget, log: Log, allowStringLiteral: boolean): Map<true> {
|
||||
const start = timestamp();
|
||||
const uniqueNames = createMap<true>();
|
||||
if (symbols) {
|
||||
for (const symbol of symbols) {
|
||||
const entry = createCompletionEntry(symbol, location, performCharacterChecks, typeChecker, target);
|
||||
const entry = createCompletionEntry(symbol, location, performCharacterChecks, typeChecker, target, allowStringLiteral);
|
||||
if (entry) {
|
||||
const id = entry.name;
|
||||
if (!uniqueNames.has(id)) {
|
||||
@@ -224,7 +224,7 @@ namespace ts.Completions {
|
||||
const type = typeChecker.getContextualType((<ObjectLiteralExpression>element.parent));
|
||||
const entries: CompletionEntry[] = [];
|
||||
if (type) {
|
||||
getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, element, /*performCharacterChecks*/ false, typeChecker, target, log);
|
||||
getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, element, /*performCharacterChecks*/ false, typeChecker, target, log, /*allowStringLiteral*/ true);
|
||||
if (entries.length) {
|
||||
return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: true, entries };
|
||||
}
|
||||
@@ -253,7 +253,7 @@ namespace ts.Completions {
|
||||
const type = typeChecker.getTypeAtLocation(node.expression);
|
||||
const entries: CompletionEntry[] = [];
|
||||
if (type) {
|
||||
getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, node, /*performCharacterChecks*/ false, typeChecker, target, log);
|
||||
getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, node, /*performCharacterChecks*/ false, typeChecker, target, log, /*allowStringLiteral*/ true);
|
||||
if (entries.length) {
|
||||
return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: true, entries };
|
||||
}
|
||||
@@ -284,7 +284,7 @@ namespace ts.Completions {
|
||||
addStringLiteralCompletionsFromType(t, result, typeChecker, uniques);
|
||||
}
|
||||
}
|
||||
else if (type.flags & TypeFlags.StringLiteral) {
|
||||
else if (type.flags & TypeFlags.StringLiteral && !(type.flags & TypeFlags.EnumLiteral)) {
|
||||
const name = (<StringLiteralType>type).value;
|
||||
if (!uniques.has(name)) {
|
||||
uniques.set(name, true);
|
||||
@@ -302,13 +302,13 @@ namespace ts.Completions {
|
||||
// Compute all the completion symbols again.
|
||||
const completionData = getCompletionData(typeChecker, log, sourceFile, position);
|
||||
if (completionData) {
|
||||
const { symbols, location } = completionData;
|
||||
const { symbols, location, allowStringLiteral } = completionData;
|
||||
|
||||
// Find the symbol with the matching entry name.
|
||||
// We don't need to perform character checks here because we're only comparing the
|
||||
// name against 'entryName' (which is known to be good), not building a new
|
||||
// completion entry.
|
||||
const symbol = forEach(symbols, s => getCompletionEntryDisplayNameForSymbol(s, compilerOptions.target, /*performCharacterChecks*/ false) === entryName ? s : undefined);
|
||||
const symbol = forEach(symbols, s => getCompletionEntryDisplayNameForSymbol(s, compilerOptions.target, /*performCharacterChecks*/ false, allowStringLiteral) === entryName ? s : undefined);
|
||||
|
||||
if (symbol) {
|
||||
const { displayParts, documentation, symbolKind, tags } = SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, location, location, SemanticMeaning.All);
|
||||
@@ -345,17 +345,22 @@ namespace ts.Completions {
|
||||
export function getCompletionEntrySymbol(typeChecker: TypeChecker, log: (message: string) => void, compilerOptions: CompilerOptions, sourceFile: SourceFile, position: number, entryName: string): Symbol | undefined {
|
||||
// Compute all the completion symbols again.
|
||||
const completionData = getCompletionData(typeChecker, log, sourceFile, position);
|
||||
if (!completionData) {
|
||||
return undefined;
|
||||
}
|
||||
const { symbols, allowStringLiteral } = completionData;
|
||||
// Find the symbol with the matching entry name.
|
||||
// We don't need to perform character checks here because we're only comparing the
|
||||
// name against 'entryName' (which is known to be good), not building a new
|
||||
// completion entry.
|
||||
return completionData && forEach(completionData.symbols, s => getCompletionEntryDisplayNameForSymbol(s, compilerOptions.target, /*performCharacterChecks*/ false) === entryName ? s : undefined);
|
||||
return forEach(symbols, s => getCompletionEntryDisplayNameForSymbol(s, compilerOptions.target, /*performCharacterChecks*/ false, allowStringLiteral) === entryName ? s : undefined);
|
||||
}
|
||||
|
||||
interface CompletionData {
|
||||
symbols: Symbol[];
|
||||
isGlobalCompletion: boolean;
|
||||
isMemberCompletion: boolean;
|
||||
allowStringLiteral: boolean;
|
||||
isNewIdentifierLocation: boolean;
|
||||
location: Node;
|
||||
isRightOfDot: boolean;
|
||||
@@ -436,7 +441,7 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
if (request) {
|
||||
return { symbols: undefined, isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, request, keywordFilters: KeywordCompletionFilters.None };
|
||||
return { symbols: undefined, isGlobalCompletion: false, isMemberCompletion: false, allowStringLiteral: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, request, keywordFilters: KeywordCompletionFilters.None };
|
||||
}
|
||||
|
||||
if (!insideJsDocTagTypeExpression) {
|
||||
@@ -534,6 +539,7 @@ namespace ts.Completions {
|
||||
const semanticStart = timestamp();
|
||||
let isGlobalCompletion = false;
|
||||
let isMemberCompletion: boolean;
|
||||
let allowStringLiteral = false;
|
||||
let isNewIdentifierLocation: boolean;
|
||||
let keywordFilters = KeywordCompletionFilters.None;
|
||||
let symbols: Symbol[] = [];
|
||||
@@ -573,7 +579,7 @@ namespace ts.Completions {
|
||||
|
||||
log("getCompletionData: Semantic work: " + (timestamp() - semanticStart));
|
||||
|
||||
return { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), request, keywordFilters };
|
||||
return { symbols, isGlobalCompletion, isMemberCompletion, allowStringLiteral, isNewIdentifierLocation, location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), request, keywordFilters };
|
||||
|
||||
type JSDocTagWithTypeExpression = JSDocAugmentsTag | JSDocParameterTag | JSDocPropertyTag | JSDocReturnTag | JSDocTypeTag | JSDocTypedefTag;
|
||||
|
||||
@@ -961,6 +967,7 @@ namespace ts.Completions {
|
||||
function tryGetObjectLikeCompletionSymbols(objectLikeContainer: ObjectLiteralExpression | ObjectBindingPattern): boolean {
|
||||
// We're looking up possible property names from contextual/inferred/declared type.
|
||||
isMemberCompletion = true;
|
||||
allowStringLiteral = true;
|
||||
|
||||
let typeMembers: Symbol[];
|
||||
let existingMembers: ReadonlyArray<Declaration>;
|
||||
@@ -1609,7 +1616,7 @@ namespace ts.Completions {
|
||||
*
|
||||
* @return undefined if the name is of external module
|
||||
*/
|
||||
function getCompletionEntryDisplayNameForSymbol(symbol: Symbol, target: ScriptTarget, performCharacterChecks: boolean): string | undefined {
|
||||
function getCompletionEntryDisplayNameForSymbol(symbol: Symbol, target: ScriptTarget, performCharacterChecks: boolean, allowStringLiteral: boolean): string | undefined {
|
||||
const name = symbol.name;
|
||||
if (!name) return undefined;
|
||||
|
||||
@@ -1623,20 +1630,21 @@ namespace ts.Completions {
|
||||
}
|
||||
}
|
||||
|
||||
return getCompletionEntryDisplayName(name, target, performCharacterChecks);
|
||||
return getCompletionEntryDisplayName(name, target, performCharacterChecks, allowStringLiteral);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a displayName from a given for completion list, performing any necessary quotes stripping
|
||||
* and checking whether the name is valid identifier name.
|
||||
*/
|
||||
function getCompletionEntryDisplayName(name: string, target: ScriptTarget, performCharacterChecks: boolean): string {
|
||||
function getCompletionEntryDisplayName(name: string, target: ScriptTarget, performCharacterChecks: boolean, allowStringLiteral: boolean): string {
|
||||
// If the user entered name for the symbol was quoted, removing the quotes is not enough, as the name could be an
|
||||
// invalid identifier name. We need to check if whatever was inside the quotes is actually a valid identifier name.
|
||||
// e.g "b a" is valid quoted name but when we strip off the quotes, it is invalid.
|
||||
// We, thus, need to check if whatever was inside the quotes is actually a valid identifier name.
|
||||
if (performCharacterChecks && !isIdentifierText(name, target)) {
|
||||
return undefined;
|
||||
// TODO: GH#18169
|
||||
return allowStringLiteral ? JSON.stringify(name) : undefined;
|
||||
}
|
||||
|
||||
return name;
|
||||
@@ -1731,7 +1739,7 @@ namespace ts.Completions {
|
||||
|
||||
/** Get the corresponding JSDocTag node if the position is in a jsDoc comment */
|
||||
function getJsDocTagAtPosition(node: Node, position: number): JSDocTag | undefined {
|
||||
const { jsDoc } = getJsDocHavingNode(node);
|
||||
const { jsDoc } = getJsDocHavingNode(node) as JSDocContainer;
|
||||
if (!jsDoc) return undefined;
|
||||
|
||||
for (const { pos, end, tags } of jsDoc) {
|
||||
|
||||
@@ -176,7 +176,9 @@ namespace ts.FindAllReferences {
|
||||
fileName: node.getSourceFile().fileName,
|
||||
textSpan: getTextSpan(node),
|
||||
isWriteAccess: isWriteAccess(node),
|
||||
isDefinition: isAnyDeclarationName(node) || isLiteralComputedPropertyDeclarationName(node),
|
||||
isDefinition: node.kind === SyntaxKind.DefaultKeyword
|
||||
|| isAnyDeclarationName(node)
|
||||
|| isLiteralComputedPropertyDeclarationName(node),
|
||||
isInString
|
||||
};
|
||||
}
|
||||
@@ -243,7 +245,7 @@ namespace ts.FindAllReferences {
|
||||
|
||||
/** A node is considered a writeAccess iff it is a name of a declaration or a target of an assignment */
|
||||
function isWriteAccess(node: Node): boolean {
|
||||
if (isAnyDeclarationName(node)) {
|
||||
if (node.kind === SyntaxKind.DefaultKeyword || isAnyDeclarationName(node)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -743,7 +745,7 @@ namespace ts.FindAllReferences.Core {
|
||||
|
||||
function isValidReferencePosition(node: Node, searchSymbolName: string): boolean {
|
||||
// Compare the length so we filter out strict superstrings of the symbol we are looking for
|
||||
switch (node && node.kind) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
return (node as Identifier).text.length === searchSymbolName.length;
|
||||
|
||||
@@ -754,6 +756,9 @@ namespace ts.FindAllReferences.Core {
|
||||
case SyntaxKind.NumericLiteral:
|
||||
return isLiteralNameOfPropertyDeclarationOrIndexAccess(node as NumericLiteral) && (node as NumericLiteral).text.length === searchSymbolName.length;
|
||||
|
||||
case SyntaxKind.DefaultKeyword:
|
||||
return "default".length === searchSymbolName.length;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -1435,22 +1440,27 @@ namespace ts.FindAllReferences.Core {
|
||||
const bindingElementPropertySymbol = getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol, checker);
|
||||
if (bindingElementPropertySymbol) {
|
||||
result.push(bindingElementPropertySymbol);
|
||||
addRootSymbols(bindingElementPropertySymbol);
|
||||
}
|
||||
|
||||
// If this is a union property, add all the symbols from all its source symbols in all unioned types.
|
||||
// If the symbol is an instantiation from a another symbol (e.g. widened symbol) , add the root the list
|
||||
for (const rootSymbol of checker.getRootSymbols(symbol)) {
|
||||
if (rootSymbol !== symbol) {
|
||||
result.push(rootSymbol);
|
||||
}
|
||||
|
||||
// Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions
|
||||
if (!implementations && rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
|
||||
getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, result, /*previousIterationSymbolsCache*/ createSymbolTable(), checker);
|
||||
}
|
||||
}
|
||||
addRootSymbols(symbol);
|
||||
|
||||
return result;
|
||||
|
||||
function addRootSymbols(sym: Symbol): void {
|
||||
// If this is a union property, add all the symbols from all its source symbols in all unioned types.
|
||||
// If the symbol is an instantiation from a another symbol (e.g. widened symbol) , add the root the list
|
||||
for (const rootSymbol of checker.getRootSymbols(sym)) {
|
||||
if (rootSymbol !== sym) {
|
||||
result.push(rootSymbol);
|
||||
}
|
||||
|
||||
// Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions
|
||||
if (!implementations && rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
|
||||
getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, result, /*previousIterationSymbolsCache*/ createSymbolTable(), checker);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1542,34 +1552,39 @@ namespace ts.FindAllReferences.Core {
|
||||
// then include the binding element in the related symbols
|
||||
// let { a } : { a };
|
||||
const bindingElementPropertySymbol = getPropertySymbolOfObjectBindingPatternWithoutPropertyName(referenceSymbol, state.checker);
|
||||
if (bindingElementPropertySymbol && search.includes(bindingElementPropertySymbol)) {
|
||||
return bindingElementPropertySymbol;
|
||||
if (bindingElementPropertySymbol) {
|
||||
const fromBindingElement = findRootSymbol(bindingElementPropertySymbol);
|
||||
if (fromBindingElement) return fromBindingElement;
|
||||
}
|
||||
|
||||
// Unwrap symbols to get to the root (e.g. transient symbols as a result of widening)
|
||||
// Or a union property, use its underlying unioned symbols
|
||||
return forEach(state.checker.getRootSymbols(referenceSymbol), rootSymbol => {
|
||||
// if it is in the list, then we are done
|
||||
if (search.includes(rootSymbol)) {
|
||||
return rootSymbol;
|
||||
}
|
||||
return findRootSymbol(referenceSymbol);
|
||||
|
||||
// Finally, try all properties with the same name in any type the containing type extended or implemented, and
|
||||
// see if any is in the list. If we were passed a parent symbol, only include types that are subtypes of the
|
||||
// parent symbol
|
||||
if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
|
||||
// Parents will only be defined if implementations is true
|
||||
if (search.parents && !some(search.parents, parent => explicitlyInheritsFrom(rootSymbol.parent, parent, state.inheritsFromCache, state.checker))) {
|
||||
return undefined;
|
||||
function findRootSymbol(sym: Symbol): Symbol | undefined {
|
||||
// Unwrap symbols to get to the root (e.g. transient symbols as a result of widening)
|
||||
// Or a union property, use its underlying unioned symbols
|
||||
return forEach(state.checker.getRootSymbols(sym), rootSymbol => {
|
||||
// if it is in the list, then we are done
|
||||
if (search.includes(rootSymbol)) {
|
||||
return rootSymbol;
|
||||
}
|
||||
|
||||
const result: Symbol[] = [];
|
||||
getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, result, /*previousIterationSymbolsCache*/ createSymbolTable(), state.checker);
|
||||
return find(result, search.includes);
|
||||
}
|
||||
// Finally, try all properties with the same name in any type the containing type extended or implemented, and
|
||||
// see if any is in the list. If we were passed a parent symbol, only include types that are subtypes of the
|
||||
// parent symbol
|
||||
if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
|
||||
// Parents will only be defined if implementations is true
|
||||
if (search.parents && !some(search.parents, parent => explicitlyInheritsFrom(rootSymbol.parent, parent, state.inheritsFromCache, state.checker))) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
const result: Symbol[] = [];
|
||||
getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, result, /*previousIterationSymbolsCache*/ createSymbolTable(), state.checker);
|
||||
return find(result, search.includes);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function getNameFromObjectLiteralElement(node: ObjectLiteralElement): string {
|
||||
|
||||
@@ -339,17 +339,17 @@ namespace ts.formatting {
|
||||
/* @internal */
|
||||
export function formatNodeGivenIndentation(node: Node, sourceFileLike: SourceFileLike, languageVariant: LanguageVariant, initialIndentation: number, delta: number, rulesProvider: RulesProvider): TextChange[] {
|
||||
const range = { pos: 0, end: sourceFileLike.text.length };
|
||||
return formatSpanWorker(
|
||||
return getFormattingScanner(sourceFileLike.text, languageVariant, range.pos, range.end, scanner => formatSpanWorker(
|
||||
range,
|
||||
node,
|
||||
initialIndentation,
|
||||
delta,
|
||||
getFormattingScanner(sourceFileLike.text, languageVariant, range.pos, range.end),
|
||||
scanner,
|
||||
rulesProvider.getFormatOptions(),
|
||||
rulesProvider,
|
||||
FormattingRequestKind.FormatSelection,
|
||||
_ => false, // assume that node does not have any errors
|
||||
sourceFileLike);
|
||||
sourceFileLike));
|
||||
}
|
||||
|
||||
function formatNodeLines(node: Node, sourceFile: SourceFile, options: FormatCodeSettings, rulesProvider: RulesProvider, requestKind: FormattingRequestKind): TextChange[] {
|
||||
@@ -372,17 +372,17 @@ namespace ts.formatting {
|
||||
requestKind: FormattingRequestKind): TextChange[] {
|
||||
// find the smallest node that fully wraps the range and compute the initial indentation for the node
|
||||
const enclosingNode = findEnclosingNode(originalRange, sourceFile);
|
||||
return formatSpanWorker(
|
||||
return getFormattingScanner(sourceFile.text, sourceFile.languageVariant, getScanStartPosition(enclosingNode, originalRange, sourceFile), originalRange.end, scanner => formatSpanWorker(
|
||||
originalRange,
|
||||
enclosingNode,
|
||||
SmartIndenter.getIndentationForNode(enclosingNode, originalRange, sourceFile, options),
|
||||
getOwnOrInheritedDelta(enclosingNode, options, sourceFile),
|
||||
getFormattingScanner(sourceFile.text, sourceFile.languageVariant, getScanStartPosition(enclosingNode, originalRange, sourceFile), originalRange.end),
|
||||
scanner,
|
||||
options,
|
||||
rulesProvider,
|
||||
requestKind,
|
||||
prepareRangeContainsErrorFunction(sourceFile.parseDiagnostics, originalRange),
|
||||
sourceFile);
|
||||
sourceFile));
|
||||
}
|
||||
|
||||
function formatSpanWorker(originalRange: TextRange,
|
||||
@@ -427,8 +427,6 @@ namespace ts.formatting {
|
||||
}
|
||||
}
|
||||
|
||||
formattingScanner.close();
|
||||
|
||||
return edits;
|
||||
|
||||
// local functions
|
||||
@@ -728,6 +726,7 @@ namespace ts.formatting {
|
||||
parent: Node,
|
||||
parentStartLine: number,
|
||||
parentDynamicIndentation: DynamicIndentation): void {
|
||||
Debug.assert(isNodeArray(nodes));
|
||||
|
||||
const listStartToken = getOpenTokenForList(parent, nodes);
|
||||
const listEndToken = getCloseTokenForOpenToken(listStartToken);
|
||||
|
||||
@@ -6,11 +6,6 @@ namespace ts.formatting {
|
||||
const standardScanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false, LanguageVariant.Standard);
|
||||
const jsxScanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false, LanguageVariant.JSX);
|
||||
|
||||
/**
|
||||
* Scanner that is currently used for formatting
|
||||
*/
|
||||
let scanner: Scanner;
|
||||
|
||||
export interface FormattingScanner {
|
||||
advance(): void;
|
||||
isOnToken(): boolean;
|
||||
@@ -18,7 +13,6 @@ namespace ts.formatting {
|
||||
getCurrentLeadingTrivia(): TextRangeWithKind[];
|
||||
lastTrailingTriviaWasNewLine(): boolean;
|
||||
skipToEndOf(node: Node): void;
|
||||
close(): void;
|
||||
}
|
||||
|
||||
const enum ScanAction {
|
||||
@@ -30,9 +24,8 @@ namespace ts.formatting {
|
||||
RescanJsxText,
|
||||
}
|
||||
|
||||
export function getFormattingScanner(text: string, languageVariant: LanguageVariant, startPos: number, endPos: number): FormattingScanner {
|
||||
Debug.assert(scanner === undefined, "Scanner should be undefined");
|
||||
scanner = languageVariant === LanguageVariant.JSX ? jsxScanner : standardScanner;
|
||||
export function getFormattingScanner<T>(text: string, languageVariant: LanguageVariant, startPos: number, endPos: number, cb: (scanner: FormattingScanner) => T): T {
|
||||
const scanner = languageVariant === LanguageVariant.JSX ? jsxScanner : standardScanner;
|
||||
|
||||
scanner.setText(text);
|
||||
scanner.setTextPos(startPos);
|
||||
@@ -45,21 +38,19 @@ namespace ts.formatting {
|
||||
let lastScanAction: ScanAction | undefined;
|
||||
let lastTokenInfo: TokenInfo | undefined;
|
||||
|
||||
return {
|
||||
const res = cb({
|
||||
advance,
|
||||
readTokenInfo,
|
||||
isOnToken,
|
||||
getCurrentLeadingTrivia: () => leadingTrivia,
|
||||
lastTrailingTriviaWasNewLine: () => wasNewLine,
|
||||
skipToEndOf,
|
||||
close: () => {
|
||||
Debug.assert(scanner !== undefined);
|
||||
});
|
||||
|
||||
lastTokenInfo = undefined;
|
||||
scanner.setText(undefined);
|
||||
scanner = undefined;
|
||||
}
|
||||
};
|
||||
lastTokenInfo = undefined;
|
||||
scanner.setText(undefined);
|
||||
|
||||
return res;
|
||||
|
||||
function advance(): void {
|
||||
Debug.assert(scanner !== undefined, "Scanner should be present");
|
||||
|
||||
@@ -3,16 +3,12 @@
|
||||
/* @internal */
|
||||
namespace ts.formatting {
|
||||
export class Rule {
|
||||
// Used for debugging to identify each rule based on the property name it's assigned to.
|
||||
public debugName?: string;
|
||||
constructor(
|
||||
public Descriptor: RuleDescriptor,
|
||||
public Operation: RuleOperation,
|
||||
public Flag: RuleFlags = RuleFlags.None) {
|
||||
}
|
||||
|
||||
public toString() {
|
||||
return "[desc=" + this.Descriptor + "," +
|
||||
"operation=" + this.Operation + "," +
|
||||
"flag=" + this.Flag + "]";
|
||||
readonly Descriptor: RuleDescriptor,
|
||||
readonly Operation: RuleOperation,
|
||||
readonly Flag: RuleFlags = RuleFlags.None) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,18 +3,6 @@
|
||||
/* @internal */
|
||||
namespace ts.formatting {
|
||||
export class Rules {
|
||||
public getRuleName(rule: Rule) {
|
||||
const o: ts.MapLike<any> = <any>this;
|
||||
for (const name in o) {
|
||||
if (o[name] === rule) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
throw new Error("Unknown rule");
|
||||
}
|
||||
|
||||
[name: string]: any;
|
||||
|
||||
public IgnoreBeforeComment: Rule;
|
||||
public IgnoreAfterLineComment: Rule;
|
||||
|
||||
@@ -569,6 +557,16 @@ namespace ts.formatting {
|
||||
this.SpaceAfterSemicolon,
|
||||
this.SpaceBetweenStatements, this.SpaceAfterTryFinally
|
||||
];
|
||||
|
||||
if (Debug.isDebugging) {
|
||||
const o: ts.MapLike<any> = <any>this;
|
||||
for (const name in o) {
|
||||
const rule = o[name];
|
||||
if (rule instanceof Rule) {
|
||||
rule.debugName = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
|
||||
@@ -9,18 +9,10 @@ namespace ts.formatting {
|
||||
|
||||
constructor() {
|
||||
this.globalRules = new Rules();
|
||||
const activeRules = this.globalRules.HighPriorityCommonRules.slice(0).concat(this.globalRules.UserConfigurableRules).concat(this.globalRules.LowPriorityCommonRules);
|
||||
const activeRules = this.globalRules.HighPriorityCommonRules.concat(this.globalRules.UserConfigurableRules).concat(this.globalRules.LowPriorityCommonRules);
|
||||
this.rulesMap = RulesMap.create(activeRules);
|
||||
}
|
||||
|
||||
public getRuleName(rule: Rule): string {
|
||||
return this.globalRules.getRuleName(rule);
|
||||
}
|
||||
|
||||
public getRuleByName(name: string): Rule {
|
||||
return this.globalRules[name];
|
||||
}
|
||||
|
||||
public getRulesMap() {
|
||||
return this.rulesMap;
|
||||
}
|
||||
|
||||
@@ -180,7 +180,6 @@ namespace ts.FindAllReferences {
|
||||
* But re-exports will be placed in 'singleReferences' since they cannot be locally referenced.
|
||||
*/
|
||||
function getSearchesFromDirectImports(directImports: Importer[], exportSymbol: Symbol, exportKind: ExportKind, checker: TypeChecker, isForRename: boolean): Pick<ImportsResult, "importSearches" | "singleReferences"> {
|
||||
const exportName = exportSymbol.escapedName;
|
||||
const importSearches: Array<[Identifier, Symbol]> = [];
|
||||
const singleReferences: Identifier[] = [];
|
||||
function addSearch(location: Identifier, symbol: Symbol): void {
|
||||
@@ -218,12 +217,11 @@ namespace ts.FindAllReferences {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!decl.importClause) {
|
||||
const { importClause } = decl;
|
||||
if (!importClause) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { importClause } = decl;
|
||||
|
||||
const { namedBindings } = importClause;
|
||||
if (namedBindings && namedBindings.kind === SyntaxKind.NamespaceImport) {
|
||||
handleNamespaceImportLike(namedBindings.name);
|
||||
@@ -245,7 +243,6 @@ namespace ts.FindAllReferences {
|
||||
|
||||
// 'default' might be accessed as a named import `{ default as foo }`.
|
||||
if (!isForRename && exportKind === ExportKind.Default) {
|
||||
Debug.assert(exportName === "default");
|
||||
searchForNamedImport(namedBindings as NamedImports | undefined);
|
||||
}
|
||||
}
|
||||
@@ -258,36 +255,43 @@ namespace ts.FindAllReferences {
|
||||
*/
|
||||
function handleNamespaceImportLike(importName: Identifier): void {
|
||||
// Don't rename an import that already has a different name than the export.
|
||||
if (exportKind === ExportKind.ExportEquals && (!isForRename || importName.escapedText === exportName)) {
|
||||
if (exportKind === ExportKind.ExportEquals && (!isForRename || isNameMatch(importName.escapedText))) {
|
||||
addSearch(importName, checker.getSymbolAtLocation(importName));
|
||||
}
|
||||
}
|
||||
|
||||
function searchForNamedImport(namedBindings: NamedImportsOrExports | undefined): void {
|
||||
if (namedBindings) {
|
||||
for (const element of namedBindings.elements) {
|
||||
const { name, propertyName } = element;
|
||||
if ((propertyName || name).escapedText !== exportName) {
|
||||
continue;
|
||||
}
|
||||
if (!namedBindings) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (propertyName) {
|
||||
// This is `import { foo as bar } from "./a"` or `export { foo as bar } from "./a"`. `foo` isn't a local in the file, so just add it as a single reference.
|
||||
singleReferences.push(propertyName);
|
||||
if (!isForRename) { // If renaming `foo`, don't touch `bar`, just `foo`.
|
||||
// Search locally for `bar`.
|
||||
addSearch(name, checker.getSymbolAtLocation(name));
|
||||
}
|
||||
}
|
||||
else {
|
||||
const localSymbol = element.kind === SyntaxKind.ExportSpecifier && element.propertyName
|
||||
? checker.getExportSpecifierLocalTargetSymbol(element) // For re-exporting under a different name, we want to get the re-exported symbol.
|
||||
: checker.getSymbolAtLocation(name);
|
||||
addSearch(name, localSymbol);
|
||||
for (const element of namedBindings.elements) {
|
||||
const { name, propertyName } = element;
|
||||
if (!isNameMatch((propertyName || name).escapedText)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (propertyName) {
|
||||
// This is `import { foo as bar } from "./a"` or `export { foo as bar } from "./a"`. `foo` isn't a local in the file, so just add it as a single reference.
|
||||
singleReferences.push(propertyName);
|
||||
if (!isForRename) { // If renaming `foo`, don't touch `bar`, just `foo`.
|
||||
// Search locally for `bar`.
|
||||
addSearch(name, checker.getSymbolAtLocation(name));
|
||||
}
|
||||
}
|
||||
else {
|
||||
const localSymbol = element.kind === SyntaxKind.ExportSpecifier && element.propertyName
|
||||
? checker.getExportSpecifierLocalTargetSymbol(element) // For re-exporting under a different name, we want to get the re-exported symbol.
|
||||
: checker.getSymbolAtLocation(name);
|
||||
addSearch(name, localSymbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isNameMatch(name: __String): boolean {
|
||||
// Use name of "default" even in `export =` case because we may have allowSyntheticDefaultImports
|
||||
return name === exportSymbol.escapedName || exportKind !== ExportKind.Named && name === "default";
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns 'true' is the namespace 'name' is re-exported from this module, and 'false' if it is only used locally. */
|
||||
@@ -413,7 +417,7 @@ namespace ts.FindAllReferences {
|
||||
case SyntaxKind.ExternalModuleReference:
|
||||
return (decl as ExternalModuleReference).parent;
|
||||
default:
|
||||
Debug.fail(`Unexpected module specifier parent: ${decl.kind}`);
|
||||
Debug.fail("Unexpected module specifier parent: " + decl.kind);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -468,11 +472,11 @@ namespace ts.FindAllReferences {
|
||||
return exportInfo(symbol, getExportKindForDeclaration(exportNode));
|
||||
}
|
||||
}
|
||||
// If we are in `export = a;`, `parent` is the export assignment.
|
||||
// If we are in `export = a;` or `export default a;`, `parent` is the export assignment.
|
||||
else if (isExportAssignment(parent)) {
|
||||
return getExportAssignmentExport(parent);
|
||||
}
|
||||
// If we are in `export = class A {};` at `A`, `parent.parent` is the export assignment.
|
||||
// If we are in `export = class A {};` (or `export = class A {};`) at `A`, `parent.parent` is the export assignment.
|
||||
else if (isExportAssignment(parent.parent)) {
|
||||
return getExportAssignmentExport(parent.parent);
|
||||
}
|
||||
@@ -489,7 +493,8 @@ namespace ts.FindAllReferences {
|
||||
// Get the symbol for the `export =` node; its parent is the module it's the export of.
|
||||
const exportingModuleSymbol = ex.symbol.parent;
|
||||
Debug.assert(!!exportingModuleSymbol);
|
||||
return { kind: ImportExport.Export, symbol, exportInfo: { exportingModuleSymbol, exportKind: ExportKind.ExportEquals } };
|
||||
const exportKind = ex.isExportEquals ? ExportKind.ExportEquals : ExportKind.Default;
|
||||
return { kind: ImportExport.Export, symbol, exportInfo: { exportingModuleSymbol, exportKind } };
|
||||
}
|
||||
|
||||
function getSpecialPropertyExport(node: ts.BinaryExpression, useLhsSymbol: boolean): ExportedSymbol | undefined {
|
||||
@@ -525,7 +530,11 @@ namespace ts.FindAllReferences {
|
||||
importedSymbol = getExportEqualsLocalSymbol(importedSymbol, checker);
|
||||
}
|
||||
|
||||
if (symbolName(importedSymbol) === symbol.escapedName) { // If this is a rename import, do not continue searching.
|
||||
// If the import has a different name than the export, do not continue searching.
|
||||
// If `importedName` is undefined, do continue searching as the export is anonymous.
|
||||
// (All imports returned from this function will be ignored anyway if we are in rename and this is a not a named export.)
|
||||
const importedName = symbolName(importedSymbol);
|
||||
if (importedName === undefined || importedName === "default" || importedName === symbol.escapedName) {
|
||||
return { kind: ImportExport.Import, symbol: importedSymbol, ...isImport };
|
||||
}
|
||||
}
|
||||
|
||||
+62
-49
@@ -173,38 +173,15 @@ namespace ts.JsDoc {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// TODO: add support for:
|
||||
// - enums/enum members
|
||||
// - interfaces
|
||||
// - property declarations
|
||||
// - potentially property assignments
|
||||
let commentOwner: Node;
|
||||
findOwner: for (commentOwner = tokenAtPos; commentOwner; commentOwner = commentOwner.parent) {
|
||||
switch (commentOwner.kind) {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.Constructor:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.VariableStatement:
|
||||
break findOwner;
|
||||
case SyntaxKind.SourceFile:
|
||||
return undefined;
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
// If in walking up the tree, we hit a a nested namespace declaration,
|
||||
// then we must be somewhere within a dotted namespace name; however we don't
|
||||
// want to give back a JSDoc template for the 'b' or 'c' in 'namespace a.b.c { }'.
|
||||
if (commentOwner.parent.kind === SyntaxKind.ModuleDeclaration) {
|
||||
return undefined;
|
||||
}
|
||||
break findOwner;
|
||||
}
|
||||
const commentOwnerInfo = getCommentOwnerInfo(tokenAtPos);
|
||||
if (!commentOwnerInfo) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (!commentOwner || commentOwner.getStart() < position) {
|
||||
const { commentOwner, parameters } = commentOwnerInfo;
|
||||
if (commentOwner.getStart() < position) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const parameters = getParametersForJsDocOwningNode(commentOwner);
|
||||
const posLineAndChar = sourceFile.getLineAndCharacterOfPosition(position);
|
||||
const lineStart = sourceFile.getLineStarts()[posLineAndChar.line];
|
||||
|
||||
@@ -213,16 +190,18 @@ namespace ts.JsDoc {
|
||||
const isJavaScriptFile = hasJavaScriptFileExtension(sourceFile.fileName);
|
||||
|
||||
let docParams = "";
|
||||
for (let i = 0; i < parameters.length; i++) {
|
||||
const currentName = parameters[i].name;
|
||||
const paramName = currentName.kind === SyntaxKind.Identifier ?
|
||||
(<Identifier>currentName).escapedText :
|
||||
"param" + i;
|
||||
if (isJavaScriptFile) {
|
||||
docParams += `${indentationStr} * @param {any} ${paramName}${newLine}`;
|
||||
}
|
||||
else {
|
||||
docParams += `${indentationStr} * @param ${paramName}${newLine}`;
|
||||
if (parameters) {
|
||||
for (let i = 0; i < parameters.length; i++) {
|
||||
const currentName = parameters[i].name;
|
||||
const paramName = currentName.kind === SyntaxKind.Identifier ?
|
||||
(<Identifier>currentName).escapedText :
|
||||
"param" + i;
|
||||
if (isJavaScriptFile) {
|
||||
docParams += `${indentationStr} * @param {any} ${paramName}${newLine}`;
|
||||
}
|
||||
else {
|
||||
docParams += `${indentationStr} * @param ${paramName}${newLine}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,21 +223,55 @@ namespace ts.JsDoc {
|
||||
return { newText: result, caretOffset: preamble.length };
|
||||
}
|
||||
|
||||
function getParametersForJsDocOwningNode(commentOwner: Node): ReadonlyArray<ParameterDeclaration> {
|
||||
if (isFunctionLike(commentOwner)) {
|
||||
return commentOwner.parameters;
|
||||
}
|
||||
interface CommentOwnerInfo {
|
||||
readonly commentOwner: Node;
|
||||
readonly parameters?: ReadonlyArray<ParameterDeclaration>;
|
||||
}
|
||||
function getCommentOwnerInfo(tokenAtPos: Node): CommentOwnerInfo | undefined {
|
||||
// TODO: add support for:
|
||||
// - enums/enum members
|
||||
// - interfaces
|
||||
// - property declarations
|
||||
// - potentially property assignments
|
||||
for (let commentOwner = tokenAtPos; commentOwner; commentOwner = commentOwner.parent) {
|
||||
switch (commentOwner.kind) {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.Constructor:
|
||||
const { parameters } = commentOwner as FunctionDeclaration | MethodDeclaration | ConstructorDeclaration;
|
||||
return { commentOwner, parameters };
|
||||
|
||||
if (commentOwner.kind === SyntaxKind.VariableStatement) {
|
||||
const varStatement = <VariableStatement>commentOwner;
|
||||
const varDeclarations = varStatement.declarationList.declarations;
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
return { commentOwner };
|
||||
|
||||
if (varDeclarations.length === 1 && varDeclarations[0].initializer) {
|
||||
return getParametersFromRightHandSideOfAssignment(varDeclarations[0].initializer);
|
||||
case SyntaxKind.VariableStatement: {
|
||||
const varStatement = <VariableStatement>commentOwner;
|
||||
const varDeclarations = varStatement.declarationList.declarations;
|
||||
const parameters = varDeclarations.length === 1 && varDeclarations[0].initializer
|
||||
? getParametersFromRightHandSideOfAssignment(varDeclarations[0].initializer)
|
||||
: undefined;
|
||||
return { commentOwner, parameters };
|
||||
}
|
||||
|
||||
case SyntaxKind.SourceFile:
|
||||
return undefined;
|
||||
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
// If in walking up the tree, we hit a a nested namespace declaration,
|
||||
// then we must be somewhere within a dotted namespace name; however we don't
|
||||
// want to give back a JSDoc template for the 'b' or 'c' in 'namespace a.b.c { }'.
|
||||
return commentOwner.parent.kind === SyntaxKind.ModuleDeclaration ? undefined : { commentOwner };
|
||||
|
||||
case SyntaxKind.BinaryExpression: {
|
||||
const be = commentOwner as BinaryExpression;
|
||||
if (getSpecialPropertyAssignmentKind(be) === ts.SpecialPropertyAssignmentKind.None) {
|
||||
return undefined;
|
||||
}
|
||||
const parameters = isFunctionLike(be.right) ? be.right.parameters : emptyArray;
|
||||
return { commentOwner, parameters };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return emptyArray;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
/* @internal */
|
||||
namespace ts.NavigateTo {
|
||||
type RawNavigateToItem = { name: string; fileName: string; matchKind: PatternMatchKind; isCaseSensitive: boolean; declaration: Declaration };
|
||||
interface RawNavigateToItem {
|
||||
name: string;
|
||||
fileName: string;
|
||||
matchKind: PatternMatchKind;
|
||||
isCaseSensitive: boolean;
|
||||
declaration: Declaration;
|
||||
}
|
||||
|
||||
export function getNavigateToItems(sourceFiles: ReadonlyArray<SourceFile>, checker: TypeChecker, cancellationToken: CancellationToken, searchValue: string, maxResultCount: number, excludeDtsFiles: boolean): NavigateToItem[] {
|
||||
const patternMatcher = createPatternMatcher(searchValue);
|
||||
|
||||
@@ -263,13 +263,15 @@ namespace ts.NavigationBar {
|
||||
break;
|
||||
|
||||
default:
|
||||
forEach(node.jsDoc, jsDoc => {
|
||||
forEach(jsDoc.tags, tag => {
|
||||
if (tag.kind === SyntaxKind.JSDocTypedefTag) {
|
||||
addLeafNode(tag);
|
||||
}
|
||||
if (hasJSDocNodes(node)) {
|
||||
forEach(node.jsDoc, jsDoc => {
|
||||
forEach(jsDoc.tags, tag => {
|
||||
if (tag.kind === SyntaxKind.JSDocTypedefTag) {
|
||||
addLeafNode(tag);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
forEachChild(node, addChildrenRecursively);
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace ts.refactor.convertFunctionToES6Class {
|
||||
}
|
||||
|
||||
const ctorDeclaration = ctorSymbol.valueDeclaration;
|
||||
const changeTracker = textChanges.ChangeTracker.fromCodeFixContext(context as { newLineCharacter: string, rulesProvider: formatting.RulesProvider });
|
||||
const changeTracker = textChanges.ChangeTracker.fromContext(context);
|
||||
|
||||
let precedingNode: Node;
|
||||
let newClassDeclaration: ClassDeclaration;
|
||||
|
||||
@@ -95,7 +95,7 @@ namespace ts.refactor.extractMethod {
|
||||
export const CannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators: DiagnosticMessage = createMessage("Cannot extract range containing writes to references located outside of the target range in generators.");
|
||||
export const TypeWillNotBeVisibleInTheNewScope = createMessage("Type will not visible in the new scope.");
|
||||
export const FunctionWillNotBeVisibleInTheNewScope = createMessage("Function will not visible in the new scope.");
|
||||
export const InsufficientSelection = createMessage("Select more than a single identifier.");
|
||||
export const InsufficientSelection = createMessage("Select more than a single token.");
|
||||
export const CannotExtractExportedEntity = createMessage("Cannot extract exported declaration");
|
||||
export const CannotCombineWritesAndReturns = createMessage("Cannot combine writes and returns");
|
||||
export const CannotExtractReadonlyPropertyInitializerOutsideConstructor = createMessage("Cannot move initialization of read-only class property outside of the constructor");
|
||||
@@ -239,7 +239,7 @@ namespace ts.refactor.extractMethod {
|
||||
}
|
||||
|
||||
function checkRootNode(node: Node): Diagnostic[] | undefined {
|
||||
if (isIdentifier(node)) {
|
||||
if (isToken(node)) {
|
||||
return [createDiagnosticForNode(node, Messages.InsufficientSelection)];
|
||||
}
|
||||
return undefined;
|
||||
@@ -352,45 +352,31 @@ namespace ts.refactor.extractMethod {
|
||||
return false;
|
||||
}
|
||||
const savedPermittedJumps = permittedJumps;
|
||||
if (node.parent) {
|
||||
switch (node.parent.kind) {
|
||||
case SyntaxKind.IfStatement:
|
||||
if ((<IfStatement>node.parent).thenStatement === node || (<IfStatement>node.parent).elseStatement === node) {
|
||||
// forbid all jumps inside thenStatement or elseStatement
|
||||
permittedJumps = PermittedJumps.None;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.TryStatement:
|
||||
if ((<TryStatement>node.parent).tryBlock === node) {
|
||||
// forbid all jumps inside try blocks
|
||||
permittedJumps = PermittedJumps.None;
|
||||
}
|
||||
else if ((<TryStatement>node.parent).finallyBlock === node) {
|
||||
// allow unconditional returns from finally blocks
|
||||
permittedJumps = PermittedJumps.Return;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.CatchClause:
|
||||
if ((<CatchClause>node.parent).block === node) {
|
||||
// forbid all jumps inside the block of catch clause
|
||||
permittedJumps = PermittedJumps.None;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.CaseClause:
|
||||
if ((<CaseClause>node).expression !== node) {
|
||||
// allow unlabeled break inside case clauses
|
||||
permittedJumps |= PermittedJumps.Break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (isIterationStatement(node.parent, /*lookInLabeledStatements*/ false)) {
|
||||
if ((<IterationStatement>node.parent).statement === node) {
|
||||
// allow unlabeled break/continue inside loops
|
||||
permittedJumps |= PermittedJumps.Break | PermittedJumps.Continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.IfStatement:
|
||||
permittedJumps = PermittedJumps.None;
|
||||
break;
|
||||
case SyntaxKind.TryStatement:
|
||||
// forbid all jumps inside try blocks
|
||||
permittedJumps = PermittedJumps.None;
|
||||
break;
|
||||
case SyntaxKind.Block:
|
||||
if (node.parent && node.parent.kind === SyntaxKind.TryStatement && (<TryStatement>node).finallyBlock === node) {
|
||||
// allow unconditional returns from finally blocks
|
||||
permittedJumps = PermittedJumps.Return;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.CaseClause:
|
||||
// allow unlabeled break inside case clauses
|
||||
permittedJumps |= PermittedJumps.Break;
|
||||
break;
|
||||
default:
|
||||
if (isIterationStatement(node, /*lookInLabeledStatements*/ false)) {
|
||||
// allow unlabeled break/continue inside loops
|
||||
permittedJumps |= PermittedJumps.Break | PermittedJumps.Continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (node.kind) {
|
||||
@@ -417,7 +403,7 @@ namespace ts.refactor.extractMethod {
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!(permittedJumps & (SyntaxKind.BreakStatement ? PermittedJumps.Break : PermittedJumps.Continue))) {
|
||||
if (!(permittedJumps & (node.kind === SyntaxKind.BreakStatement ? PermittedJumps.Break : PermittedJumps.Continue))) {
|
||||
// attempt to break or continue in a forbidden context
|
||||
(errors || (errors = [])).push(createDiagnosticForNode(node, Messages.CannotExtractRangeContainingConditionalBreakOrContinueStatements));
|
||||
}
|
||||
@@ -656,11 +642,13 @@ namespace ts.refactor.extractMethod {
|
||||
const typeParametersAndDeclarations = arrayFrom(typeParameterUsages.values()).map(type => ({ type, declaration: getFirstDeclaration(type) }));
|
||||
const sortedTypeParametersAndDeclarations = typeParametersAndDeclarations.sort(compareTypesByDeclarationOrder);
|
||||
|
||||
const typeParameters: ReadonlyArray<TypeParameterDeclaration> = sortedTypeParametersAndDeclarations.map(t => t.declaration as TypeParameterDeclaration);
|
||||
const typeParameters: ReadonlyArray<TypeParameterDeclaration> | undefined = sortedTypeParametersAndDeclarations.length === 0
|
||||
? undefined
|
||||
: sortedTypeParametersAndDeclarations.map(t => t.declaration as TypeParameterDeclaration);
|
||||
|
||||
// Strictly speaking, we should check whether each name actually binds to the appropriate type
|
||||
// parameter. In cases of shadowing, they may not.
|
||||
const callTypeArguments: ReadonlyArray<TypeNode> | undefined = typeParameters.length > 0
|
||||
const callTypeArguments: ReadonlyArray<TypeNode> | undefined = typeParameters !== undefined
|
||||
? typeParameters.map(decl => createTypeReferenceNode(decl.name, /*typeArguments*/ undefined))
|
||||
: undefined;
|
||||
|
||||
@@ -708,7 +696,7 @@ namespace ts.refactor.extractMethod {
|
||||
);
|
||||
}
|
||||
|
||||
const changeTracker = textChanges.ChangeTracker.fromCodeFixContext(context);
|
||||
const changeTracker = textChanges.ChangeTracker.fromContext(context);
|
||||
// insert function at the end of the scope
|
||||
changeTracker.insertNodeBefore(context.file, scope.getLastToken(), newFunction, { prefix: context.newLineCharacter, suffix: context.newLineCharacter });
|
||||
|
||||
@@ -746,6 +734,10 @@ namespace ts.refactor.extractMethod {
|
||||
}
|
||||
else {
|
||||
newNodes.push(createStatement(createBinary(assignments[0].name, SyntaxKind.EqualsToken, call)));
|
||||
|
||||
if (range.facts & RangeFacts.HasReturn) {
|
||||
newNodes.push(createReturn());
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -722,6 +722,12 @@ namespace ts {
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.BinaryExpression:
|
||||
if (getSpecialPropertyAssignmentKind(node as BinaryExpression) !== SpecialPropertyAssignmentKind.None) {
|
||||
addDeclaration(node as BinaryExpression);
|
||||
}
|
||||
// falls through
|
||||
|
||||
default:
|
||||
forEachChild(node, visit);
|
||||
}
|
||||
@@ -1137,7 +1143,7 @@ namespace ts {
|
||||
oldSettings.noResolve !== newSettings.noResolve ||
|
||||
oldSettings.jsx !== newSettings.jsx ||
|
||||
oldSettings.allowJs !== newSettings.allowJs ||
|
||||
oldSettings.disableSizeLimit !== oldSettings.disableSizeLimit ||
|
||||
oldSettings.disableSizeLimit !== newSettings.disableSizeLimit ||
|
||||
oldSettings.baseUrl !== newSettings.baseUrl ||
|
||||
!equalOwnProperties(oldSettings.paths, newSettings.paths));
|
||||
|
||||
@@ -1398,7 +1404,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
const typeChecker = program.getTypeChecker();
|
||||
const symbol = typeChecker.getSymbolAtLocation(node);
|
||||
const symbol = getSymbolAtLocationForQuickInfo(node, typeChecker);
|
||||
|
||||
if (!symbol || typeChecker.isUnknownSymbol(symbol)) {
|
||||
// Try getting just type at this position and show
|
||||
@@ -1437,6 +1443,21 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
function getSymbolAtLocationForQuickInfo(node: Node, checker: TypeChecker): Symbol | undefined {
|
||||
if ((isIdentifier(node) || isStringLiteral(node))
|
||||
&& isPropertyAssignment(node.parent)
|
||||
&& node.parent.name === node) {
|
||||
const type = checker.getContextualType(node.parent.parent);
|
||||
if (type) {
|
||||
const property = checker.getPropertyOfType(type, getTextOfIdentifierOrLiteral(node));
|
||||
if (property) {
|
||||
return property;
|
||||
}
|
||||
}
|
||||
}
|
||||
return checker.getSymbolAtLocation(node);
|
||||
}
|
||||
|
||||
/// Goto definition
|
||||
function getDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] {
|
||||
synchronizeHostData();
|
||||
@@ -2090,7 +2111,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
forEachChild(node, walk);
|
||||
if (node.jsDoc) {
|
||||
if (hasJSDocNodes(node)) {
|
||||
for (const jsDoc of node.jsDoc) {
|
||||
forEachChild(jsDoc, walk);
|
||||
}
|
||||
|
||||
@@ -372,8 +372,7 @@ namespace ts.SignatureHelp {
|
||||
if (isTypeParameterList) {
|
||||
isVariadic = false; // type parameter lists are not variadic
|
||||
prefixDisplayParts.push(punctuationPart(SyntaxKind.LessThanToken));
|
||||
// Use `.mapper` to ensure we get the generic type arguments even if this is an instantiated version of the signature.
|
||||
const typeParameters = candidateSignature.mapper ? candidateSignature.mapper.mappedTypes : candidateSignature.typeParameters;
|
||||
const typeParameters = (candidateSignature.target || candidateSignature).typeParameters;
|
||||
signatureHelpParameters = typeParameters && typeParameters.length > 0 ? map(typeParameters, createSignatureHelpParameterForTypeParameter) : emptyArray;
|
||||
suffixDisplayParts.push(punctuationPart(SyntaxKind.GreaterThanToken));
|
||||
const parameterParts = mapToDisplayParts(writer =>
|
||||
|
||||
+16
-14
@@ -5,19 +5,25 @@ namespace ts.textChanges {
|
||||
* Currently for simplicity we store recovered positions on the node itself.
|
||||
* It can be changed to side-table later if we decide that current design is too invasive.
|
||||
*/
|
||||
function getPos(n: TextRange) {
|
||||
return (<any>n)["__pos"];
|
||||
function getPos(n: TextRange): number {
|
||||
const result = (<any>n)["__pos"];
|
||||
Debug.assert(typeof result === "number");
|
||||
return result;
|
||||
}
|
||||
|
||||
function setPos(n: TextRange, pos: number) {
|
||||
function setPos(n: TextRange, pos: number): void {
|
||||
Debug.assert(typeof pos === "number");
|
||||
(<any>n)["__pos"] = pos;
|
||||
}
|
||||
|
||||
function getEnd(n: TextRange) {
|
||||
return (<any>n)["__end"];
|
||||
function getEnd(n: TextRange): number {
|
||||
const result = (<any>n)["__end"];
|
||||
Debug.assert(typeof result === "number");
|
||||
return result;
|
||||
}
|
||||
|
||||
function setEnd(n: TextRange, end: number) {
|
||||
function setEnd(n: TextRange, end: number): void {
|
||||
Debug.assert(typeof end === "number");
|
||||
(<any>n)["__end"] = end;
|
||||
}
|
||||
|
||||
@@ -186,7 +192,7 @@ namespace ts.textChanges {
|
||||
private changes: Change[] = [];
|
||||
private readonly newLineCharacter: string;
|
||||
|
||||
public static fromCodeFixContext(context: { newLineCharacter: string, rulesProvider?: formatting.RulesProvider }) {
|
||||
public static fromContext(context: RefactorContext | CodeFixContext) {
|
||||
return new ChangeTracker(getNewlineKind(context), context.rulesProvider);
|
||||
}
|
||||
|
||||
@@ -582,7 +588,7 @@ namespace ts.textChanges {
|
||||
readonly node: Node;
|
||||
}
|
||||
|
||||
export function getNonformattedText(node: Node, sourceFile: SourceFile | undefined, newLine: NewLineKind): NonFormattedText {
|
||||
function getNonformattedText(node: Node, sourceFile: SourceFile | undefined, newLine: NewLineKind): NonFormattedText {
|
||||
const options = { newLine, target: sourceFile && sourceFile.languageVersion };
|
||||
const writer = new Writer(getNewLineCharacter(options));
|
||||
const printer = createPrinter(options, writer);
|
||||
@@ -590,7 +596,7 @@ namespace ts.textChanges {
|
||||
return { text: writer.getText(), node: assignPositionsToNode(node) };
|
||||
}
|
||||
|
||||
export function applyFormatting(nonFormattedText: NonFormattedText, sourceFile: SourceFile, initialIndentation: number, delta: number, rulesProvider: formatting.RulesProvider) {
|
||||
function applyFormatting(nonFormattedText: NonFormattedText, sourceFile: SourceFile, initialIndentation: number, delta: number, rulesProvider: formatting.RulesProvider) {
|
||||
const lineMap = computeLineStarts(nonFormattedText.text);
|
||||
const file: SourceFileLike = {
|
||||
text: nonFormattedText.text,
|
||||
@@ -616,14 +622,10 @@ namespace ts.textChanges {
|
||||
function assignPositionsToNode(node: Node): Node {
|
||||
const visited = visitEachChild(node, assignPositionsToNode, nullTransformationContext, assignPositionsToNodeArray, assignPositionsToNode);
|
||||
// create proxy node for non synthesized nodes
|
||||
const newNode = nodeIsSynthesized(visited)
|
||||
? visited
|
||||
: (Proxy.prototype = visited, new (<any>Proxy)());
|
||||
const newNode = nodeIsSynthesized(visited) ? visited : Object.create(visited) as Node;
|
||||
newNode.pos = getPos(node);
|
||||
newNode.end = getEnd(node);
|
||||
return newNode;
|
||||
|
||||
function Proxy() { }
|
||||
}
|
||||
|
||||
function assignPositionsToNodeArray(nodes: NodeArray<any>, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number) {
|
||||
|
||||
@@ -394,7 +394,7 @@ namespace ts {
|
||||
* Represents a single refactoring action - for example, the "Extract Method..." refactor might
|
||||
* offer several actions, each corresponding to a surround class or closure to extract into.
|
||||
*/
|
||||
export type RefactorActionInfo = {
|
||||
export interface RefactorActionInfo {
|
||||
/**
|
||||
* The programmatic name of the refactoring action
|
||||
*/
|
||||
@@ -406,18 +406,17 @@ namespace ts {
|
||||
* so this description should make sense by itself if the parent is inlineable=true
|
||||
*/
|
||||
description: string;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* A set of edits to make in response to a refactor action, plus an optional
|
||||
* location where renaming should be invoked from
|
||||
*/
|
||||
export type RefactorEditInfo = {
|
||||
export interface RefactorEditInfo {
|
||||
edits: FileTextChanges[];
|
||||
renameFilename?: string;
|
||||
renameLocation?: number;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
export interface TextInsertion {
|
||||
newText: string;
|
||||
|
||||
@@ -343,6 +343,28 @@ namespace ts {
|
||||
return ScriptElementKind.alias;
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
return ScriptElementKind.typeElement;
|
||||
case SyntaxKind.BinaryExpression:
|
||||
const kind = getSpecialPropertyAssignmentKind(node as BinaryExpression);
|
||||
const { right } = node as BinaryExpression;
|
||||
switch (kind) {
|
||||
case SpecialPropertyAssignmentKind.None:
|
||||
return ScriptElementKind.unknown;
|
||||
case SpecialPropertyAssignmentKind.ExportsProperty:
|
||||
case SpecialPropertyAssignmentKind.ModuleExports:
|
||||
const rightKind = getNodeKind(right);
|
||||
return rightKind === ScriptElementKind.unknown ? ScriptElementKind.constElement : rightKind;
|
||||
case SpecialPropertyAssignmentKind.PrototypeProperty:
|
||||
return ScriptElementKind.memberFunctionElement; // instance method
|
||||
case SpecialPropertyAssignmentKind.ThisProperty:
|
||||
return ScriptElementKind.memberVariableElement; // property
|
||||
case SpecialPropertyAssignmentKind.Property:
|
||||
// static method / property
|
||||
return isFunctionExpression(right) ? ScriptElementKind.memberFunctionElement : ScriptElementKind.memberVariableElement;
|
||||
default: {
|
||||
assertTypeIsNever(kind);
|
||||
return ScriptElementKind.unknown;
|
||||
}
|
||||
}
|
||||
default:
|
||||
return ScriptElementKind.unknown;
|
||||
}
|
||||
|
||||
-32
@@ -34,38 +34,6 @@
|
||||
"kind": "JSDocTypeLiteral",
|
||||
"pos": 26,
|
||||
"end": 98,
|
||||
"jsDocTypeTag": {
|
||||
"kind": "JSDocTypeTag",
|
||||
"pos": 28,
|
||||
"end": 42,
|
||||
"atToken": {
|
||||
"kind": "AtToken",
|
||||
"pos": 28,
|
||||
"end": 29
|
||||
},
|
||||
"tagName": {
|
||||
"kind": "Identifier",
|
||||
"pos": 29,
|
||||
"end": 33,
|
||||
"escapedText": "type"
|
||||
},
|
||||
"typeExpression": {
|
||||
"kind": "JSDocTypeExpression",
|
||||
"pos": 34,
|
||||
"end": 42,
|
||||
"type": {
|
||||
"kind": "TypeReference",
|
||||
"pos": 35,
|
||||
"end": 41,
|
||||
"typeName": {
|
||||
"kind": "Identifier",
|
||||
"pos": 35,
|
||||
"end": 41,
|
||||
"escapedText": "Object"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"jsDocPropertyTags": [
|
||||
{
|
||||
"kind": "JSDocPropertyTag",
|
||||
|
||||
@@ -1,110 +1,15 @@
|
||||
tests/cases/compiler/immutable.d.ts(25,39): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(46,20): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(47,23): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(48,23): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(49,23): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(50,23): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(51,22): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(52,26): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(58,45): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(60,63): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(68,41): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(69,38): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(69,47): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(78,21): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(79,21): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(89,20): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(90,23): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(91,23): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(92,23): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(93,23): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(94,22): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(95,26): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(101,42): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(106,58): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(113,48): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(114,45): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(114,54): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(120,42): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(125,58): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(134,33): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(134,42): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(135,29): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(135,38): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(139,38): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(155,45): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(157,62): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(169,45): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(172,45): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(174,62): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(188,40): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(195,22): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(198,19): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(205,45): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(207,63): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(217,30): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(218,34): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(226,22): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(227,22): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(234,48): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(235,52): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(236,109): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(237,109): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(242,22): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(243,25): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(244,24): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(245,28): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(246,25): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(247,25): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(258,8): error TS2304: Cannot find name 'Symbol'.
|
||||
tests/cases/compiler/immutable.d.ts(258,28): error TS2304: Cannot find name 'IterableIterator'.
|
||||
tests/cases/compiler/immutable.d.ts(266,45): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(274,44): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(279,60): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(288,44): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(293,47): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(295,65): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(304,40): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(309,47): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(311,64): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(320,38): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(329,58): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(339,45): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(341,22): error TS2430: Interface 'Keyed<K, V>' incorrectly extends interface 'Collection<K, V>'.
|
||||
Types of property 'toSeq' are incompatible.
|
||||
Type '() => Keyed<K, V>' is not assignable to type '() => this'.
|
||||
Type 'Keyed<K, V>' is not assignable to type 'this'.
|
||||
tests/cases/compiler/immutable.d.ts(347,44): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(352,60): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(355,8): error TS2304: Cannot find name 'Symbol'.
|
||||
tests/cases/compiler/immutable.d.ts(355,28): error TS2304: Cannot find name 'IterableIterator'.
|
||||
tests/cases/compiler/immutable.d.ts(358,44): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(359,22): error TS2430: Interface 'Indexed<T>' incorrectly extends interface 'Collection<number, T>'.
|
||||
Types of property 'toSeq' are incompatible.
|
||||
Type '() => Indexed<T>' is not assignable to type '() => this'.
|
||||
Type 'Indexed<T>' is not assignable to type 'this'.
|
||||
tests/cases/compiler/immutable.d.ts(382,47): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(384,65): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(387,8): error TS2304: Cannot find name 'Symbol'.
|
||||
tests/cases/compiler/immutable.d.ts(387,28): error TS2304: Cannot find name 'IterableIterator'.
|
||||
tests/cases/compiler/immutable.d.ts(390,40): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(391,22): error TS2430: Interface 'Set<T>' incorrectly extends interface 'Collection<never, T>'.
|
||||
Types of property 'toSeq' are incompatible.
|
||||
Type '() => Set<T>' is not assignable to type '() => this'.
|
||||
Type 'Set<T>' is not assignable to type 'this'.
|
||||
tests/cases/compiler/immutable.d.ts(396,47): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(398,64): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(401,8): error TS2304: Cannot find name 'Symbol'.
|
||||
tests/cases/compiler/immutable.d.ts(401,28): error TS2304: Cannot find name 'IterableIterator'.
|
||||
tests/cases/compiler/immutable.d.ts(405,45): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(420,26): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(421,26): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(442,13): error TS2304: Cannot find name 'IterableIterator'.
|
||||
tests/cases/compiler/immutable.d.ts(443,15): error TS2304: Cannot find name 'IterableIterator'.
|
||||
tests/cases/compiler/immutable.d.ts(444,16): error TS2304: Cannot find name 'IterableIterator'.
|
||||
tests/cases/compiler/immutable.d.ts(476,58): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(503,20): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Iterable'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/complex.d.ts (0 errors) ====
|
||||
@@ -128,7 +33,7 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
flatMap<M>(mapper: (value: T, key: void, iter: this) => Ara<M>, context?: any): N2<M>;
|
||||
toSeq(): N2<T>;
|
||||
}
|
||||
==== tests/cases/compiler/immutable.d.ts (98 errors) ====
|
||||
==== tests/cases/compiler/immutable.d.ts (3 errors) ====
|
||||
// Test that complex recursive collections can pass the `extends` assignability check without
|
||||
// running out of memory. This bug was exposed in Typescript 2.4 when more generic signatures
|
||||
// started being checked.
|
||||
@@ -154,8 +59,6 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
export function List(): List<any>;
|
||||
export function List<T>(): List<T>;
|
||||
export function List<T>(collection: Iterable<T>): List<T>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
export interface List<T> extends Collection.Indexed<T> {
|
||||
// Persistent changes
|
||||
set(index: number, value: T): List<T>;
|
||||
@@ -177,38 +80,20 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
setSize(size: number): List<T>;
|
||||
// Deep persistent changes
|
||||
setIn(keyPath: Iterable<any>, value: any): this;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
deleteIn(keyPath: Iterable<any>): this;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
removeIn(keyPath: Iterable<any>): this;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
updateIn(keyPath: Iterable<any>, notSetValue: any, updater: (value: any) => any): this;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
updateIn(keyPath: Iterable<any>, updater: (value: any) => any): this;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
mergeIn(keyPath: Iterable<any>, ...collections: Array<any>): this;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
mergeDeepIn(keyPath: Iterable<any>, ...collections: Array<any>): this;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
// Transient changes
|
||||
withMutations(mutator: (mutable: this) => any): this;
|
||||
asMutable(): this;
|
||||
asImmutable(): this;
|
||||
// Sequence algorithms
|
||||
concat<C>(...valuesOrCollections: Array<Iterable<C> | C>): List<T | C>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
map<M>(mapper: (value: T, key: number, iter: this) => M, context?: any): List<M>;
|
||||
flatMap<M>(mapper: (value: T, key: number, iter: this) => Iterable<M>, context?: any): List<M>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
filter<F extends T>(predicate: (value: T, index: number, iter: this) => value is F, context?: any): List<F>;
|
||||
filter(predicate: (value: T, index: number, iter: this) => any, context?: any): this;
|
||||
}
|
||||
@@ -217,13 +102,7 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
function of(...keyValues: Array<any>): Map<any, any>;
|
||||
}
|
||||
export function Map<K, V>(collection: Iterable<[K, V]>): Map<K, V>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
export function Map<T>(collection: Iterable<Iterable<T>>): Map<T, T>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
export function Map<V>(obj: {[key: string]: V}): Map<string, V>;
|
||||
export function Map<K, V>(): Map<K, V>;
|
||||
export function Map(): Map<any, any>;
|
||||
@@ -233,11 +112,7 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
delete(key: K): this;
|
||||
remove(key: K): this;
|
||||
deleteAll(keys: Iterable<K>): this;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
removeAll(keys: Iterable<K>): this;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
clear(): this;
|
||||
update(key: K, notSetValue: V, updater: (value: V) => V): this;
|
||||
update(key: K, updater: (value: V) => V): this;
|
||||
@@ -248,41 +123,23 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
mergeDeepWith(merger: (oldVal: V, newVal: V, key: K) => V, ...collections: Array<Collection<K, V> | {[key: string]: V}>): this;
|
||||
// Deep persistent changes
|
||||
setIn(keyPath: Iterable<any>, value: any): this;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
deleteIn(keyPath: Iterable<any>): this;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
removeIn(keyPath: Iterable<any>): this;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
updateIn(keyPath: Iterable<any>, notSetValue: any, updater: (value: any) => any): this;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
updateIn(keyPath: Iterable<any>, updater: (value: any) => any): this;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
mergeIn(keyPath: Iterable<any>, ...collections: Array<any>): this;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
mergeDeepIn(keyPath: Iterable<any>, ...collections: Array<any>): this;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
// Transient changes
|
||||
withMutations(mutator: (mutable: this) => any): this;
|
||||
asMutable(): this;
|
||||
asImmutable(): this;
|
||||
// Sequence algorithms
|
||||
concat<KC, VC>(...collections: Array<Iterable<[KC, VC]>>): Map<K | KC, V | VC>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
concat<C>(...collections: Array<{[key: string]: C}>): Map<K | string, V | C>;
|
||||
map<M>(mapper: (value: V, key: K, iter: this) => M, context?: any): Map<K, M>;
|
||||
mapKeys<M>(mapper: (key: K, value: V, iter: this) => M, context?: any): Map<M, V>;
|
||||
mapEntries<KM, VM>(mapper: (entry: [K, V], index: number, iter: this) => [KM, VM], context?: any): Map<KM, VM>;
|
||||
flatMap<M>(mapper: (value: V, key: K, iter: this) => Iterable<M>, context?: any): Map<any, any>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
filter<F extends V>(predicate: (value: V, key: K, iter: this) => value is F, context?: any): Map<K, F>;
|
||||
filter(predicate: (value: V, key: K, iter: this) => any, context?: any): this;
|
||||
}
|
||||
@@ -290,28 +147,18 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
function isOrderedMap(maybeOrderedMap: any): maybeOrderedMap is OrderedMap<any, any>;
|
||||
}
|
||||
export function OrderedMap<K, V>(collection: Iterable<[K, V]>): OrderedMap<K, V>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
export function OrderedMap<T>(collection: Iterable<Iterable<T>>): OrderedMap<T, T>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
export function OrderedMap<V>(obj: {[key: string]: V}): OrderedMap<string, V>;
|
||||
export function OrderedMap<K, V>(): OrderedMap<K, V>;
|
||||
export function OrderedMap(): OrderedMap<any, any>;
|
||||
export interface OrderedMap<K, V> extends Map<K, V> {
|
||||
// Sequence algorithms
|
||||
concat<KC, VC>(...collections: Array<Iterable<[KC, VC]>>): OrderedMap<K | KC, V | VC>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
concat<C>(...collections: Array<{[key: string]: C}>): OrderedMap<K | string, V | C>;
|
||||
map<M>(mapper: (value: V, key: K, iter: this) => M, context?: any): OrderedMap<K, M>;
|
||||
mapKeys<M>(mapper: (key: K, value: V, iter: this) => M, context?: any): OrderedMap<M, V>;
|
||||
mapEntries<KM, VM>(mapper: (entry: [K, V], index: number, iter: this) => [KM, VM], context?: any): OrderedMap<KM, VM>;
|
||||
flatMap<M>(mapper: (value: V, key: K, iter: this) => Iterable<M>, context?: any): OrderedMap<any, any>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
filter<F extends V>(predicate: (value: V, key: K, iter: this) => value is F, context?: any): OrderedMap<K, F>;
|
||||
filter(predicate: (value: V, key: K, iter: this) => any, context?: any): this;
|
||||
}
|
||||
@@ -321,21 +168,11 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
function fromKeys<T>(iter: Collection<T, any>): Set<T>;
|
||||
function fromKeys(obj: {[key: string]: any}): Set<string>;
|
||||
function intersect<T>(sets: Iterable<Iterable<T>>): Set<T>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
function union<T>(sets: Iterable<Iterable<T>>): Set<T>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
}
|
||||
export function Set(): Set<any>;
|
||||
export function Set<T>(): Set<T>;
|
||||
export function Set<T>(collection: Iterable<T>): Set<T>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
export interface Set<T> extends Collection.Set<T> {
|
||||
// Persistent changes
|
||||
add(value: T): this;
|
||||
@@ -352,12 +189,8 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
asImmutable(): this;
|
||||
// Sequence algorithms
|
||||
concat<C>(...valuesOrCollections: Array<Iterable<C> | C>): Set<T | C>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
map<M>(mapper: (value: T, key: never, iter: this) => M, context?: any): Set<M>;
|
||||
flatMap<M>(mapper: (value: T, key: never, iter: this) => Iterable<M>, context?: any): Set<M>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
filter<F extends T>(predicate: (value: T, key: never, iter: this) => value is F, context?: any): Set<F>;
|
||||
filter(predicate: (value: T, key: never, iter: this) => any, context?: any): this;
|
||||
}
|
||||
@@ -370,17 +203,11 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
export function OrderedSet(): OrderedSet<any>;
|
||||
export function OrderedSet<T>(): OrderedSet<T>;
|
||||
export function OrderedSet<T>(collection: Iterable<T>): OrderedSet<T>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
export interface OrderedSet<T> extends Set<T> {
|
||||
// Sequence algorithms
|
||||
concat<C>(...valuesOrCollections: Array<Iterable<C> | C>): OrderedSet<T | C>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
map<M>(mapper: (value: T, key: never, iter: this) => M, context?: any): OrderedSet<M>;
|
||||
flatMap<M>(mapper: (value: T, key: never, iter: this) => Iterable<M>, context?: any): OrderedSet<M>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
filter<F extends T>(predicate: (value: T, key: never, iter: this) => value is F, context?: any): OrderedSet<F>;
|
||||
filter(predicate: (value: T, key: never, iter: this) => any, context?: any): this;
|
||||
zip(...collections: Array<Collection<any, any>>): OrderedSet<any>;
|
||||
@@ -395,8 +222,6 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
export function Stack(): Stack<any>;
|
||||
export function Stack<T>(): Stack<T>;
|
||||
export function Stack<T>(collection: Iterable<T>): Stack<T>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
export interface Stack<T> extends Collection.Indexed<T> {
|
||||
// Reading values
|
||||
peek(): T | undefined;
|
||||
@@ -404,13 +229,9 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
clear(): Stack<T>;
|
||||
unshift(...values: Array<T>): Stack<T>;
|
||||
unshiftAll(iter: Iterable<T>): Stack<T>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
shift(): Stack<T>;
|
||||
push(...values: Array<T>): Stack<T>;
|
||||
pushAll(iter: Iterable<T>): Stack<T>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
pop(): Stack<T>;
|
||||
// Transient changes
|
||||
withMutations(mutator: (mutable: this) => any): this;
|
||||
@@ -418,12 +239,8 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
asImmutable(): this;
|
||||
// Sequence algorithms
|
||||
concat<C>(...valuesOrCollections: Array<Iterable<C> | C>): Stack<T | C>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
map<M>(mapper: (value: T, key: number, iter: this) => M, context?: any): Stack<M>;
|
||||
flatMap<M>(mapper: (value: T, key: number, iter: this) => Iterable<M>, context?: any): Stack<M>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
filter<F extends T>(predicate: (value: T, index: number, iter: this) => value is F, context?: any): Set<F>;
|
||||
filter(predicate: (value: T, index: number, iter: this) => any, context?: any): this;
|
||||
}
|
||||
@@ -434,11 +251,7 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
export function getDescriptiveName(record: Instance<any>): string;
|
||||
export interface Class<T extends Object> {
|
||||
(values?: Partial<T> | Iterable<[string, any]>): Instance<T> & Readonly<T>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
new (values?: Partial<T> | Iterable<[string, any]>): Instance<T> & Readonly<T>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
}
|
||||
export interface Instance<T extends Object> {
|
||||
readonly size: number;
|
||||
@@ -447,11 +260,7 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
get<K extends keyof T>(key: K): T[K];
|
||||
// Reading deep values
|
||||
hasIn(keyPath: Iterable<any>): boolean;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
getIn(keyPath: Iterable<any>): any;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
// Value equality
|
||||
equals(other: any): boolean;
|
||||
hashCode(): number;
|
||||
@@ -459,39 +268,19 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
set<K extends keyof T>(key: K, value: T[K]): this;
|
||||
update<K extends keyof T>(key: K, updater: (value: T[K]) => T[K]): this;
|
||||
merge(...collections: Array<Partial<T> | Iterable<[string, any]>>): this;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
mergeDeep(...collections: Array<Partial<T> | Iterable<[string, any]>>): this;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
mergeWith(merger: (oldVal: any, newVal: any, key: keyof T) => any, ...collections: Array<Partial<T> | Iterable<[string, any]>>): this;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
mergeDeepWith(merger: (oldVal: any, newVal: any, key: any) => any, ...collections: Array<Partial<T> | Iterable<[string, any]>>): this;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
delete<K extends keyof T>(key: K): this;
|
||||
remove<K extends keyof T>(key: K): this;
|
||||
clear(): this;
|
||||
// Deep persistent changes
|
||||
setIn(keyPath: Iterable<any>, value: any): this;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
updateIn(keyPath: Iterable<any>, updater: (value: any) => any): this;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
mergeIn(keyPath: Iterable<any>, ...collections: Array<any>): this;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
mergeDeepIn(keyPath: Iterable<any>, ...collections: Array<any>): this;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
deleteIn(keyPath: Iterable<any>): this;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
removeIn(keyPath: Iterable<any>): this;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
// Conversion to JavaScript types
|
||||
toJS(): { [K in keyof T]: any };
|
||||
toJSON(): T;
|
||||
@@ -503,10 +292,6 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
// Sequence algorithms
|
||||
toSeq(): Seq.Keyed<keyof T, T[keyof T]>;
|
||||
[Symbol.iterator](): IterableIterator<[keyof T, T[keyof T]]>;
|
||||
~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Symbol'.
|
||||
~~~~~~~~~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'IterableIterator'.
|
||||
}
|
||||
}
|
||||
export function Record<T>(defaultValues: T, name?: string): Record.Class<T>;
|
||||
@@ -515,8 +300,6 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
function of<T>(...values: Array<T>): Seq.Indexed<T>;
|
||||
export module Keyed {}
|
||||
export function Keyed<K, V>(collection: Iterable<[K, V]>): Seq.Keyed<K, V>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
export function Keyed<V>(obj: {[key: string]: V}): Seq.Keyed<string, V>;
|
||||
export function Keyed<K, V>(): Seq.Keyed<K, V>;
|
||||
export function Keyed(): Seq.Keyed<any, any>;
|
||||
@@ -525,15 +308,11 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
toJSON(): { [key: string]: V };
|
||||
toSeq(): this;
|
||||
concat<KC, VC>(...collections: Array<Iterable<[KC, VC]>>): Seq.Keyed<K | KC, V | VC>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
concat<C>(...collections: Array<{[key: string]: C}>): Seq.Keyed<K | string, V | C>;
|
||||
map<M>(mapper: (value: V, key: K, iter: this) => M, context?: any): Seq.Keyed<K, M>;
|
||||
mapKeys<M>(mapper: (key: K, value: V, iter: this) => M, context?: any): Seq.Keyed<M, V>;
|
||||
mapEntries<KM, VM>(mapper: (entry: [K, V], index: number, iter: this) => [KM, VM], context?: any): Seq.Keyed<KM, VM>;
|
||||
flatMap<M>(mapper: (value: V, key: K, iter: this) => Iterable<M>, context?: any): Seq.Keyed<any, any>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
filter<F extends V>(predicate: (value: V, key: K, iter: this) => value is F, context?: any): Seq.Keyed<K, F>;
|
||||
filter(predicate: (value: V, key: K, iter: this) => any, context?: any): this;
|
||||
}
|
||||
@@ -543,19 +322,13 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
export function Indexed(): Seq.Indexed<any>;
|
||||
export function Indexed<T>(): Seq.Indexed<T>;
|
||||
export function Indexed<T>(collection: Iterable<T>): Seq.Indexed<T>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
export interface Indexed<T> extends Seq<number, T>, Collection.Indexed<T> {
|
||||
toJS(): Array<any>;
|
||||
toJSON(): Array<T>;
|
||||
toSeq(): this;
|
||||
concat<C>(...valuesOrCollections: Array<Iterable<C> | C>): Seq.Indexed<T | C>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
map<M>(mapper: (value: T, key: number, iter: this) => M, context?: any): Seq.Indexed<M>;
|
||||
flatMap<M>(mapper: (value: T, key: number, iter: this) => Iterable<M>, context?: any): Seq.Indexed<M>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
filter<F extends T>(predicate: (value: T, index: number, iter: this) => value is F, context?: any): Seq.Indexed<F>;
|
||||
filter(predicate: (value: T, index: number, iter: this) => any, context?: any): this;
|
||||
}
|
||||
@@ -565,19 +338,13 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
export function Set(): Seq.Set<any>;
|
||||
export function Set<T>(): Seq.Set<T>;
|
||||
export function Set<T>(collection: Iterable<T>): Seq.Set<T>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
export interface Set<T> extends Seq<never, T>, Collection.Set<T> {
|
||||
toJS(): Array<any>;
|
||||
toJSON(): Array<T>;
|
||||
toSeq(): this;
|
||||
concat<C>(...valuesOrCollections: Array<Iterable<C> | C>): Seq.Set<T | C>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
map<M>(mapper: (value: T, key: never, iter: this) => M, context?: any): Seq.Set<M>;
|
||||
flatMap<M>(mapper: (value: T, key: never, iter: this) => Iterable<M>, context?: any): Seq.Set<M>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
filter<F extends T>(predicate: (value: T, key: never, iter: this) => value is F, context?: any): Seq.Set<F>;
|
||||
filter(predicate: (value: T, key: never, iter: this) => any, context?: any): this;
|
||||
}
|
||||
@@ -587,8 +354,6 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
export function Seq<T>(collection: Collection.Indexed<T>): Seq.Indexed<T>;
|
||||
export function Seq<T>(collection: Collection.Set<T>): Seq.Set<T>;
|
||||
export function Seq<T>(collection: Iterable<T>): Seq.Indexed<T>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
export function Seq<V>(obj: {[key: string]: V}): Seq.Keyed<string, V>;
|
||||
export function Seq(): Seq<any, any>;
|
||||
export interface Seq<K, V> extends Collection<K, V> {
|
||||
@@ -598,8 +363,6 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
// Sequence algorithms
|
||||
map<M>(mapper: (value: V, key: K, iter: this) => M, context?: any): Seq<K, M>;
|
||||
flatMap<M>(mapper: (value: V, key: K, iter: this) => Iterable<M>, context?: any): Seq<K, M>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
filter<F extends V>(predicate: (value: V, key: K, iter: this) => value is F, context?: any): Seq<K, F>;
|
||||
filter(predicate: (value: V, key: K, iter: this) => any, context?: any): this;
|
||||
}
|
||||
@@ -610,8 +373,6 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
function isOrdered(maybeOrdered: any): boolean;
|
||||
export module Keyed {}
|
||||
export function Keyed<K, V>(collection: Iterable<[K, V]>): Collection.Keyed<K, V>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
export function Keyed<V>(obj: {[key: string]: V}): Collection.Keyed<string, V>;
|
||||
export interface Keyed<K, V> extends Collection<K, V> {
|
||||
~~~~~
|
||||
@@ -625,27 +386,17 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
// Sequence functions
|
||||
flip(): this;
|
||||
concat<KC, VC>(...collections: Array<Iterable<[KC, VC]>>): Collection.Keyed<K | KC, V | VC>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
concat<C>(...collections: Array<{[key: string]: C}>): Collection.Keyed<K | string, V | C>;
|
||||
map<M>(mapper: (value: V, key: K, iter: this) => M, context?: any): Collection.Keyed<K, M>;
|
||||
mapKeys<M>(mapper: (key: K, value: V, iter: this) => M, context?: any): Collection.Keyed<M, V>;
|
||||
mapEntries<KM, VM>(mapper: (entry: [K, V], index: number, iter: this) => [KM, VM], context?: any): Collection.Keyed<KM, VM>;
|
||||
flatMap<M>(mapper: (value: V, key: K, iter: this) => Iterable<M>, context?: any): Collection.Keyed<any, any>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
filter<F extends V>(predicate: (value: V, key: K, iter: this) => value is F, context?: any): Collection.Keyed<K, F>;
|
||||
filter(predicate: (value: V, key: K, iter: this) => any, context?: any): this;
|
||||
[Symbol.iterator](): IterableIterator<[K, V]>;
|
||||
~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Symbol'.
|
||||
~~~~~~~~~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'IterableIterator'.
|
||||
}
|
||||
export module Indexed {}
|
||||
export function Indexed<T>(collection: Iterable<T>): Collection.Indexed<T>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
export interface Indexed<T> extends Collection<number, T> {
|
||||
~~~~~~~
|
||||
!!! error TS2430: Interface 'Indexed<T>' incorrectly extends interface 'Collection<number, T>'.
|
||||
@@ -675,24 +426,14 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
findLastIndex(predicate: (value: T, index: number, iter: this) => boolean, context?: any): number;
|
||||
// Sequence algorithms
|
||||
concat<C>(...valuesOrCollections: Array<Iterable<C> | C>): Collection.Indexed<T | C>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
map<M>(mapper: (value: T, key: number, iter: this) => M, context?: any): Collection.Indexed<M>;
|
||||
flatMap<M>(mapper: (value: T, key: number, iter: this) => Iterable<M>, context?: any): Collection.Indexed<M>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
filter<F extends T>(predicate: (value: T, index: number, iter: this) => value is F, context?: any): Collection.Indexed<F>;
|
||||
filter(predicate: (value: T, index: number, iter: this) => any, context?: any): this;
|
||||
[Symbol.iterator](): IterableIterator<T>;
|
||||
~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Symbol'.
|
||||
~~~~~~~~~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'IterableIterator'.
|
||||
}
|
||||
export module Set {}
|
||||
export function Set<T>(collection: Iterable<T>): Collection.Set<T>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
export interface Set<T> extends Collection<never, T> {
|
||||
~~~
|
||||
!!! error TS2430: Interface 'Set<T>' incorrectly extends interface 'Collection<never, T>'.
|
||||
@@ -704,25 +445,15 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
toSeq(): Seq.Set<T>;
|
||||
// Sequence algorithms
|
||||
concat<C>(...valuesOrCollections: Array<Iterable<C> | C>): Collection.Set<T | C>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
map<M>(mapper: (value: T, key: never, iter: this) => M, context?: any): Collection.Set<M>;
|
||||
flatMap<M>(mapper: (value: T, key: never, iter: this) => Iterable<M>, context?: any): Collection.Set<M>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
filter<F extends T>(predicate: (value: T, key: never, iter: this) => value is F, context?: any): Collection.Set<F>;
|
||||
filter(predicate: (value: T, key: never, iter: this) => any, context?: any): this;
|
||||
[Symbol.iterator](): IterableIterator<T>;
|
||||
~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Symbol'.
|
||||
~~~~~~~~~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'IterableIterator'.
|
||||
}
|
||||
}
|
||||
export function Collection<I extends Collection<any, any>>(collection: I): I;
|
||||
export function Collection<T>(collection: Iterable<T>): Collection.Indexed<T>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
export function Collection<V>(obj: {[key: string]: V}): Collection.Keyed<string, V>;
|
||||
export interface Collection<K, V> extends ValueObject {
|
||||
// Value equality
|
||||
@@ -738,11 +469,7 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
last(): V | undefined;
|
||||
// Reading deep values
|
||||
getIn(searchKeyPath: Iterable<any>, notSetValue?: any): any;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
hasIn(searchKeyPath: Iterable<any>): boolean;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
// Persistent changes
|
||||
update<R>(updater: (value: this) => R): R;
|
||||
// Conversion to JavaScript types
|
||||
@@ -764,14 +491,8 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
toSetSeq(): Seq.Set<V>;
|
||||
// Iterators
|
||||
keys(): IterableIterator<K>;
|
||||
~~~~~~~~~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'IterableIterator'.
|
||||
values(): IterableIterator<V>;
|
||||
~~~~~~~~~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'IterableIterator'.
|
||||
entries(): IterableIterator<[K, V]>;
|
||||
~~~~~~~~~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'IterableIterator'.
|
||||
// Collections (Seq)
|
||||
keySeq(): Seq.Indexed<K>;
|
||||
valueSeq(): Seq.Indexed<V>;
|
||||
@@ -804,8 +525,6 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
flatten(depth?: number): Collection<any, any>;
|
||||
flatten(shallow?: boolean): Collection<any, any>;
|
||||
flatMap<M>(mapper: (value: V, key: K, iter: this) => Iterable<M>, context?: any): Collection<K, M>;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
// Reducing a value
|
||||
reduce<R>(reducer: (reduction: R, value: V, key: K, iter: this) => R, initialReduction: R, context?: any): R;
|
||||
reduce<R>(reducer: (reduction: V | R, value: V, key: K, iter: this) => R): R;
|
||||
@@ -833,11 +552,7 @@ tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Ite
|
||||
minBy<C>(comparatorValueMapper: (value: V, key: K, iter: this) => C, comparator?: (valueA: C, valueB: C) => number): V | undefined;
|
||||
// Comparison
|
||||
isSubset(iter: Iterable<V>): boolean;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
isSuperset(iter: Iterable<V>): boolean;
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
readonly size: number;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
=== tests/cases/conformance/es6/computedProperties/computedPropertyNames46_ES5.ts ===
|
||||
var o = {
|
||||
>o : { [x: number]: number; }
|
||||
>{ ["" || 0]: 0} : { [x: number]: number; }
|
||||
>o : { ["" || 0]: number; }
|
||||
>{ ["" || 0]: 0} : { ["" || 0]: number; }
|
||||
|
||||
["" || 0]: 0
|
||||
>"" || 0 : 0
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
=== tests/cases/conformance/es6/computedProperties/computedPropertyNames46_ES6.ts ===
|
||||
var o = {
|
||||
>o : { [x: number]: number; }
|
||||
>{ ["" || 0]: 0} : { [x: number]: number; }
|
||||
>o : { ["" || 0]: number; }
|
||||
>{ ["" || 0]: 0} : { ["" || 0]: number; }
|
||||
|
||||
["" || 0]: 0
|
||||
>"" || 0 : 0
|
||||
|
||||
@@ -8,8 +8,8 @@ enum E2 { x }
|
||||
>x : E2
|
||||
|
||||
var o = {
|
||||
>o : { [x: number]: number; }
|
||||
>{ [E1.x || E2.x]: 0} : { [x: number]: number; }
|
||||
>o : { [E1.x || E2.x]: number; }
|
||||
>{ [E1.x || E2.x]: 0} : { [E1.x || E2.x]: number; }
|
||||
|
||||
[E1.x || E2.x]: 0
|
||||
>E1.x || E2.x : E2
|
||||
|
||||
@@ -8,8 +8,8 @@ enum E2 { x }
|
||||
>x : E2
|
||||
|
||||
var o = {
|
||||
>o : { [x: number]: number; }
|
||||
>{ [E1.x || E2.x]: 0} : { [x: number]: number; }
|
||||
>o : { [E1.x || E2.x]: number; }
|
||||
>{ [E1.x || E2.x]: 0} : { [E1.x || E2.x]: number; }
|
||||
|
||||
[E1.x || E2.x]: 0
|
||||
>E1.x || E2.x : E2
|
||||
|
||||
@@ -28,7 +28,7 @@ extractIndexer({
|
||||
extractIndexer({
|
||||
>extractIndexer({ [E.x]: ""}) : string
|
||||
>extractIndexer : <T>(p: { [n: number]: T; }) => T
|
||||
>{ [E.x]: ""} : { [x: number]: string; }
|
||||
>{ [E.x]: ""} : { [E.x]: string; }
|
||||
|
||||
[E.x]: ""
|
||||
>E.x : E
|
||||
@@ -41,7 +41,7 @@ extractIndexer({
|
||||
extractIndexer({
|
||||
>extractIndexer({ ["" || 0]: ""}) : string
|
||||
>extractIndexer : <T>(p: { [n: number]: T; }) => T
|
||||
>{ ["" || 0]: ""} : { [x: number]: string; }
|
||||
>{ ["" || 0]: ""} : { ["" || 0]: string; }
|
||||
|
||||
["" || 0]: ""
|
||||
>"" || 0 : 0
|
||||
|
||||
@@ -28,7 +28,7 @@ extractIndexer({
|
||||
extractIndexer({
|
||||
>extractIndexer({ [E.x]: ""}) : string
|
||||
>extractIndexer : <T>(p: { [n: number]: T; }) => T
|
||||
>{ [E.x]: ""} : { [x: number]: string; }
|
||||
>{ [E.x]: ""} : { [E.x]: string; }
|
||||
|
||||
[E.x]: ""
|
||||
>E.x : E
|
||||
@@ -41,7 +41,7 @@ extractIndexer({
|
||||
extractIndexer({
|
||||
>extractIndexer({ ["" || 0]: ""}) : string
|
||||
>extractIndexer : <T>(p: { [n: number]: T; }) => T
|
||||
>{ ["" || 0]: ""} : { [x: number]: string; }
|
||||
>{ ["" || 0]: ""} : { ["" || 0]: string; }
|
||||
|
||||
["" || 0]: ""
|
||||
>"" || 0 : 0
|
||||
|
||||
@@ -9,8 +9,8 @@ var a: any;
|
||||
>a : any
|
||||
|
||||
var v = {
|
||||
>v : { [x: string]: string | number; [x: number]: string | number; [""]: number; [0]: number; }
|
||||
>{ [s]: 0, [n]: n, [s + s]: 1, [s + n]: 2, [+s]: s, [""]: 0, [0]: 0, [a]: 1, [<any>true]: 0, [`hello bye`]: 0, [`hello ${a} bye`]: 0} : { [x: string]: string | number; [x: number]: string | number; [""]: number; [0]: number; }
|
||||
>v : { [x: string]: string | number; [x: number]: string | number; [""]: number; [0]: number; [`hello bye`]: number; }
|
||||
>{ [s]: 0, [n]: n, [s + s]: 1, [s + n]: 2, [+s]: s, [""]: 0, [0]: 0, [a]: 1, [<any>true]: 0, [`hello bye`]: 0, [`hello ${a} bye`]: 0} : { [x: string]: string | number; [x: number]: string | number; [""]: number; [0]: number; [`hello bye`]: number; }
|
||||
|
||||
[s]: 0,
|
||||
>s : string
|
||||
|
||||
@@ -9,8 +9,8 @@ var a: any;
|
||||
>a : any
|
||||
|
||||
var v = {
|
||||
>v : { [x: string]: string | number; [x: number]: string | number; [""]: number; [0]: number; }
|
||||
>{ [s]: 0, [n]: n, [s + s]: 1, [s + n]: 2, [+s]: s, [""]: 0, [0]: 0, [a]: 1, [<any>true]: 0, [`hello bye`]: 0, [`hello ${a} bye`]: 0} : { [x: string]: string | number; [x: number]: string | number; [""]: number; [0]: number; }
|
||||
>v : { [x: string]: string | number; [x: number]: string | number; [""]: number; [0]: number; [`hello bye`]: number; }
|
||||
>{ [s]: 0, [n]: n, [s + s]: 1, [s + n]: 2, [+s]: s, [""]: 0, [0]: 0, [a]: 1, [<any>true]: 0, [`hello bye`]: 0, [`hello ${a} bye`]: 0} : { [x: string]: string | number; [x: number]: string | number; [""]: number; [0]: number; [`hello bye`]: number; }
|
||||
|
||||
[s]: 0,
|
||||
>s : string
|
||||
|
||||
@@ -6,8 +6,8 @@ enum E {
|
||||
>member : E
|
||||
}
|
||||
var v = {
|
||||
>v : { [x: number]: number; }
|
||||
>{ [E.member]: 0} : { [x: number]: number; }
|
||||
>v : { [E.member]: number; }
|
||||
>{ [E.member]: 0} : { [E.member]: number; }
|
||||
|
||||
[E.member]: 0
|
||||
>E.member : E
|
||||
|
||||
@@ -6,8 +6,8 @@ enum E {
|
||||
>member : E
|
||||
}
|
||||
var v = {
|
||||
>v : { [x: number]: number; }
|
||||
>{ [E.member]: 0} : { [x: number]: number; }
|
||||
>v : { [E.member]: number; }
|
||||
>{ [E.member]: 0} : { [E.member]: number; }
|
||||
|
||||
[E.member]: 0
|
||||
>E.member : E
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
//// [tests/cases/compiler/duplicatePackage_packageIdIncludesSubModule.ts] ////
|
||||
|
||||
//// [Foo.d.ts]
|
||||
export default class Foo {
|
||||
protected source: boolean;
|
||||
}
|
||||
|
||||
//// [Bar.d.ts]
|
||||
// This is *not* the same!
|
||||
export const x: number;
|
||||
|
||||
//// [package.json]
|
||||
{ "name": "foo", "version": "1.2.3" }
|
||||
|
||||
//// [index.ts]
|
||||
import Foo from "foo/Foo";
|
||||
import { x } from "foo/Bar";
|
||||
|
||||
|
||||
//// [index.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
@@ -0,0 +1,20 @@
|
||||
=== /index.ts ===
|
||||
import Foo from "foo/Foo";
|
||||
>Foo : Symbol(Foo, Decl(index.ts, 0, 6))
|
||||
|
||||
import { x } from "foo/Bar";
|
||||
>x : Symbol(x, Decl(index.ts, 1, 8))
|
||||
|
||||
=== /node_modules/foo/Foo.d.ts ===
|
||||
export default class Foo {
|
||||
>Foo : Symbol(Foo, Decl(Foo.d.ts, 0, 0))
|
||||
|
||||
protected source: boolean;
|
||||
>source : Symbol(Foo.source, Decl(Foo.d.ts, 0, 26))
|
||||
}
|
||||
|
||||
=== /node_modules/foo/Bar.d.ts ===
|
||||
// This is *not* the same!
|
||||
export const x: number;
|
||||
>x : Symbol(x, Decl(Bar.d.ts, 1, 12))
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
=== /index.ts ===
|
||||
import Foo from "foo/Foo";
|
||||
>Foo : typeof Foo
|
||||
|
||||
import { x } from "foo/Bar";
|
||||
>x : number
|
||||
|
||||
=== /node_modules/foo/Foo.d.ts ===
|
||||
export default class Foo {
|
||||
>Foo : Foo
|
||||
|
||||
protected source: boolean;
|
||||
>source : boolean
|
||||
}
|
||||
|
||||
=== /node_modules/foo/Bar.d.ts ===
|
||||
// This is *not* the same!
|
||||
export const x: number;
|
||||
>x : number
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
//// [tests/cases/compiler/duplicatePackage_referenceTypes.ts] ////
|
||||
|
||||
//// [index.d.ts]
|
||||
/// <reference types="foo" />
|
||||
import { Foo } from "foo";
|
||||
export const foo: Foo;
|
||||
|
||||
//// [index.d.ts]
|
||||
export class Foo { private x; }
|
||||
|
||||
//// [package.json]
|
||||
{ "name": "foo", "version": "1.2.3" }
|
||||
|
||||
//// [index.d.ts]
|
||||
export class Foo { private x; }
|
||||
|
||||
//// [package.json]
|
||||
{ "name": "foo", "version": "1.2.3" }
|
||||
|
||||
//// [index.ts]
|
||||
import * as a from "a";
|
||||
import { Foo } from "foo";
|
||||
|
||||
let foo: Foo = a.foo;
|
||||
|
||||
|
||||
//// [index.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var a = require("a");
|
||||
var foo = a.foo;
|
||||
@@ -0,0 +1,33 @@
|
||||
=== /index.ts ===
|
||||
import * as a from "a";
|
||||
>a : Symbol(a, Decl(index.ts, 0, 6))
|
||||
|
||||
import { Foo } from "foo";
|
||||
>Foo : Symbol(Foo, Decl(index.ts, 1, 8))
|
||||
|
||||
let foo: Foo = a.foo;
|
||||
>foo : Symbol(foo, Decl(index.ts, 3, 3))
|
||||
>Foo : Symbol(Foo, Decl(index.ts, 1, 8))
|
||||
>a.foo : Symbol(a.foo, Decl(index.d.ts, 2, 12))
|
||||
>a : Symbol(a, Decl(index.ts, 0, 6))
|
||||
>foo : Symbol(a.foo, Decl(index.d.ts, 2, 12))
|
||||
|
||||
=== /node_modules/a/index.d.ts ===
|
||||
/// <reference types="foo" />
|
||||
import { Foo } from "foo";
|
||||
>Foo : Symbol(Foo, Decl(index.d.ts, 1, 8))
|
||||
|
||||
export const foo: Foo;
|
||||
>foo : Symbol(foo, Decl(index.d.ts, 2, 12))
|
||||
>Foo : Symbol(Foo, Decl(index.d.ts, 1, 8))
|
||||
|
||||
=== /node_modules/a/node_modules/foo/index.d.ts ===
|
||||
export class Foo { private x; }
|
||||
>Foo : Symbol(Foo, Decl(index.d.ts, 0, 0))
|
||||
>x : Symbol(Foo.x, Decl(index.d.ts, 0, 18))
|
||||
|
||||
=== /node_modules/@types/foo/index.d.ts ===
|
||||
export class Foo { private x; }
|
||||
>Foo : Symbol(Foo, Decl(index.d.ts, 0, 0))
|
||||
>x : Symbol(Foo.x, Decl(index.d.ts, 0, 18))
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
=== /index.ts ===
|
||||
import * as a from "a";
|
||||
>a : typeof a
|
||||
|
||||
import { Foo } from "foo";
|
||||
>Foo : typeof Foo
|
||||
|
||||
let foo: Foo = a.foo;
|
||||
>foo : Foo
|
||||
>Foo : Foo
|
||||
>a.foo : Foo
|
||||
>a : typeof a
|
||||
>foo : Foo
|
||||
|
||||
=== /node_modules/a/index.d.ts ===
|
||||
/// <reference types="foo" />
|
||||
import { Foo } from "foo";
|
||||
>Foo : typeof Foo
|
||||
|
||||
export const foo: Foo;
|
||||
>foo : Foo
|
||||
>Foo : Foo
|
||||
|
||||
=== /node_modules/a/node_modules/foo/index.d.ts ===
|
||||
export class Foo { private x; }
|
||||
>Foo : Foo
|
||||
>x : any
|
||||
|
||||
=== /node_modules/@types/foo/index.d.ts ===
|
||||
export class Foo { private x; }
|
||||
>Foo : Foo
|
||||
>x : any
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
//// [tests/cases/compiler/duplicatePackage_subModule.ts] ////
|
||||
|
||||
//// [index.d.ts]
|
||||
import Foo from "foo/Foo";
|
||||
export const o: Foo;
|
||||
|
||||
//// [Foo.d.ts]
|
||||
export default class Foo {
|
||||
protected source: boolean;
|
||||
}
|
||||
|
||||
//// [package.json]
|
||||
{ "name": "foo", "version": "1.2.3" }
|
||||
|
||||
//// [Foo.d.ts]
|
||||
export default class Foo {
|
||||
protected source: boolean;
|
||||
}
|
||||
|
||||
//// [package.json]
|
||||
{ "name": "foo", "version": "1.2.3" }
|
||||
|
||||
//// [index.ts]
|
||||
import Foo from "foo/Foo";
|
||||
import * as a from "a";
|
||||
|
||||
const o: Foo = a.o;
|
||||
|
||||
|
||||
//// [index.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var a = require("a");
|
||||
var o = a.o;
|
||||
@@ -0,0 +1,38 @@
|
||||
=== /index.ts ===
|
||||
import Foo from "foo/Foo";
|
||||
>Foo : Symbol(Foo, Decl(index.ts, 0, 6))
|
||||
|
||||
import * as a from "a";
|
||||
>a : Symbol(a, Decl(index.ts, 1, 6))
|
||||
|
||||
const o: Foo = a.o;
|
||||
>o : Symbol(o, Decl(index.ts, 3, 5))
|
||||
>Foo : Symbol(Foo, Decl(index.ts, 0, 6))
|
||||
>a.o : Symbol(a.o, Decl(index.d.ts, 1, 12))
|
||||
>a : Symbol(a, Decl(index.ts, 1, 6))
|
||||
>o : Symbol(a.o, Decl(index.d.ts, 1, 12))
|
||||
|
||||
=== /node_modules/a/index.d.ts ===
|
||||
import Foo from "foo/Foo";
|
||||
>Foo : Symbol(Foo, Decl(index.d.ts, 0, 6))
|
||||
|
||||
export const o: Foo;
|
||||
>o : Symbol(o, Decl(index.d.ts, 1, 12))
|
||||
>Foo : Symbol(Foo, Decl(index.d.ts, 0, 6))
|
||||
|
||||
=== /node_modules/a/node_modules/foo/Foo.d.ts ===
|
||||
export default class Foo {
|
||||
>Foo : Symbol(Foo, Decl(Foo.d.ts, 0, 0))
|
||||
|
||||
protected source: boolean;
|
||||
>source : Symbol(Foo.source, Decl(Foo.d.ts, 0, 26))
|
||||
}
|
||||
|
||||
=== /node_modules/foo/Foo.d.ts ===
|
||||
export default class Foo {
|
||||
>Foo : Symbol(Foo, Decl(Foo.d.ts, 0, 0))
|
||||
|
||||
protected source: boolean;
|
||||
>source : Symbol(Foo.source, Decl(Foo.d.ts, 0, 26))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
=== /index.ts ===
|
||||
import Foo from "foo/Foo";
|
||||
>Foo : typeof Foo
|
||||
|
||||
import * as a from "a";
|
||||
>a : typeof a
|
||||
|
||||
const o: Foo = a.o;
|
||||
>o : Foo
|
||||
>Foo : Foo
|
||||
>a.o : Foo
|
||||
>a : typeof a
|
||||
>o : Foo
|
||||
|
||||
=== /node_modules/a/index.d.ts ===
|
||||
import Foo from "foo/Foo";
|
||||
>Foo : typeof Foo
|
||||
|
||||
export const o: Foo;
|
||||
>o : Foo
|
||||
>Foo : Foo
|
||||
|
||||
=== /node_modules/a/node_modules/foo/Foo.d.ts ===
|
||||
export default class Foo {
|
||||
>Foo : Foo
|
||||
|
||||
protected source: boolean;
|
||||
>source : boolean
|
||||
}
|
||||
|
||||
=== /node_modules/foo/Foo.d.ts ===
|
||||
export default class Foo {
|
||||
>Foo : Foo
|
||||
|
||||
protected source: boolean;
|
||||
>source : boolean
|
||||
}
|
||||
|
||||
@@ -5,5 +5,5 @@ export var X;
|
||||
>X : any
|
||||
|
||||
export as namespace N
|
||||
>N : typeof N
|
||||
>N : typeof "tests/cases/compiler/exportAsNamespace"
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
// ==ORIGINAL==
|
||||
function foo() {
|
||||
let x = 10;
|
||||
x++;
|
||||
return;
|
||||
}
|
||||
// ==SCOPE::function 'foo'==
|
||||
function foo() {
|
||||
let x = 10;
|
||||
return newFunction();
|
||||
|
||||
function newFunction() {
|
||||
x++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// ==SCOPE::global scope==
|
||||
function foo() {
|
||||
let x = 10;
|
||||
x = newFunction(x);
|
||||
return;
|
||||
}
|
||||
function newFunction(x: number) {
|
||||
x++;
|
||||
return x;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// ==ORIGINAL==
|
||||
function test() {
|
||||
try {
|
||||
}
|
||||
finally {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
// ==SCOPE::function 'test'==
|
||||
function test() {
|
||||
try {
|
||||
}
|
||||
finally {
|
||||
return newFunction();
|
||||
}
|
||||
|
||||
function newFunction() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
// ==SCOPE::global scope==
|
||||
function test() {
|
||||
try {
|
||||
}
|
||||
finally {
|
||||
return newFunction();
|
||||
}
|
||||
}
|
||||
function newFunction() {
|
||||
return 1;
|
||||
}
|
||||
@@ -24,9 +24,9 @@ namespace A {
|
||||
|
||||
async function newFunction() {
|
||||
let y = 5;
|
||||
if(z) {
|
||||
await z1;
|
||||
}
|
||||
if (z) {
|
||||
await z1;
|
||||
}
|
||||
return foo();
|
||||
}
|
||||
}
|
||||
@@ -44,9 +44,9 @@ namespace A {
|
||||
|
||||
async function newFunction(z: number, z1: any) {
|
||||
let y = 5;
|
||||
if(z) {
|
||||
await z1;
|
||||
}
|
||||
if (z) {
|
||||
await z1;
|
||||
}
|
||||
return foo();
|
||||
}
|
||||
}
|
||||
@@ -64,9 +64,9 @@ namespace A {
|
||||
|
||||
async function newFunction(z: number, z1: any) {
|
||||
let y = 5;
|
||||
if(z) {
|
||||
await z1;
|
||||
}
|
||||
if (z) {
|
||||
await z1;
|
||||
}
|
||||
return foo();
|
||||
}
|
||||
}
|
||||
@@ -83,8 +83,8 @@ namespace A {
|
||||
}
|
||||
async function newFunction(z: number, z1: any, foo: () => void) {
|
||||
let y = 5;
|
||||
if(z) {
|
||||
await z1;
|
||||
}
|
||||
if (z) {
|
||||
await z1;
|
||||
}
|
||||
return foo();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(1,15): error TS1003: Identifier expected.
|
||||
tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(1,12): error TS2304: Cannot find name 'a'.
|
||||
tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(1,12): error TS2695: Left side of comma operator is unused and has no side effects.
|
||||
tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(1,16): error TS2304: Cannot find name 'b'.
|
||||
tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(1,16): error TS2695: Left side of comma operator is unused and has no side effects.
|
||||
tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(1,19): error TS2304: Cannot find name 'c'.
|
||||
tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(1,23): error TS1005: ';' expected.
|
||||
tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(1,26): error TS2304: Cannot find name 'a'.
|
||||
tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(1,28): error TS2304: Cannot find name 'b'.
|
||||
tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(1,30): error TS2304: Cannot find name 'c'.
|
||||
tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(2,12): error TS2695: Left side of comma operator is unused and has no side effects.
|
||||
@@ -18,16 +21,22 @@ tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(4,17): error TS1005
|
||||
tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(4,20): error TS2304: Cannot find name 'a'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts (18 errors) ====
|
||||
==== tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts (21 errors) ====
|
||||
var tt1 = (a, (b, c)) => a+b+c;
|
||||
~
|
||||
!!! error TS1003: Identifier expected.
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'a'.
|
||||
~
|
||||
!!! error TS2695: Left side of comma operator is unused and has no side effects.
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'b'.
|
||||
~
|
||||
!!! error TS2695: Left side of comma operator is unused and has no side effects.
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'c'.
|
||||
~~
|
||||
!!! error TS1005: ';' expected.
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'a'.
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'b'.
|
||||
~
|
||||
|
||||
@@ -5,10 +5,8 @@ var tt2 = ((a), b, c) => a+b+c;
|
||||
var tt3 = ((a)) => a;
|
||||
|
||||
//// [fatarrowfunctionsOptionalArgsErrors2.js]
|
||||
var tt1 = function (a, ) {
|
||||
if ( === void 0) { = (b, c); }
|
||||
return a + b + c;
|
||||
};
|
||||
var tt1 = (a, (b, c));
|
||||
a + b + c;
|
||||
var tt2 = ((a), b, c);
|
||||
a + b + c;
|
||||
var tt3 = ((a));
|
||||
|
||||
@@ -22,8 +22,6 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/functionConstrain
|
||||
Type 'void' is not assignable to type 'string'.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/functionConstraintSatisfaction2.ts(38,10): error TS2345: Argument of type 'U' is not assignable to parameter of type '(x: string) => string'.
|
||||
Type 'T' is not assignable to type '(x: string) => string'.
|
||||
Type '() => void' is not assignable to type '(x: string) => string'.
|
||||
Type 'void' is not assignable to type 'string'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/typeParameters/typeArgumentLists/functionConstraintSatisfaction2.ts (13 errors) ====
|
||||
@@ -102,7 +100,5 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/functionConstrain
|
||||
~
|
||||
!!! error TS2345: Argument of type 'U' is not assignable to parameter of type '(x: string) => string'.
|
||||
!!! error TS2345: Type 'T' is not assignable to type '(x: string) => string'.
|
||||
!!! error TS2345: Type '() => void' is not assignable to type '(x: string) => string'.
|
||||
!!! error TS2345: Type 'void' is not assignable to type 'string'.
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
//// [tests/cases/compiler/importShouldNotBeElidedInDeclarationEmit.ts] ////
|
||||
|
||||
//// [umd.d.ts]
|
||||
export as namespace UMD;
|
||||
|
||||
export type Thing = {
|
||||
a: number;
|
||||
}
|
||||
|
||||
export declare function makeThing(): Thing;
|
||||
//// [index.ts]
|
||||
import { makeThing } from "umd";
|
||||
export const thing = makeThing();
|
||||
|
||||
|
||||
//// [index.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var umd_1 = require("umd");
|
||||
exports.thing = umd_1.makeThing();
|
||||
|
||||
|
||||
//// [index.d.ts]
|
||||
export declare const thing: {
|
||||
a: number;
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
=== tests/cases/compiler/node_modules/umd.d.ts ===
|
||||
export as namespace UMD;
|
||||
>UMD : Symbol(UMD, Decl(umd.d.ts, 0, 0))
|
||||
|
||||
export type Thing = {
|
||||
>Thing : Symbol(Thing, Decl(umd.d.ts, 0, 24))
|
||||
|
||||
a: number;
|
||||
>a : Symbol(a, Decl(umd.d.ts, 2, 21))
|
||||
}
|
||||
|
||||
export declare function makeThing(): Thing;
|
||||
>makeThing : Symbol(makeThing, Decl(umd.d.ts, 4, 1))
|
||||
>Thing : Symbol(Thing, Decl(umd.d.ts, 0, 24))
|
||||
|
||||
=== tests/cases/compiler/index.ts ===
|
||||
import { makeThing } from "umd";
|
||||
>makeThing : Symbol(makeThing, Decl(index.ts, 0, 8))
|
||||
|
||||
export const thing = makeThing();
|
||||
>thing : Symbol(thing, Decl(index.ts, 1, 12))
|
||||
>makeThing : Symbol(makeThing, Decl(index.ts, 0, 8))
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user