Merge branch 'master' into addCodeFixMissingMethod

This commit is contained in:
Arthur Ozga
2017-05-30 15:20:59 -07:00
190 changed files with 6124 additions and 733 deletions
+1
View File
@@ -131,6 +131,7 @@ const es2017LibrarySource = [
"es2017.object.d.ts",
"es2017.sharedmemory.d.ts",
"es2017.string.d.ts",
"es2017.intl.d.ts",
];
const es2017LibrarySourceMap = es2017LibrarySource.map(function(source) {
+5 -3
View File
@@ -129,6 +129,7 @@ var harnessSources = harnessCoreSources.concat([
"initializeTSConfig.ts",
"printer.ts",
"textChanges.ts",
"telemetry.ts",
"transform.ts",
"customTransforms.ts",
].map(function (f) {
@@ -172,7 +173,8 @@ var es2016LibrarySourceMap = es2016LibrarySource.map(function (source) {
var es2017LibrarySource = [
"es2017.object.d.ts",
"es2017.sharedmemory.d.ts",
"es2017.string.d.ts"
"es2017.string.d.ts",
"es2017.intl.d.ts"
];
var es2017LibrarySourceMap = es2017LibrarySource.map(function (source) {
@@ -1078,7 +1080,7 @@ var loggedIOJsPath = builtLocalDirectory + 'loggedIO.js';
file(loggedIOJsPath, [builtLocalDirectory, loggedIOpath], function () {
var temp = builtLocalDirectory + 'temp';
jake.mkdirP(temp);
var options = "--types --outdir " + temp + ' ' + loggedIOpath;
var options = "--target es5 --lib es6 --types --outdir " + temp + ' ' + loggedIOpath;
var cmd = host + " " + LKGDirectory + compilerFilename + " " + options + " ";
console.log(cmd + "\n");
var ex = jake.createExec([cmd]);
@@ -1092,7 +1094,7 @@ file(loggedIOJsPath, [builtLocalDirectory, loggedIOpath], function () {
var instrumenterPath = harnessDirectory + 'instrumenter.ts';
var instrumenterJsPath = builtLocalDirectory + 'instrumenter.js';
compileFile(instrumenterJsPath, [instrumenterPath], [tscFile, instrumenterPath].concat(libraryTargets), [], /*useBuiltCompiler*/ true);
compileFile(instrumenterJsPath, [instrumenterPath], [tscFile, instrumenterPath].concat(libraryTargets), [], /*useBuiltCompiler*/ true, { lib: "es6", types: ["node"] });
desc("Builds an instrumented tsc.js");
task('tsc-instrumented', [loggedIOJsPath, instrumenterJsPath, tscFile], function () {
+2 -1
View File
@@ -21,4 +21,5 @@ and limitations under the License.
/// <reference path="lib.es2016.d.ts" />
/// <reference path="lib.es2017.object.d.ts" />
/// <reference path="lib.es2017.sharedmemory.d.ts" />
/// <reference path="lib.es2017.string.d.ts" />
/// <reference path="lib.es2017.string.d.ts" />
/// <reference path="lib.es2017.intl.d.ts" />
+1
View File
@@ -22,6 +22,7 @@ and limitations under the License.
/// <reference path="lib.es2017.object.d.ts" />
/// <reference path="lib.es2017.sharedmemory.d.ts" />
/// <reference path="lib.es2017.string.d.ts" />
/// <reference path="lib.es2017.intl.d.ts" />
declare type PropertyKey = string | number | symbol;
+1
View File
@@ -56880,6 +56880,7 @@ var ts;
"es2017.object": "lib.es2017.object.d.ts",
"es2017.sharedmemory": "lib.es2017.sharedmemory.d.ts",
"es2017.string": "lib.es2017.string.d.ts",
"es2017.intl": "lib.es2017.intl.d.ts",
"esnext.asynciterable": "lib.esnext.asynciterable.d.ts",
}),
},
+1
View File
@@ -56898,6 +56898,7 @@ var ts;
"es2017.object": "lib.es2017.object.d.ts",
"es2017.sharedmemory": "lib.es2017.sharedmemory.d.ts",
"es2017.string": "lib.es2017.string.d.ts",
"es2017.intl": "lib.es2017.intl.d.ts",
"esnext.asynciterable": "lib.esnext.asynciterable.d.ts",
}),
},
+1
View File
@@ -6079,6 +6079,7 @@ var ts;
"es2017.object": "lib.es2017.object.d.ts",
"es2017.sharedmemory": "lib.es2017.sharedmemory.d.ts",
"es2017.string": "lib.es2017.string.d.ts",
"es2017.intl": "lib.es2017.intl.d.ts",
"esnext.asynciterable": "lib.esnext.asynciterable.d.ts",
}),
},
+1
View File
@@ -69276,6 +69276,7 @@ var ts;
"es2017.object": "lib.es2017.object.d.ts",
"es2017.sharedmemory": "lib.es2017.sharedmemory.d.ts",
"es2017.string": "lib.es2017.string.d.ts",
"es2017.intl": "lib.es2017.intl.d.ts",
"esnext.asynciterable": "lib.esnext.asynciterable.d.ts",
}),
},
+1
View File
@@ -69276,6 +69276,7 @@ var ts;
"es2017.object": "lib.es2017.object.d.ts",
"es2017.sharedmemory": "lib.es2017.sharedmemory.d.ts",
"es2017.string": "lib.es2017.string.d.ts",
"es2017.intl": "lib.es2017.intl.d.ts",
"esnext.asynciterable": "lib.esnext.asynciterable.d.ts",
}),
},
+1
View File
@@ -6071,6 +6071,7 @@ var ts;
"es2017.object": "lib.es2017.object.d.ts",
"es2017.sharedmemory": "lib.es2017.sharedmemory.d.ts",
"es2017.string": "lib.es2017.string.d.ts",
"es2017.intl": "lib.es2017.intl.d.ts",
"esnext.asynciterable": "lib.esnext.asynciterable.d.ts",
}),
},
+2 -2
View File
@@ -59,7 +59,7 @@
"gulp-insert": "latest",
"gulp-newer": "latest",
"gulp-sourcemaps": "latest",
"gulp-typescript": "3.1.5",
"gulp-typescript": "latest",
"into-stream": "latest",
"istanbul": "latest",
"jake": "latest",
@@ -74,7 +74,7 @@
"through2": "latest",
"travis-fold": "latest",
"ts-node": "latest",
"tslint": "next",
"tslint": "latest",
"typescript": "next"
},
"scripts": {
+6 -2
View File
@@ -2178,7 +2178,10 @@ namespace ts {
case SyntaxKind.JSDocRecordMember:
return bindPropertyWorker(node as JSDocRecordMember);
case SyntaxKind.JSDocPropertyTag:
return declareSymbolAndAddToSymbolTable(node as JSDocPropertyTag, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
return declareSymbolAndAddToSymbolTable(node as JSDocPropertyTag,
(node as JSDocPropertyTag).isBracketed || ((node as JSDocPropertyTag).typeExpression && (node as JSDocPropertyTag).typeExpression.type.kind === SyntaxKind.JSDocOptionalType) ?
SymbolFlags.Property | SymbolFlags.Optional : SymbolFlags.Property,
SymbolFlags.PropertyExcludes);
case SyntaxKind.JSDocFunctionType:
return bindFunctionOrConstructorType(<SignatureDeclaration>node);
case SyntaxKind.JSDocTypeLiteral:
@@ -3398,6 +3401,7 @@ namespace ts {
case SyntaxKind.IndexedAccessType:
case SyntaxKind.MappedType:
case SyntaxKind.LiteralType:
case SyntaxKind.NamespaceExportDeclaration:
// Types and signatures are TypeScript syntax, and exclude all other facts.
transformFlags = TransformFlags.AssertTypeScript;
excludeFlags = TransformFlags.TypeExcludes;
@@ -3592,4 +3596,4 @@ namespace ts {
return TransformFlags.NodeExcludes;
}
}
}
}
+188 -147
View File
@@ -2818,9 +2818,11 @@ namespace ts {
const parameterDeclaration = getDeclarationOfKind<ParameterDeclaration>(parameterSymbol, SyntaxKind.Parameter);
const modifiers = parameterDeclaration.modifiers && parameterDeclaration.modifiers.map(getSynthesizedClone);
const dotDotDotToken = isRestParameter(parameterDeclaration) ? createToken(SyntaxKind.DotDotDotToken) : undefined;
const name = parameterDeclaration.name.kind === SyntaxKind.Identifier ?
setEmitFlags(getSynthesizedClone(parameterDeclaration.name), EmitFlags.NoAsciiEscaping) :
cloneBindingName(parameterDeclaration.name);
const name = parameterDeclaration.name ?
parameterDeclaration.name.kind === SyntaxKind.Identifier ?
setEmitFlags(getSynthesizedClone(parameterDeclaration.name), EmitFlags.NoAsciiEscaping) :
cloneBindingName(parameterDeclaration.name) :
parameterSymbol.name;
const questionToken = isOptionalParameter(parameterDeclaration) ? createToken(SyntaxKind.QuestionToken) : undefined;
let parameterType = getTypeOfSymbol(parameterSymbol);
@@ -5690,6 +5692,7 @@ namespace ts {
prop.type = propType;
if (propertySymbol) {
prop.syntheticOrigin = propertySymbol;
prop.declarations = propertySymbol.declarations;
}
members.set(propName, prop);
}
@@ -6696,8 +6699,10 @@ namespace ts {
return length(type.target.typeParameters);
}
// Get type from reference to class or interface
function getTypeFromClassOrInterfaceReference(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference, symbol: Symbol, typeArgs: Type[]): Type {
/**
* Get type from type-reference that reference to class or interface
*/
function getTypeFromClassOrInterfaceReference(node: TypeReferenceType, symbol: Symbol, typeArgs: Type[]): Type {
const type = <InterfaceType>getDeclaredTypeOfSymbol(getMergedSymbol(symbol));
const typeParameters = type.localTypeParameters;
if (typeParameters) {
@@ -6738,10 +6743,12 @@ namespace ts {
return instantiation;
}
// Get type from reference to type alias. When a type alias is generic, the declared type of the type alias may include
// references to the type parameters of the alias. We replace those with the actual type arguments by instantiating the
// declared type. Instantiations are cached using the type identities of the type arguments as the key.
function getTypeFromTypeAliasReference(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference, symbol: Symbol, typeArguments: Type[]): Type {
/**
* Get type from reference to type alias. When a type alias is generic, the declared type of the type alias may include
* references to the type parameters of the alias. We replace those with the actual type arguments by instantiating the
* declared type. Instantiations are cached using the type identities of the type arguments as the key.
*/
function getTypeFromTypeAliasReference(node: TypeReferenceType, symbol: Symbol, typeArguments: Type[]): Type {
const type = getDeclaredTypeOfSymbol(symbol);
const typeParameters = getSymbolLinks(symbol).typeParameters;
if (typeParameters) {
@@ -6766,8 +6773,10 @@ namespace ts {
return type;
}
// Get type from reference to named type that cannot be generic (enum or type parameter)
function getTypeFromNonGenericTypeReference(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference, symbol: Symbol): Type {
/**
* Get type from reference to named type that cannot be generic (enum or type parameter)
*/
function getTypeFromNonGenericTypeReference(node: TypeReferenceType, symbol: Symbol): Type {
if (node.typeArguments) {
error(node, Diagnostics.Type_0_is_not_generic, symbolToString(symbol));
return unknownType;
@@ -6775,7 +6784,7 @@ namespace ts {
return getDeclaredTypeOfSymbol(symbol);
}
function getTypeReferenceName(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference): EntityNameOrEntityNameExpression | undefined {
function getTypeReferenceName(node: TypeReferenceType): EntityNameOrEntityNameExpression | undefined {
switch (node.kind) {
case SyntaxKind.TypeReference:
return (<TypeReferenceNode>node).typeName;
@@ -6803,7 +6812,7 @@ namespace ts {
return resolveEntityName(typeReferenceName, SymbolFlags.Type) || unknownSymbol;
}
function getTypeReferenceType(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference, symbol: Symbol) {
function getTypeReferenceType(node: TypeReferenceType, symbol: Symbol) {
const typeArguments = typeArgumentsFromTypeReferenceNode(node); // Do unconditionally so we mark type arguments as referenced.
if (symbol === unknownSymbol) {
@@ -6846,7 +6855,8 @@ namespace ts {
case "Object":
return anyType;
case "Function":
return anyFunctionType;
case "function":
return globalFunctionType;
case "Array":
case "array":
return !node.typeArguments || !node.typeArguments.length ? createArrayType(anyType) : undefined;
@@ -6862,7 +6872,7 @@ namespace ts {
return strictNullChecks ? getUnionType([type, nullType]) : type;
}
function getTypeFromTypeReference(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference): Type {
function getTypeFromTypeReference(node: TypeReferenceType): Type {
const links = getNodeLinks(node);
if (!links.resolvedType) {
let symbol: Symbol;
@@ -6893,7 +6903,7 @@ namespace ts {
return links.resolvedType;
}
function typeArgumentsFromTypeReferenceNode(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference): Type[] {
function typeArgumentsFromTypeReferenceNode(node: TypeReferenceType): Type[] {
return map(node.typeArguments, getTypeFromTypeNode);
}
@@ -7944,23 +7954,14 @@ namespace ts {
return mapper;
}
function getInferenceMapper(context: InferenceContext): TypeMapper {
if (!context.mapper) {
const mapper: TypeMapper = t => {
const typeParameters = context.signature.typeParameters;
for (let i = 0; i < typeParameters.length; i++) {
if (t === typeParameters[i]) {
context.inferences[i].isFixed = true;
return getInferredType(context, i);
}
}
return t;
};
mapper.mappedTypes = context.signature.typeParameters;
mapper.context = context;
context.mapper = mapper;
}
return context.mapper;
function isInferenceContext(mapper: TypeMapper): mapper is InferenceContext {
return !!(<InferenceContext>mapper).signature;
}
function cloneTypeMapper(mapper: TypeMapper): TypeMapper {
return mapper && isInferenceContext(mapper) ?
createInferenceContext(mapper.signature, mapper.flags | InferenceFlags.NoDefault, mapper.inferences) :
mapper;
}
function identityMapper(type: Type): Type {
@@ -10156,23 +10157,45 @@ namespace ts {
}
}
function createInferenceContext(signature: Signature, inferUnionTypes: boolean, useAnyForNoInferences: boolean): InferenceContext {
const inferences = map(signature.typeParameters, createTypeInferencesObject);
function createInferenceContext(signature: Signature, flags: InferenceFlags, 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;
return context;
function mapper(t: Type): Type {
for (let i = 0; i < inferences.length; i++) {
if (t === inferences[i].typeParameter) {
inferences[i].isFixed = true;
return getInferredType(context, i);
}
}
return t;
}
}
function createInferenceInfo(typeParameter: TypeParameter): InferenceInfo {
return {
signature,
inferUnionTypes,
inferences,
inferredTypes: new Array(signature.typeParameters.length),
useAnyForNoInferences
typeParameter,
candidates: undefined,
inferredType: undefined,
priority: undefined,
topLevel: true,
isFixed: false
};
}
function createTypeInferencesObject(): TypeInferences {
function cloneInferenceInfo(inference: InferenceInfo): InferenceInfo {
return {
primary: undefined,
secondary: undefined,
topLevel: true,
isFixed: false,
typeParameter: inference.typeParameter,
candidates: inference.candidates && inference.candidates.slice(),
inferredType: inference.inferredType,
priority: inference.priority,
topLevel: inference.topLevel,
isFixed: inference.isFixed
};
}
@@ -10209,10 +10232,9 @@ namespace ts {
if (properties.length === 0 && !indexInfo) {
return undefined;
}
const typeVariable = <TypeVariable>getIndexedAccessType((<IndexType>getConstraintTypeFromMappedType(target)).type, getTypeParameterFromMappedType(target));
const typeVariableArray = [typeVariable];
const typeInferences = createTypeInferencesObject();
const typeInferencesArray = [typeInferences];
const typeParameter = <TypeParameter>getIndexedAccessType((<IndexType>getConstraintTypeFromMappedType(target)).type, getTypeParameterFromMappedType(target));
const inference = createInferenceInfo(typeParameter);
const inferences = [inference];
const templateType = getTemplateTypeFromMappedType(target);
const readonlyMask = target.declaration.readonlyToken ? false : true;
const optionalMask = target.declaration.questionToken ? 0 : SymbolFlags.Optional;
@@ -10238,22 +10260,15 @@ namespace ts {
return createAnonymousType(undefined, members, emptyArray, emptyArray, indexInfo, undefined);
function inferTargetType(sourceType: Type): Type {
typeInferences.primary = undefined;
typeInferences.secondary = undefined;
inferTypes(typeVariableArray, typeInferencesArray, sourceType, templateType);
const inferences = typeInferences.primary || typeInferences.secondary;
return inferences && getUnionType(inferences, /*subtypeReduction*/ true);
inference.candidates = undefined;
inferTypes(inferences, sourceType, templateType);
return inference.candidates && getUnionType(inference.candidates, /*subtypeReduction*/ true);
}
}
function inferTypesWithContext(context: InferenceContext, originalSource: Type, originalTarget: Type) {
inferTypes(context.signature.typeParameters, context.inferences, originalSource, originalTarget);
}
function inferTypes(typeVariables: TypeVariable[], typeInferences: TypeInferences[], originalSource: Type, originalTarget: Type) {
function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority: InferencePriority = 0) {
let symbolStack: Symbol[];
let visited: Map<boolean>;
let inferiority = 0;
inferFromTypes(originalSource, originalTarget);
function inferFromTypes(source: Type, target: Type) {
@@ -10313,32 +10328,26 @@ namespace ts {
// Because the anyFunctionType is internal, it should not be exposed to the user by adding
// it as an inference candidate. Hopefully, a better candidate will come along that does
// not contain anyFunctionType when we come back to this argument for its second round
// of inference.
if (source.flags & TypeFlags.ContainsAnyFunctionType) {
// of inference. Also, we exclude inferences for silentNeverType which is used as a wildcard
// when constructing types from type parameters that had no inference candidates.
if (source.flags & TypeFlags.ContainsAnyFunctionType || source === silentNeverType) {
return;
}
for (let i = 0; i < typeVariables.length; i++) {
if (target === typeVariables[i]) {
const inferences = typeInferences[i];
if (!inferences.isFixed) {
// Any inferences that are made to a type parameter in a union type are inferior
// to inferences made to a flat (non-union) type. This is because if we infer to
// T | string[], we really don't know if we should be inferring to T or not (because
// the correct constituent on the target side could be string[]). Therefore, we put
// such inferior inferences into a secondary bucket, and only use them if the primary
// bucket is empty.
const candidates = inferiority ?
inferences.secondary || (inferences.secondary = []) :
inferences.primary || (inferences.primary = []);
if (!contains(candidates, source)) {
candidates.push(source);
}
if (target.flags & TypeFlags.TypeParameter && !isTypeParameterAtTopLevel(originalTarget, <TypeParameter>target)) {
inferences.topLevel = false;
}
const inference = getInferenceInfoForType(target);
if (inference) {
if (!inference.isFixed) {
if (!inference.candidates || priority < inference.priority) {
inference.candidates = [source];
inference.priority = priority;
}
else if (priority === inference.priority) {
inference.candidates.push(source);
}
if (!(priority & InferencePriority.ReturnType) && target.flags & TypeFlags.TypeParameter && !isTypeParameterAtTopLevel(originalTarget, <TypeParameter>target)) {
inference.topLevel = false;
}
return;
}
return;
}
}
else if (getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference && (<TypeReference>source).target === (<TypeReference>target).target) {
@@ -10356,7 +10365,7 @@ namespace ts {
let typeVariable: TypeVariable;
// First infer to each type in union or intersection that isn't a type variable
for (const t of targetTypes) {
if (t.flags & TypeFlags.TypeVariable && contains(typeVariables, t)) {
if (getInferenceInfoForType(t)) {
typeVariable = <TypeVariable>t;
typeVariableCount++;
}
@@ -10368,9 +10377,10 @@ namespace ts {
// variable. This gives meaningful results for union types in co-variant positions and intersection
// types in contra-variant positions (such as callback parameters).
if (typeVariableCount === 1) {
inferiority++;
const savePriority = priority;
priority |= InferencePriority.NakedTypeVariable;
inferFromTypes(source, typeVariable);
inferiority--;
priority = savePriority;
}
}
else if (source.flags & TypeFlags.UnionOrIntersection) {
@@ -10410,6 +10420,17 @@ namespace ts {
}
}
function getInferenceInfoForType(type: Type) {
if (type.flags & TypeFlags.TypeVariable) {
for (const inference of inferences) {
if (type === inference.typeParameter) {
return inference;
}
}
}
return undefined;
}
function inferFromObjectTypes(source: Type, target: Type) {
if (getObjectFlags(target) & ObjectFlags.Mapped) {
const constraintType = getConstraintTypeFromMappedType(<MappedType>target);
@@ -10418,13 +10439,14 @@ namespace ts {
// where T is a type variable. Use inferTypeForHomomorphicMappedType to infer a suitable source
// type and then make a secondary inference from that type to T. We make a secondary inference
// such that direct inferences to T get priority over inferences to Partial<T>, for example.
const index = indexOf(typeVariables, (<IndexType>constraintType).type);
if (index >= 0 && !typeInferences[index].isFixed) {
const inference = getInferenceInfoForType((<IndexType>constraintType).type);
if (inference && !inference.isFixed) {
const inferredType = inferTypeForHomomorphicMappedType(source, <MappedType>target);
if (inferredType) {
inferiority++;
inferFromTypes(inferredType, typeVariables[index]);
inferiority--;
const savePriority = priority;
priority |= InferencePriority.MappedType;
inferFromTypes(inferredType, inference.typeParameter);
priority = savePriority;
}
}
return;
@@ -10523,66 +10545,68 @@ namespace ts {
return type.flags & TypeFlags.Union ? getUnionType(reducedTypes) : getIntersectionType(reducedTypes);
}
function getInferenceCandidates(context: InferenceContext, index: number): Type[] {
const inferences = context.inferences[index];
return inferences.primary || inferences.secondary || emptyArray;
}
function hasPrimitiveConstraint(type: TypeParameter): boolean {
const constraint = getConstraintOfTypeParameter(type);
return constraint && maybeTypeOfKind(constraint, TypeFlags.Primitive | TypeFlags.Index);
}
function getInferredType(context: InferenceContext, index: number): Type {
let inferredType = context.inferredTypes[index];
const inference = context.inferences[index];
let inferredType = inference.inferredType;
let inferenceSucceeded: boolean;
if (!inferredType) {
const inferences = getInferenceCandidates(context, index);
if (inferences.length) {
if (inference.candidates) {
// We widen inferred literal types if
// all inferences were made to top-level ocurrences of the type parameter, and
// the type parameter has no constraint or its constraint includes no primitive or literal types, and
// the type parameter was fixed during inference or does not occur at top-level in the return type.
const signature = context.signature;
const widenLiteralTypes = context.inferences[index].topLevel &&
!hasPrimitiveConstraint(signature.typeParameters[index]) &&
(context.inferences[index].isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), signature.typeParameters[index]));
const baseInferences = widenLiteralTypes ? sameMap(inferences, getWidenedLiteralType) : inferences;
// Infer widened union or supertype, or the unknown type for no common supertype
const unionOrSuperType = context.inferUnionTypes ? getUnionType(baseInferences, /*subtypeReduction*/ true) : getCommonSupertype(baseInferences);
const widenLiteralTypes = inference.topLevel &&
!hasPrimitiveConstraint(inference.typeParameter) &&
(inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.typeParameter));
const baseCandidates = widenLiteralTypes ? sameMap(inference.candidates, getWidenedLiteralType) : inference.candidates;
// Infer widened union or supertype, or the unknown type for no common supertype. We infer union types
// for inferences coming from return types in order to avoid common supertype failures.
const unionOrSuperType = context.flags & InferenceFlags.InferUnionTypes || inference.priority & InferencePriority.ReturnType ?
getUnionType(baseCandidates, /*subtypeReduction*/ true) : getCommonSupertype(baseCandidates);
inferredType = unionOrSuperType ? getWidenedType(unionOrSuperType) : unknownType;
inferenceSucceeded = !!unionOrSuperType;
}
else {
// Infer either the default or the empty object type when no inferences were
// made. It is important to remember that in this case, inference still
// succeeds, meaning there is no error for not having inference candidates. An
// inference error only occurs when there are *conflicting* candidates, i.e.
// candidates with no common supertype.
const defaultType = getDefaultFromTypeParameter(context.signature.typeParameters[index]);
if (defaultType) {
// Instantiate the default type. Any forward reference to a type
// parameter should be instantiated to the empty object type.
inferredType = instantiateType(defaultType,
combineTypeMappers(
createBackreferenceMapper(context.signature.typeParameters, index),
getInferenceMapper(context)));
if (context.flags & InferenceFlags.NoDefault) {
// We use silentNeverType as the wildcard that signals no inferences.
inferredType = silentNeverType;
}
else {
inferredType = context.useAnyForNoInferences ? anyType : emptyObjectType;
// Infer either the default or the empty object type when no inferences were
// made. It is important to remember that in this case, inference still
// succeeds, meaning there is no error for not having inference candidates. An
// inference error only occurs when there are *conflicting* candidates, i.e.
// candidates with no common supertype.
const defaultType = getDefaultFromTypeParameter(inference.typeParameter);
if (defaultType) {
// Instantiate the default type. Any forward reference to a type
// parameter should be instantiated to the empty object type.
inferredType = instantiateType(defaultType,
combineTypeMappers(
createBackreferenceMapper(context.signature.typeParameters, index),
context));
}
else {
inferredType = context.flags & InferenceFlags.AnyDefault ? anyType : emptyObjectType;
}
}
inferenceSucceeded = true;
}
context.inferredTypes[index] = inferredType;
inference.inferredType = inferredType;
// Only do the constraint check if inference succeeded (to prevent cascading errors)
if (inferenceSucceeded) {
const constraint = getConstraintOfTypeParameter(context.signature.typeParameters[index]);
if (constraint) {
const instantiatedConstraint = instantiateType(constraint, getInferenceMapper(context));
const instantiatedConstraint = instantiateType(constraint, context);
if (!isTypeAssignableTo(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) {
context.inferredTypes[index] = inferredType = instantiatedConstraint;
inference.inferredType = inferredType = instantiatedConstraint;
}
}
}
@@ -10597,10 +10621,11 @@ namespace ts {
}
function getInferredTypes(context: InferenceContext): Type[] {
for (let i = 0; i < context.inferredTypes.length; i++) {
getInferredType(context, i);
const result: Type[] = [];
for (let i = 0; i < context.inferences.length; i++) {
result.push(getInferredType(context, i));
}
return context.inferredTypes;
return result;
}
// EXPRESSION TYPE CHECKING
@@ -12035,6 +12060,7 @@ namespace ts {
// declaration container are the same).
const assumeInitialized = isParameter || isOuterVariable ||
type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & TypeFlags.Any) !== 0 || isInTypeQuery(node) || node.parent.kind === SyntaxKind.ExportSpecifier) ||
node.parent.kind === SyntaxKind.NonNullExpression ||
isInAmbientContext(declaration);
const initialType = assumeInitialized ? (isParameter ? removeOptionalityFromDeclaredType(type, getRootDeclaration(declaration) as VariableLikeDeclaration) : type) :
type === autoType || type === autoArrayType ? undefinedType :
@@ -12750,7 +12776,7 @@ namespace ts {
function getContextualTypeForBinaryOperand(node: Expression): Type {
const binaryExpression = <BinaryExpression>node.parent;
const operator = binaryExpression.operatorToken.kind;
if (operator >= SyntaxKind.FirstAssignment && operator <= SyntaxKind.LastAssignment) {
if (isAssignmentOperator(operator)) {
// Don't do this for special property assignments to avoid circularity
if (getSpecialPropertyAssignmentKind(binaryExpression) !== SpecialPropertyAssignmentKind.None) {
return undefined;
@@ -14855,26 +14881,25 @@ namespace ts {
// Instantiate a generic signature in the context of a non-generic signature (section 3.8.5 in TypeScript spec)
function instantiateSignatureInContextOf(signature: Signature, contextualSignature: Signature, contextualMapper: TypeMapper): Signature {
const context = createInferenceContext(signature, /*inferUnionTypes*/ true, /*useAnyForNoInferences*/ false);
const context = createInferenceContext(signature, InferenceFlags.InferUnionTypes);
forEachMatchingParameterType(contextualSignature, signature, (source, target) => {
// Type parameters from outer context referenced by source type are fixed by instantiation of the source type
inferTypesWithContext(context, instantiateType(source, contextualMapper), target);
inferTypes(context.inferences, instantiateType(source, contextualMapper), target);
});
return getSignatureInstantiation(signature, getInferredTypes(context));
}
function inferTypeArguments(node: CallLikeExpression, signature: Signature, args: Expression[], excludeArgument: boolean[], context: InferenceContext): void {
const typeParameters = signature.typeParameters;
const inferenceMapper = getInferenceMapper(context);
function inferTypeArguments(node: CallLikeExpression, signature: Signature, args: Expression[], excludeArgument: boolean[], context: InferenceContext): Type[] {
const inferences = context.inferences;
// Clear out all the inference results from the last time inferTypeArguments was called on this context
for (let i = 0; i < typeParameters.length; i++) {
for (let i = 0; i < inferences.length; i++) {
// As an optimization, we don't have to clear (and later recompute) inferred types
// for type parameters that have already been fixed on the previous call to inferTypeArguments.
// It would be just as correct to reset all of them. But then we'd be repeating the same work
// for the type parameters that were fixed, namely the work done by getInferredType.
if (!context.inferences[i].isFixed) {
context.inferredTypes[i] = undefined;
if (!inferences[i].isFixed) {
inferences[i].inferredType = undefined;
}
}
@@ -14889,11 +14914,29 @@ namespace ts {
context.failedTypeParameterIndex = undefined;
}
// If a contextual type is available, infer from that type to the return type of the call expression. For
// example, given a 'function wrap<T, U>(cb: (x: T) => U): (x: T) => U' and a call expression
// 'let f: (x: string) => number = wrap(s => s.length)', we infer from the declared type of 'f' to the
// return type of 'wrap'.
if (isExpression(node)) {
const contextualType = getContextualType(node);
if (contextualType) {
// We clone the contextual mapper to avoid disturbing a resolution in progress for an
// outer call expression. Effectively we just want a snapshot of whatever has been
// inferred for any outer call expression so far.
const mapper = cloneTypeMapper(getContextualMapper(node));
const instantiatedType = instantiateType(contextualType, mapper);
const returnType = getReturnTypeOfSignature(signature);
// Inferences made from return types have lower priority than all other inferences.
inferTypes(context.inferences, instantiatedType, returnType, InferencePriority.ReturnType);
}
}
const thisType = getThisTypeOfSignature(signature);
if (thisType) {
const thisArgumentNode = getThisArgumentOfCall(node);
const thisArgumentType = thisArgumentNode ? checkExpression(thisArgumentNode) : voidType;
inferTypesWithContext(context, thisArgumentType, thisType);
inferTypes(context.inferences, thisArgumentType, thisType);
}
// We perform two passes over the arguments. In the first pass we infer from all arguments, but use
@@ -14911,11 +14954,11 @@ namespace ts {
if (argType === undefined) {
// For context sensitive arguments we pass the identityMapper, which is a signal to treat all
// context sensitive function expressions as wildcards
const mapper = excludeArgument && excludeArgument[i] !== undefined ? identityMapper : inferenceMapper;
const mapper = excludeArgument && excludeArgument[i] !== undefined ? identityMapper : context;
argType = checkExpressionWithContextualType(arg, paramType, mapper);
}
inferTypesWithContext(context, argType, paramType);
inferTypes(context.inferences, argType, paramType);
}
}
@@ -14930,12 +14973,11 @@ namespace ts {
if (excludeArgument[i] === false) {
const arg = args[i];
const paramType = getTypeAtPosition(signature, i);
inferTypesWithContext(context, checkExpressionWithContextualType(arg, paramType, inferenceMapper), paramType);
inferTypes(context.inferences, checkExpressionWithContextualType(arg, paramType, context), paramType);
}
}
}
getInferredTypes(context);
return getInferredTypes(context);
}
function checkTypeArguments(signature: Signature, typeArgumentNodes: TypeNode[], typeArgumentTypes: Type[], reportErrors: boolean, headMessage?: DiagnosticMessage): boolean {
@@ -15517,7 +15559,7 @@ namespace ts {
else {
Debug.assert(resultOfFailedInference.failedTypeParameterIndex >= 0);
const failedTypeParameter = candidateForTypeArgumentError.typeParameters[resultOfFailedInference.failedTypeParameterIndex];
const inferenceCandidates = getInferenceCandidates(resultOfFailedInference, resultOfFailedInference.failedTypeParameterIndex);
const inferenceCandidates = resultOfFailedInference.inferences[resultOfFailedInference.failedTypeParameterIndex].candidates;
let diagnosticChainHead = chainDiagnosticMessages(/*details*/ undefined, // details will be provided by call to reportNoCommonSupertypeError
Diagnostics.The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_type_arguments_explicitly,
@@ -15590,7 +15632,7 @@ namespace ts {
let candidate: Signature;
let typeArgumentsAreValid: boolean;
const inferenceContext = originalCandidate.typeParameters
? createInferenceContext(originalCandidate, /*inferUnionTypes*/ false, /*useAnyForNoInferences*/ isInJavaScriptFile(node))
? createInferenceContext(originalCandidate, /*flags*/ isInJavaScriptFile(node) ? InferenceFlags.AnyDefault : 0)
: undefined;
while (true) {
@@ -15602,8 +15644,7 @@ namespace ts {
typeArgumentsAreValid = checkTypeArguments(candidate, typeArguments, typeArgumentTypes, /*reportErrors*/ false);
}
else {
inferTypeArguments(node, candidate, args, excludeArgument, inferenceContext);
typeArgumentTypes = inferenceContext.inferredTypes;
typeArgumentTypes = inferTypeArguments(node, candidate, args, excludeArgument, inferenceContext);
typeArgumentsAreValid = inferenceContext.failedTypeParameterIndex === undefined;
}
if (!typeArgumentsAreValid) {
@@ -16177,7 +16218,7 @@ namespace ts {
for (let i = 0; i < len; i++) {
const declaration = <ParameterDeclaration>signature.parameters[i].valueDeclaration;
if (declaration.type) {
inferTypesWithContext(mapper.context, getTypeFromTypeNode(declaration.type), getTypeAtPosition(context, i));
inferTypes((<InferenceContext>mapper).inferences, getTypeFromTypeNode(declaration.type), getTypeAtPosition(context, i));
}
}
}
@@ -16263,7 +16304,7 @@ namespace ts {
// T in the second overload so that we do not infer Base as a candidate for T
// (inferring Base would make type argument inference inconsistent between the two
// overloads).
inferTypesWithContext(mapper.context, links.type, instantiateType(contextualType, mapper));
inferTypes((<InferenceContext>mapper).inferences, links.type, instantiateType(contextualType, mapper));
}
}
@@ -17305,7 +17346,7 @@ namespace ts {
}
function checkAssignmentOperator(valueType: Type): void {
if (produceDiagnostics && operator >= SyntaxKind.FirstAssignment && operator <= SyntaxKind.LastAssignment) {
if (produceDiagnostics && isAssignmentOperator(operator)) {
// TypeScript 1.0 spec (April 2014): 4.17
// An assignment of the form
// VarExpr = ValueExpr
+56 -14
View File
@@ -139,6 +139,7 @@ namespace ts {
"es2017.object": "lib.es2017.object.d.ts",
"es2017.sharedmemory": "lib.es2017.sharedmemory.d.ts",
"es2017.string": "lib.es2017.string.d.ts",
"es2017.intl": "lib.es2017.intl.d.ts",
"esnext.asynciterable": "lib.esnext.asynciterable.d.ts",
}),
},
@@ -691,8 +692,7 @@ namespace ts {
return typeAcquisition;
}
/* @internal */
export function getOptionNameMap(): OptionNameMap {
function getOptionNameMap(): OptionNameMap {
if (optionNameMapCache) {
return optionNameMapCache;
}
@@ -745,7 +745,6 @@ namespace ts {
const options: CompilerOptions = {};
const fileNames: string[] = [];
const errors: Diagnostic[] = [];
const { optionNameMap, shortOptionNames } = getOptionNameMap();
parseStrings(commandLine);
return {
@@ -757,21 +756,13 @@ namespace ts {
function parseStrings(args: string[]) {
let i = 0;
while (i < args.length) {
let s = args[i];
const s = args[i];
i++;
if (s.charCodeAt(0) === CharacterCodes.at) {
parseResponseFile(s.slice(1));
}
else if (s.charCodeAt(0) === CharacterCodes.minus) {
s = s.slice(s.charCodeAt(1) === CharacterCodes.minus ? 2 : 1).toLowerCase();
// Try to translate short option names to their full equivalents.
const short = shortOptionNames.get(s);
if (short !== undefined) {
s = short;
}
const opt = optionNameMap.get(s);
const opt = getOptionFromName(s.slice(s.charCodeAt(1) === CharacterCodes.minus ? 2 : 1), /*allowShort*/ true);
if (opt) {
if (opt.isTSConfigOnly) {
errors.push(createCompilerDiagnostic(Diagnostics.Option_0_can_only_be_specified_in_tsconfig_json_file, opt.name));
@@ -859,6 +850,19 @@ namespace ts {
}
}
function getOptionFromName(optionName: string, allowShort = false): CommandLineOption | undefined {
optionName = optionName.toLowerCase();
const { optionNameMap, shortOptionNames } = getOptionNameMap();
// Try to translate short option names to their full equivalents.
if (allowShort) {
const short = shortOptionNames.get(optionName);
if (short !== undefined) {
optionName = short;
}
}
return optionNameMap.get(optionName);
}
/**
* Read tsconfig.json file
* @param fileName The path to the config file
@@ -1704,4 +1708,42 @@ namespace ts {
function caseInsensitiveKeyMapper(key: string) {
return key.toLowerCase();
}
}
/**
* Produces a cleaned version of compiler options with personally identifiying info (aka, paths) removed.
* Also converts enum values back to strings.
*/
/* @internal */
export function convertCompilerOptionsForTelemetry(opts: ts.CompilerOptions): ts.CompilerOptions {
const out: ts.CompilerOptions = {};
for (const key in opts) if (opts.hasOwnProperty(key)) {
const type = getOptionFromName(key);
if (type !== undefined) { // Ignore unknown options
out[key] = getOptionValueWithEmptyStrings(opts[key], type);
}
}
return out;
}
function getOptionValueWithEmptyStrings(value: any, option: CommandLineOption): {} {
switch (option.type) {
case "object": // "paths". Can't get any useful information from the value since we blank out strings, so just return "".
return "";
case "string": // Could be any arbitrary string -- use empty string instead.
return "";
case "number": // Allow numbers, but be sure to check it's actually a number.
return typeof value === "number" ? value : "";
case "boolean":
return typeof value === "boolean" ? value : "";
case "list":
const elementType = (option as CommandLineOptionOfListType).element;
return ts.isArray(value) ? value.map(v => getOptionValueWithEmptyStrings(v, elementType)) : "";
default:
return ts.forEachEntry(option.type, (optionEnumValue, optionStringValue) => {
if (optionEnumValue === value) {
return optionStringValue;
}
});
}
}
}
+4 -2
View File
@@ -58,8 +58,10 @@ namespace ts {
}
const isEmittedNode = node.kind !== SyntaxKind.NotEmittedStatement;
const skipLeadingComments = pos < 0 || (emitFlags & EmitFlags.NoLeadingComments) !== 0;
const skipTrailingComments = end < 0 || (emitFlags & EmitFlags.NoTrailingComments) !== 0;
// We have to explicitly check that the node is JsxText because if the compilerOptions.jsx is "preserve" we will not do any transformation.
// It is expensive to walk entire tree just to set one kind of node to have no comments.
const skipLeadingComments = pos < 0 || (emitFlags & EmitFlags.NoLeadingComments) !== 0 || node.kind === SyntaxKind.JsxText;
const skipTrailingComments = end < 0 || (emitFlags & EmitFlags.NoTrailingComments) !== 0 || node.kind === SyntaxKind.JsxText;
// Emit leading comments if the position is not synthesized and the node
// has not opted out from emitting leading comments.
+12
View File
@@ -521,6 +521,18 @@ namespace ts {
return result || array;
}
export function mapDefined<T>(array: ReadonlyArray<T>, mapFn: (x: T, i: number) => T | undefined): ReadonlyArray<T> {
const result: T[] = [];
for (let i = 0; i < array.length; i++) {
const item = array[i];
const mapped = mapFn(item, i);
if (mapped !== undefined) {
result.push(mapped);
}
}
return result;
}
/**
* Computes the first matching span of elements and returns a tuple of the first span
* and the remaining elements.
+29 -4
View File
@@ -571,6 +571,8 @@ namespace ts {
return emitModuleBlock(<ModuleBlock>node);
case SyntaxKind.CaseBlock:
return emitCaseBlock(<CaseBlock>node);
case SyntaxKind.NamespaceExportDeclaration:
return emitNamespaceExportDeclaration(<NamespaceExportDeclaration>node);
case SyntaxKind.ImportEqualsDeclaration:
return emitImportEqualsDeclaration(<ImportEqualsDeclaration>node);
case SyntaxKind.ImportDeclaration:
@@ -860,6 +862,7 @@ namespace ts {
emitDecorators(node, node.decorators);
emitModifiers(node, node.modifiers);
emit(node.name);
writeIfPresent(node.questionToken, "?");
emitWithPrefix(": ", node.type);
emitExpressionWithPrefix(" = ", node.initializer);
write(";");
@@ -881,6 +884,7 @@ namespace ts {
emitModifiers(node, node.modifiers);
writeIfPresent(node.asteriskToken, "*");
emit(node.name);
writeIfPresent(node.questionToken, "?");
emitSignatureAndBody(node, emitSignatureHead);
}
@@ -1060,7 +1064,7 @@ namespace ts {
}
else {
write("{");
emitList(node, elements, getEmitFlags(node) & EmitFlags.SingleLine ? ListFormat.ObjectBindingPatternElements : ListFormat.ObjectBindingPatternElementsWithSpaceBetweenBraces);
emitList(node, elements, ListFormat.ObjectBindingPatternElements);
write("}");
}
}
@@ -1884,6 +1888,12 @@ namespace ts {
write(";");
}
function emitNamespaceExportDeclaration(node: NamespaceExportDeclaration) {
write("export as namespace ");
emit(node.name);
write(";");
}
function emitNamedExports(node: NamedExports) {
emitNamedImportsOrExports(node);
}
@@ -2021,6 +2031,22 @@ namespace ts {
rangeStartPositionsAreOnSameLine(parentNode, statements[0], currentSourceFile)
);
// e.g:
// case 0: // Zero
// case 1: // One
// case 2: // two
// return "hi";
// If there is no statements, emitNodeWithComments of the parentNode which is caseClause will take care of trailing comment.
// So in example above, comment "// Zero" and "// One" will be emit in emitTrailingComments in emitNodeWithComments.
// However, for "case 2", because parentNode which is caseClause has an "end" property to be end of the statements (in this case return statement)
// comment "// two" will not be emitted in emitNodeWithComments.
// Therefore, we have to do the check here to emit such comment.
if (statements.length > 0) {
// We use emitTrailingCommentsOfPosition instead of emitLeadingCommentsOfPosition because leading comments is defined as comments before the node after newline character separating it from previous line
// Note: we can't use parentNode.end as such position includes statements.
emitTrailingCommentsOfPosition(statements.pos);
}
if (emitAsSingleStatement) {
write(" ");
emit(statements[0]);
@@ -2985,7 +3011,7 @@ namespace ts {
NoInterveningComments = 1 << 17, // Do not emit comments between each node
// Precomputed Formats
Modifiers = SingleLine | SpaceBetweenSiblings,
Modifiers = SingleLine | SpaceBetweenSiblings | NoInterveningComments,
HeritageClauses = SingleLine | SpaceBetweenSiblings,
SingleLineTypeLiteralMembers = SingleLine | SpaceBetweenBraces | SpaceBetweenSiblings | Indented,
MultiLineTypeLiteralMembers = MultiLine | Indented,
@@ -2993,8 +3019,7 @@ namespace ts {
TupleTypeElements = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented,
UnionTypeConstituents = BarDelimited | SpaceBetweenSiblings | SingleLine,
IntersectionTypeConstituents = AmpersandDelimited | SpaceBetweenSiblings | SingleLine,
ObjectBindingPatternElements = SingleLine | CommaDelimited | SpaceBetweenSiblings,
ObjectBindingPatternElementsWithSpaceBetweenBraces = SingleLine | AllowTrailingComma | SpaceBetweenBraces | CommaDelimited | SpaceBetweenSiblings,
ObjectBindingPatternElements = SingleLine | AllowTrailingComma | SpaceBetweenBraces | CommaDelimited | SpaceBetweenSiblings,
ArrayBindingPatternElements = SingleLine | AllowTrailingComma | CommaDelimited | SpaceBetweenSiblings,
ObjectLiteralExpressionProperties = PreserveLines | CommaDelimited | SpaceBetweenSiblings | SpaceBetweenBraces | Indented | Braces,
ArrayLiteralExpressionElements = PreserveLines | CommaDelimited | SpaceBetweenSiblings | AllowTrailingComma | Indented | SquareBrackets,
+2 -2
View File
@@ -303,7 +303,7 @@ namespace ts {
: node;
}
export function createProperty(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression) {
export function createProperty(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) {
const node = <PropertyDeclaration>createSynthesizedNode(SyntaxKind.PropertyDeclaration);
node.decorators = asNodeArray(decorators);
node.modifiers = asNodeArray(modifiers);
@@ -314,7 +314,7 @@ namespace ts {
return node;
}
export function updateProperty(node: PropertyDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: PropertyName, type: TypeNode | undefined, initializer: Expression) {
export function updateProperty(node: PropertyDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: PropertyName, type: TypeNode | undefined, initializer: Expression | undefined) {
return node.decorators !== decorators
|| node.modifiers !== modifiers
|| node.name !== name
+25 -32
View File
@@ -1240,12 +1240,12 @@ namespace ts {
if (token() === SyntaxKind.ExportKeyword) {
nextToken();
if (token() === SyntaxKind.DefaultKeyword) {
return lookAhead(nextTokenIsClassOrFunctionOrAsync);
return lookAhead(nextTokenCanFollowDefaultKeyword);
}
return token() !== SyntaxKind.AsteriskToken && token() !== SyntaxKind.AsKeyword && token() !== SyntaxKind.OpenBraceToken && canFollowModifier();
}
if (token() === SyntaxKind.DefaultKeyword) {
return nextTokenIsClassOrFunctionOrAsync();
return nextTokenCanFollowDefaultKeyword();
}
if (token() === SyntaxKind.StaticKeyword) {
nextToken();
@@ -1267,9 +1267,10 @@ namespace ts {
|| isLiteralPropertyName();
}
function nextTokenIsClassOrFunctionOrAsync(): boolean {
function nextTokenCanFollowDefaultKeyword(): boolean {
nextToken();
return token() === SyntaxKind.ClassKeyword || token() === SyntaxKind.FunctionKeyword ||
token() === SyntaxKind.InterfaceKeyword ||
(token() === SyntaxKind.AbstractKeyword && lookAhead(nextTokenIsClassKeywordOnSameLine)) ||
(token() === SyntaxKind.AsyncKeyword && lookAhead(nextTokenIsFunctionKeywordOnSameLine));
}
@@ -6074,7 +6075,10 @@ namespace ts {
case SyntaxKind.OpenBraceToken:
return parseJSDocRecordType();
case SyntaxKind.FunctionKeyword:
return parseJSDocFunctionType();
if (lookAhead(nextTokenIsOpenParen)) {
return parseJSDocFunctionType();
}
break;
case SyntaxKind.DotDotDotToken:
return parseJSDocVariadicType();
case SyntaxKind.NewKeyword:
@@ -6090,7 +6094,6 @@ namespace ts {
case SyntaxKind.NullKeyword:
case SyntaxKind.UndefinedKeyword:
case SyntaxKind.NeverKeyword:
case SyntaxKind.ObjectKeyword:
return parseTokenNode<JSDocType>();
case SyntaxKind.StringLiteral:
case SyntaxKind.NumericLiteral:
@@ -6507,7 +6510,7 @@ namespace ts {
case "arg":
case "argument":
case "param":
tag = parseParamTag(atToken, tagName);
tag = parseParameterOrPropertyTag(atToken, tagName, /*shouldParseParamTag*/ true);
break;
case "return":
case "returns":
@@ -6630,10 +6633,7 @@ namespace ts {
});
}
function parseParamTag(atToken: AtToken, tagName: Identifier) {
let typeExpression = tryParseTypeExpression();
skipWhitespace();
function parseBracketNameInPropertyAndParamTag() {
let name: Identifier;
let isBracketed: boolean;
// Looking for something like '[foo]' or 'foo'
@@ -6652,6 +6652,15 @@ namespace ts {
else if (tokenIsIdentifierOrKeyword(token())) {
name = parseJSDocIdentifierName();
}
return { name, isBracketed };
}
function parseParameterOrPropertyTag(atToken: AtToken, tagName: Identifier, shouldParseParamTag: boolean): JSDocPropertyTag | JSDocParameterTag {
let typeExpression = tryParseTypeExpression();
skipWhitespace();
const { name, isBracketed } = parseBracketNameInPropertyAndParamTag();
skipWhitespace();
if (!name) {
parseErrorAtPosition(scanner.getStartPos(), 0, Diagnostics.Identifier_expected);
@@ -6670,13 +6679,15 @@ namespace ts {
typeExpression = tryParseTypeExpression();
}
const result = <JSDocParameterTag>createNode(SyntaxKind.JSDocParameterTag, atToken.pos);
const result = shouldParseParamTag ?
<JSDocParameterTag>createNode(SyntaxKind.JSDocParameterTag, atToken.pos) :
<JSDocPropertyTag>createNode(SyntaxKind.JSDocPropertyTag, atToken.pos);
result.atToken = atToken;
result.tagName = tagName;
result.preParameterName = preName;
result.typeExpression = typeExpression;
result.postParameterName = postName;
result.parameterName = postName || preName;
result.name = postName || preName;
result.isBracketed = isBracketed;
return finishNode(result);
}
@@ -6705,24 +6716,6 @@ namespace ts {
return finishNode(result);
}
function parsePropertyTag(atToken: AtToken, tagName: Identifier): JSDocPropertyTag {
const typeExpression = tryParseTypeExpression();
skipWhitespace();
const name = parseJSDocIdentifierName();
skipWhitespace();
if (!name) {
parseErrorAtPosition(scanner.getStartPos(), /*length*/ 0, Diagnostics.Identifier_expected);
return undefined;
}
const result = <JSDocPropertyTag>createNode(SyntaxKind.JSDocPropertyTag, atToken.pos);
result.atToken = atToken;
result.tagName = tagName;
result.name = name;
result.typeExpression = typeExpression;
return finishNode(result);
}
function parseAugmentsTag(atToken: AtToken, tagName: Identifier): JSDocAugmentsTag {
const typeExpression = tryParseTypeExpression();
@@ -6761,7 +6754,7 @@ namespace ts {
const jsDocTypeReference = <JSDocTypeReference>typeExpression.type;
if (jsDocTypeReference.name.kind === SyntaxKind.Identifier) {
const name = <Identifier>jsDocTypeReference.name;
if (name.text === "Object") {
if (name.text === "Object" || name.text === "object") {
typedefTag.jsDocTypeLiteral = scanChildTags();
}
}
@@ -6859,7 +6852,7 @@ namespace ts {
return true;
case "prop":
case "property":
const propertyTag = parsePropertyTag(atToken, tagName);
const propertyTag = parseParameterOrPropertyTag(atToken, tagName, /*shouldParseParamTag*/ false) as JSDocPropertyTag;
if (propertyTag) {
if (!parentTag.jsDocPropertyTags) {
parentTag.jsDocPropertyTags = <NodeArray<JSDocPropertyTag>>[];
+13
View File
@@ -386,6 +386,19 @@ namespace ts {
allDiagnostics?: Diagnostic[];
}
/**
* Create a new 'Program' instance. A Program is an immutable collection of 'SourceFile's and a 'CompilerOptions'
* that represent a compilation unit.
*
* Creating a program proceeds from a set of root files, expanding the set of inputs by following imports and
* triple-slash-reference-path directives transitively. '@types' and triple-slash-reference-types are also pulled in.
*
* @param rootNames - A set of root files.
* @param options - The compiler options which should be used.
* @param host - The host interacts with the underlying file system.
* @param oldProgram - Reuses an old program structure.
* @returns A 'Program' object.
*/
export function createProgram(rootNames: string[], options: CompilerOptions, host?: CompilerHost, oldProgram?: Program): Program {
let program: Program;
let files: SourceFile[] = [];
+17 -5
View File
@@ -429,6 +429,7 @@ namespace ts {
case CharacterCodes.slash:
// starts of normal trivia
case CharacterCodes.lessThan:
case CharacterCodes.bar:
case CharacterCodes.equals:
case CharacterCodes.greaterThan:
// Starts of conflict marker trivia
@@ -496,6 +497,7 @@ namespace ts {
break;
case CharacterCodes.lessThan:
case CharacterCodes.bar:
case CharacterCodes.equals:
case CharacterCodes.greaterThan:
if (isConflictMarkerTrivia(text, pos)) {
@@ -562,12 +564,12 @@ namespace ts {
}
}
else {
Debug.assert(ch === CharacterCodes.equals);
// Consume everything from the start of the mid-conflict marker to the start of the next
// end-conflict marker.
Debug.assert(ch === CharacterCodes.bar || ch === CharacterCodes.equals);
// Consume everything from the start of a ||||||| or ======= marker to the start
// of the next ======= or >>>>>>> marker.
while (pos < len) {
const ch = text.charCodeAt(pos);
if (ch === CharacterCodes.greaterThan && isConflictMarkerTrivia(text, pos)) {
const currentChar = text.charCodeAt(pos);
if ((currentChar === CharacterCodes.equals || currentChar === CharacterCodes.greaterThan) && currentChar !== ch && isConflictMarkerTrivia(text, pos)) {
break;
}
@@ -1562,6 +1564,16 @@ namespace ts {
pos++;
return token = SyntaxKind.OpenBraceToken;
case CharacterCodes.bar:
if (isConflictMarkerTrivia(text, pos)) {
pos = scanConflictMarkerTrivia(text, pos, error);
if (skipTrivia) {
continue;
}
else {
return token = SyntaxKind.ConflictMarkerTrivia;
}
}
if (text.charCodeAt(pos + 1) === CharacterCodes.bar) {
return pos += 2, token = SyntaxKind.BarBarToken;
}
+3
View File
@@ -345,6 +345,9 @@ namespace ts {
case SyntaxKind.PropertyDeclaration:
// TypeScript property declarations are elided.
case SyntaxKind.NamespaceExportDeclaration:
// TypeScript namespace export declarations are elided.
return undefined;
case SyntaxKind.Constructor:
+35 -19
View File
@@ -892,6 +892,8 @@ namespace ts {
kind: SyntaxKind.ConstructorType;
}
export type TypeReferenceType = TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference;
export interface TypeReferenceNode extends TypeNode {
kind: SyntaxKind.TypeReference;
typeName: EntityName;
@@ -2100,6 +2102,7 @@ namespace ts {
}
export interface JSDocTag extends Node {
parent: JSDoc;
atToken: AtToken;
tagName: Identifier;
comment: string | undefined;
@@ -2130,6 +2133,7 @@ namespace ts {
}
export interface JSDocTypedefTag extends JSDocTag, NamedDeclaration {
parent: JSDoc;
kind: SyntaxKind.JSDocTypedefTag;
fullName?: JSDocNamespaceDeclaration | Identifier;
name?: Identifier;
@@ -2138,9 +2142,15 @@ namespace ts {
}
export interface JSDocPropertyTag extends JSDocTag, TypeElement {
parent: JSDoc;
kind: SyntaxKind.JSDocPropertyTag;
name: Identifier;
/** the parameter name, if provided *before* the type (TypeScript-style) */
preParameterName?: Identifier;
/** the parameter name, if provided *after* the type (JSDoc-standard) */
postParameterName?: Identifier;
typeExpression: JSDocTypeExpression;
isBracketed: boolean;
}
export interface JSDocTypeLiteral extends JSDocType {
@@ -2157,7 +2167,7 @@ namespace ts {
/** the parameter name, if provided *after* the type (JSDoc-standard) */
postParameterName?: Identifier;
/** the parameter name, regardless of the location it was provided */
parameterName: Identifier;
name: Identifier;
isBracketed: boolean;
}
@@ -3336,30 +3346,36 @@ namespace ts {
(t: TypeParameter): Type;
mappedTypes?: Type[]; // Types mapped by this mapper
instantiations?: Type[]; // Cache of instantiations created using this type mapper.
context?: InferenceContext; // The inference context this mapper was created from.
// Only inference mappers have this set (in createInferenceMapper).
// The identity mapper and regular instantiation mappers do not need it.
}
export const enum InferencePriority {
NakedTypeVariable = 1 << 0, // Naked type variable in union or intersection type
MappedType = 1 << 1, // Reverse inference for mapped type
ReturnType = 1 << 2, // Inference made from return type of generic function
}
export interface InferenceInfo {
typeParameter: TypeParameter;
candidates: Type[];
inferredType: Type;
priority: InferencePriority;
topLevel: boolean;
isFixed: boolean;
}
export const enum InferenceFlags {
InferUnionTypes = 1 << 0, // Infer union types for disjoint candidates (otherwise unknownType)
NoDefault = 1 << 1, // Infer unknownType for no inferences (otherwise anyType or emptyObjectType)
AnyDefault = 1 << 2, // Infer anyType for no inferences (otherwise emptyObjectType)
}
/* @internal */
export interface TypeInferences {
primary: Type[]; // Inferences made directly to a type parameter
secondary: Type[]; // Inferences made to a type parameter in a union type
topLevel: boolean; // True if all inferences were made from top-level (not nested in object type) locations
isFixed: boolean; // Whether the type parameter is fixed, as defined in section 4.12.2 of the TypeScript spec
// If a type parameter is fixed, no more inferences can be made for the type parameter
}
/* @internal */
export interface InferenceContext {
export interface InferenceContext extends TypeMapper {
signature: Signature; // Generic signature for which inferences are made
inferUnionTypes: boolean; // Infer union types for disjoint candidates (otherwise undefinedType)
inferences: TypeInferences[]; // Inferences made for each type parameter
inferredTypes: Type[]; // Inferred type for each type parameter
mapper?: TypeMapper; // Type mapper for this inference context
inferences: InferenceInfo[]; // Inferences made for each type parameter
flags: InferenceFlags; // Inference flags
failedTypeParameterIndex?: number; // Index of type parameter for which inference failed
// It is optional because in contextual signature instantiation, nothing fails
useAnyForNoInferences?: boolean; // Use any instead of {} for no inferences
}
/* @internal */
+33 -4
View File
@@ -288,6 +288,14 @@ namespace ts {
return node.kind >= SyntaxKind.FirstJSDocNode && node.kind <= SyntaxKind.LastJSDocNode;
}
export function isJSDoc(node: Node): node is JSDoc {
return node.kind === SyntaxKind.JSDocComment;
}
export function isJSDocTypedefTag(node: Node): node is JSDocTypedefTag {
return node.kind === SyntaxKind.JSDocTypedefTag;
}
export function isJSDocTag(node: Node) {
return node.kind >= SyntaxKind.FirstJSDocTagNode && node.kind <= SyntaxKind.LastJSDocTagNode;
}
@@ -1551,6 +1559,10 @@ namespace ts {
}
export function getJSDocs(node: Node): (JSDoc | JSDocTag)[] {
if (isJSDocTypedefTag(node)) {
return [node.parent];
}
let cache: (JSDoc | JSDocTag)[] = node.jsDocCache;
if (!cache) {
getJSDocsWorker(node);
@@ -1623,7 +1635,7 @@ namespace ts {
}
else if (param.name.kind === SyntaxKind.Identifier) {
const name = (param.name as Identifier).text;
return filter(tags, tag => tag.kind === SyntaxKind.JSDocParameterTag && tag.parameterName.text === name);
return filter(tags, tag => tag.kind === SyntaxKind.JSDocParameterTag && tag.name.text === name);
}
else {
// TODO: it's a destructured parameter, so it should look up an "object type" series of multiple lines
@@ -1634,7 +1646,7 @@ namespace ts {
/** Does the opposite of `getJSDocParameterTags`: given a JSDoc parameter, finds the parameter corresponding to it. */
export function getParameterFromJSDoc(node: JSDocParameterTag): ParameterDeclaration | undefined {
const name = node.parameterName.text;
const name = node.name.text;
const grandParent = node.parent!.parent!;
Debug.assert(node.parent!.kind === SyntaxKind.JSDocComment);
if (!isFunctionLike(grandParent)) {
@@ -1785,6 +1797,23 @@ namespace ts {
}
}
/* @internal */
// See GH#16030
export function isAnyDeclarationName(name: Node): boolean {
switch (name.kind) {
case SyntaxKind.Identifier:
case SyntaxKind.StringLiteral:
case SyntaxKind.NumericLiteral:
if (isDeclaration(name.parent)) {
return name.parent.name === name;
}
const binExp = name.parent.parent;
return isBinaryExpression(binExp) && getSpecialPropertyAssignmentKind(binExp) !== SpecialPropertyAssignmentKind.None && getNameOfDeclaration(binExp) === name;
default:
return false;
}
}
export function isLiteralComputedPropertyDeclarationName(node: Node) {
return (node.kind === SyntaxKind.StringLiteral || node.kind === SyntaxKind.NumericLiteral) &&
node.parent.kind === SyntaxKind.ComputedPropertyName &&
@@ -3151,11 +3180,11 @@ namespace ts {
}
export function getLocalSymbolForExportDefault(symbol: Symbol) {
return isExportDefaultSymbol(symbol) ? symbol.valueDeclaration.localSymbol : undefined;
return isExportDefaultSymbol(symbol) ? symbol.declarations[0].localSymbol : undefined;
}
function isExportDefaultSymbol(symbol: Symbol): boolean {
return symbol && symbol.valueDeclaration && hasModifier(symbol.valueDeclaration, ModifierFlags.Default);
return symbol && length(symbol.declarations) > 0 && hasModifier(symbol.declarations[0], ModifierFlags.Default);
}
/** Return ".ts", ".d.ts", or ".tsx", if that is the extension. */
-1
View File
@@ -1,4 +1,3 @@
declare const require: any, process: any;
const fs: any = require("fs");
const path: any = require("path");
+2 -1
View File
@@ -127,6 +127,7 @@
"./unittests/printer.ts",
"./unittests/transform.ts",
"./unittests/customTransforms.ts",
"./unittests/textChanges.ts"
"./unittests/textChanges.ts",
"./unittests/telemetry.ts"
]
}
+3 -3
View File
@@ -60,7 +60,7 @@ namespace ts {
assertParseResult(["--lib", "es5,invalidOption", "0.ts"],
{
errors: [{
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'esnext.asynciterable'.",
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'esnext.asynciterable'.",
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
@@ -263,7 +263,7 @@ namespace ts {
assertParseResult(["--lib", "es5,", "es7", "0.ts"],
{
errors: [{
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'esnext.asynciterable'.",
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'esnext.asynciterable'.",
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
@@ -283,7 +283,7 @@ namespace ts {
assertParseResult(["--lib", "es5, ", "es7", "0.ts"],
{
errors: [{
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'esnext.asynciterable'.",
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'esnext.asynciterable'.",
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
@@ -233,7 +233,7 @@ namespace ts {
file: undefined,
start: 0,
length: 0,
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'esnext.asynciterable'.",
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'esnext.asynciterable'.",
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
}]
@@ -264,7 +264,7 @@ namespace ts {
file: undefined,
start: 0,
length: 0,
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'esnext.asynciterable'.",
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'esnext.asynciterable'.",
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
}]
@@ -295,7 +295,7 @@ namespace ts {
file: undefined,
start: 0,
length: 0,
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'esnext.asynciterable'.",
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'esnext.asynciterable'.",
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
}]
@@ -326,7 +326,7 @@ namespace ts {
file: undefined,
start: 0,
length: 0,
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'esnext.asynciterable'.",
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'esnext.asynciterable'.",
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
}]
+35
View File
@@ -98,8 +98,43 @@ namespace ts {
)
])
);
// https://github.com/Microsoft/TypeScript/issues/15971
const classWithOptionalMethodAndProperty = createClassDeclaration(
undefined,
/* modifiers */ createNodeArray([createToken(SyntaxKind.DeclareKeyword)]),
/* name */ createIdentifier("X"),
undefined,
undefined,
createNodeArray([
createMethod(
undefined,
undefined,
undefined,
/* name */ createIdentifier("method"),
/* questionToken */ createToken(SyntaxKind.QuestionToken),
undefined,
undefined,
/* type */ createKeywordTypeNode(SyntaxKind.VoidKeyword),
undefined
),
createProperty(
undefined,
undefined,
/* name */ createIdentifier("property"),
/* questionToken */ createToken(SyntaxKind.QuestionToken),
/* type */ createKeywordTypeNode(SyntaxKind.StringKeyword),
undefined
),
])
);
// tslint:enable boolean-trivia
printsCorrectly("class", {}, printer => printer.printNode(EmitHint.Unspecified, syntheticNode, sourceFile));
printsCorrectly("namespaceExportDeclaration", {}, printer => printer.printNode(EmitHint.Unspecified, createNamespaceExportDeclaration("B"), sourceFile));
printsCorrectly("classWithOptionalMethodAndProperty", {}, printer => printer.printNode(EmitHint.Unspecified, classWithOptionalMethodAndProperty, sourceFile));
});
});
}
@@ -424,6 +424,50 @@ class D { }\r\n\
comment("=======\r\nclass D { }\r\n"),
comment(">>>>>>> Branch - a"),
finalEndOfLineState(ts.EndOfLineState.None));
testLexicalClassification(
"class C {\r\n\
<<<<<<< HEAD\r\n\
v = 1;\r\n\
||||||| merged common ancestors\r\n\
v = 3;\r\n\
=======\r\n\
v = 2;\r\n\
>>>>>>> Branch - a\r\n\
}",
ts.EndOfLineState.None,
keyword("class"),
identifier("C"),
punctuation("{"),
comment("<<<<<<< HEAD"),
identifier("v"),
operator("="),
numberLiteral("1"),
punctuation(";"),
comment("||||||| merged common ancestors\r\n v = 3;\r\n"),
comment("=======\r\n v = 2;\r\n"),
comment(">>>>>>> Branch - a"),
punctuation("}"),
finalEndOfLineState(ts.EndOfLineState.None));
testLexicalClassification(
"<<<<<<< HEAD\r\n\
class C { }\r\n\
||||||| merged common ancestors\r\n\
class E { }\r\n\
=======\r\n\
class D { }\r\n\
>>>>>>> Branch - a\r\n",
ts.EndOfLineState.None,
comment("<<<<<<< HEAD"),
keyword("class"),
identifier("C"),
punctuation("{"),
punctuation("}"),
comment("||||||| merged common ancestors\r\nclass E { }\r\n"),
comment("=======\r\nclass D { }\r\n"),
comment(">>>>>>> Branch - a"),
finalEndOfLineState(ts.EndOfLineState.None));
});
it("'of' keyword", function () {
+291
View File
@@ -0,0 +1,291 @@
/// <reference path="../harness.ts" />
/// <reference path="./tsserverProjectSystem.ts" />
namespace ts.projectSystem {
describe("project telemetry", () => {
it("does nothing for inferred project", () => {
const file = makeFile("/a.js");
const et = new EventTracker([file]);
et.service.openClientFile(file.path);
assert.equal(et.getEvents().length, 0);
});
it("only sends an event once", () => {
const file = makeFile("/a.ts");
const tsconfig = makeFile("/tsconfig.json", {});
const et = new EventTracker([file, tsconfig]);
et.service.openClientFile(file.path);
et.assertProjectInfoTelemetryEvent({});
et.service.closeClientFile(file.path);
checkNumberOfProjects(et.service, { configuredProjects: 0 });
et.service.openClientFile(file.path);
checkNumberOfProjects(et.service, { configuredProjects: 1 });
assert.equal(et.getEvents().length, 0);
});
it("counts files by extension", () => {
const files = ["ts.ts", "tsx.tsx", "moo.ts", "dts.d.ts", "jsx.jsx", "js.js", "badExtension.badExtension"].map(f => makeFile(`/src/${f}`));
const notIncludedFile = makeFile("/bin/ts.js");
const compilerOptions: ts.CompilerOptions = { allowJs: true };
const tsconfig = makeFile("/tsconfig.json", { compilerOptions, include: ["src"] });
const et = new EventTracker([...files, notIncludedFile, tsconfig]);
et.service.openClientFile(files[0].path);
et.assertProjectInfoTelemetryEvent({
fileStats: { ts: 2, tsx: 1, js: 1, jsx: 1, dts: 1 },
compilerOptions,
include: true,
});
});
it("works with external project", () => {
const file1 = makeFile("/a.ts");
const et = new EventTracker([file1]);
const compilerOptions: ts.CompilerOptions = { strict: true };
const projectFileName = "foo.csproj";
open();
// TODO: Apparently compilerOptions is mutated, so have to repeat it here!
et.assertProjectInfoTelemetryEvent({
compilerOptions: { strict: true },
compileOnSave: true,
// These properties can't be present for an external project, so they are undefined instead of false.
extends: undefined,
files: undefined,
include: undefined,
exclude: undefined,
configFileName: "other",
projectType: "external",
});
// Also test that opening an external project only sends an event once.
et.service.closeExternalProject(projectFileName);
checkNumberOfProjects(et.service, { externalProjects: 0 });
open();
assert.equal(et.getEvents().length, 0);
function open(): void {
et.service.openExternalProject({
rootFiles: toExternalFiles([file1.path]),
options: compilerOptions,
projectFileName: projectFileName,
});
checkNumberOfProjects(et.service, { externalProjects: 1 });
}
});
it("does not expose paths", () => {
const file = makeFile("/a.ts");
const compilerOptions: ts.CompilerOptions = {
project: "",
outFile: "hunter2.js",
outDir: "hunter2",
rootDir: "hunter2",
baseUrl: "hunter2",
rootDirs: ["hunter2"],
typeRoots: ["hunter2"],
types: ["hunter2"],
sourceRoot: "hunter2",
mapRoot: "hunter2",
jsxFactory: "hunter2",
out: "hunter2",
reactNamespace: "hunter2",
charset: "hunter2",
locale: "hunter2",
declarationDir: "hunter2",
paths: {
"*": ["hunter2"],
},
// Boolean / number options get through
declaration: true,
// List of string enum gets through -- but only if legitimately a member of the enum
lib: ["es6", "dom", "hunter2"],
// Sensitive data doesn't get through even if sent to an option of safe type
checkJs: "hunter2" as any as boolean,
};
const safeCompilerOptions: ts.CompilerOptions = {
project: "",
outFile: "",
outDir: "",
rootDir: "",
baseUrl: "",
rootDirs: [""],
typeRoots: [""],
types: [""],
sourceRoot: "",
mapRoot: "",
jsxFactory: "",
out: "",
reactNamespace: "",
charset: "",
locale: "",
declarationDir: "",
paths: "" as any,
declaration: true,
lib: ["es6", "dom"],
checkJs: "" as any as boolean,
};
(compilerOptions as any).unknownCompilerOption = "hunter2"; // These are always ignored.
const tsconfig = makeFile("/tsconfig.json", { compilerOptions, files: ["/a.ts"] });
const et = new EventTracker([file, tsconfig]);
et.service.openClientFile(file.path);
et.assertProjectInfoTelemetryEvent({
compilerOptions: safeCompilerOptions,
files: true,
});
});
it("sends telemetry for extends, files, include, exclude, and compileOnSave", () => {
const file = makeFile("/hunter2/a.ts");
const tsconfig = makeFile("/tsconfig.json", {
compilerOptions: {},
extends: "hunter2.json",
files: ["hunter2/a.ts"],
include: ["hunter2"],
exclude: ["hunter2"],
compileOnSave: true,
});
const et = new EventTracker([tsconfig, file]);
et.service.openClientFile(file.path);
et.assertProjectInfoTelemetryEvent({
extends: true,
files: true,
include: true,
exclude: true,
compileOnSave: true,
});
});
const autoJsCompilerOptions = {
// Apparently some options are added by default.
allowJs: true,
allowSyntheticDefaultImports: true,
maxNodeModuleJsDepth: 2,
skipLibCheck: true,
};
it("sends telemetry for typeAcquisition settings", () => {
const file = makeFile("/a.js");
const jsconfig = makeFile("/jsconfig.json", {
compilerOptions: {},
typeAcquisition: {
enable: true,
enableAutoDiscovery: false,
include: ["hunter2", "hunter3"],
exclude: [],
},
});
const et = new EventTracker([jsconfig, file]);
et.service.openClientFile(file.path);
et.assertProjectInfoTelemetryEvent({
fileStats: fileStats({ js: 1 }),
compilerOptions: autoJsCompilerOptions,
typeAcquisition: {
enable: true,
include: true,
exclude: false,
},
configFileName: "jsconfig.json",
});
});
it("detects whether language service was disabled", () => {
const file = makeFile("/a.js");
const tsconfig = makeFile("/jsconfig.json", {});
const et = new EventTracker([tsconfig, file]);
et.host.getFileSize = () => server.maxProgramSizeForNonTsFiles + 1;
et.service.openClientFile(file.path);
et.getEvent<server.ProjectLanguageServiceStateEvent>(server.ProjectLanguageServiceStateEvent, /*mayBeMore*/ true);
et.assertProjectInfoTelemetryEvent({
fileStats: fileStats({ js: 1 }),
compilerOptions: autoJsCompilerOptions,
configFileName: "jsconfig.json",
typeAcquisition: {
enable: true,
include: false,
exclude: false,
},
languageServiceEnabled: false,
});
});
});
class EventTracker {
private events: server.ProjectServiceEvent[] = [];
readonly service: TestProjectService;
readonly host: projectSystem.TestServerHost;
constructor(files: projectSystem.FileOrFolder[]) {
this.host = createServerHost(files);
this.service = createProjectService(this.host, {
eventHandler: event => {
this.events.push(event);
},
});
}
getEvents(): ReadonlyArray<server.ProjectServiceEvent> {
const events = this.events;
this.events = [];
return events;
}
assertProjectInfoTelemetryEvent(partial: Partial<server.ProjectInfoTelemetryEventData>): void {
assert.deepEqual(this.getEvent<server.ProjectInfoTelemetryEvent>(ts.server.ProjectInfoTelemetryEvent), makePayload(partial));
}
getEvent<T extends server.ProjectServiceEvent>(eventName: T["eventName"], mayBeMore = false): T["data"] {
if (mayBeMore) assert(this.events.length !== 0); else assert.equal(this.events.length, 1);
const event = this.events.shift();
assert.equal(event.eventName, eventName);
return event.data;
}
}
function makePayload(partial: Partial<server.ProjectInfoTelemetryEventData>): server.ProjectInfoTelemetryEventData {
return {
fileStats: fileStats({ ts: 1 }),
compilerOptions: {},
extends: false,
files: false,
include: false,
exclude: false,
compileOnSave: false,
typeAcquisition: {
enable: false,
exclude: false,
include: false,
},
configFileName: "tsconfig.json",
projectType: "configured",
languageServiceEnabled: true,
version: ts.version,
...partial
};
}
function makeFile(path: string, content: {} = ""): projectSystem.FileOrFolder {
return { path, content: typeof content === "string" ? "" : JSON.stringify(content) };
}
function fileStats(nonZeroStats: Partial<server.FileStats>): server.FileStats {
return { ts: 0, tsx: 0, dts: 0, js: 0, jsx: 0, ...nonZeroStats };
}
}
@@ -2234,7 +2234,7 @@ namespace ts.projectSystem {
let lastEvent: server.ProjectLanguageServiceStateEvent;
const session = createSession(host, /*typingsInstaller*/ undefined, e => {
if (e.eventName === server.ConfigFileDiagEvent || e.eventName === server.ContextEvent) {
if (e.eventName === server.ConfigFileDiagEvent || e.eventName === server.ContextEvent || e.eventName === server.ProjectInfoTelemetryEvent) {
return;
}
assert.equal(e.eventName, server.ProjectLanguageServiceStateEvent);
@@ -2284,7 +2284,7 @@ namespace ts.projectSystem {
filePath === f2.path ? server.maxProgramSizeForNonTsFiles + 1 : originalGetFileSize.call(host, filePath);
let lastEvent: server.ProjectLanguageServiceStateEvent;
const session = createSession(host, /*typingsInstaller*/ undefined, e => {
if (e.eventName === server.ConfigFileDiagEvent) {
if (e.eventName === server.ConfigFileDiagEvent || e.eventName === server.ProjectInfoTelemetryEvent) {
return;
}
assert.equal(e.eventName, server.ProjectLanguageServiceStateEvent);
+14 -14
View File
@@ -44,7 +44,7 @@ namespace ts.projectSystem {
});
}
import typingsName = server.typingsInstaller.typingsName;
import typingsName = TI.typingsName;
describe("local module", () => {
it("should not be picked up", () => {
@@ -73,7 +73,7 @@ namespace ts.projectSystem {
constructor() {
super(host, { typesRegistry: createTypesRegistry("config"), globalTypingsCacheLocation: typesCache });
}
installWorker(_requestId: number, _args: string[], _cwd: string, _cb: server.typingsInstaller.RequestCompletedAction) {
installWorker(_requestId: number, _args: string[], _cwd: string, _cb: TI.RequestCompletedAction) {
assert(false, "should not be called");
}
})();
@@ -121,7 +121,7 @@ namespace ts.projectSystem {
constructor() {
super(host, { typesRegistry: createTypesRegistry("jquery") });
}
installWorker(_requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction) {
const installedTypings = ["@types/jquery"];
const typingFiles = [jquery];
executeCommand(this, host, installedTypings, typingFiles, cb);
@@ -165,7 +165,7 @@ namespace ts.projectSystem {
constructor() {
super(host, { typesRegistry: createTypesRegistry("jquery") });
}
installWorker(_requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction) {
const installedTypings = ["@types/jquery"];
const typingFiles = [jquery];
executeCommand(this, host, installedTypings, typingFiles, cb);
@@ -672,7 +672,7 @@ namespace ts.projectSystem {
constructor() {
super(host, { globalTypingsCacheLocation: "/tmp", typesRegistry: createTypesRegistry("jquery") });
}
installWorker(_requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction) {
const installedTypings = ["@types/jquery"];
const typingFiles = [jqueryDTS];
executeCommand(this, host, installedTypings, typingFiles, cb);
@@ -718,7 +718,7 @@ namespace ts.projectSystem {
constructor() {
super(host, { globalTypingsCacheLocation: "/tmp", typesRegistry: createTypesRegistry("jquery") });
}
installWorker(_requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction) {
const installedTypings = ["@types/jquery"];
const typingFiles = [jqueryDTS];
executeCommand(this, host, installedTypings, typingFiles, cb);
@@ -765,7 +765,7 @@ namespace ts.projectSystem {
constructor() {
super(host, { globalTypingsCacheLocation: "/tmp", typesRegistry: createTypesRegistry("jquery") });
}
installWorker(_requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction) {
const installedTypings = ["@types/jquery"];
const typingFiles = [jqueryDTS];
executeCommand(this, host, installedTypings, typingFiles, cb);
@@ -808,7 +808,7 @@ namespace ts.projectSystem {
constructor() {
super(host, { globalTypingsCacheLocation: cachePath, typesRegistry: createTypesRegistry("commander") });
}
installWorker(_requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction) {
const installedTypings = ["@types/commander"];
const typingFiles = [commander];
executeCommand(this, host, installedTypings, typingFiles, cb);
@@ -849,7 +849,7 @@ namespace ts.projectSystem {
constructor() {
super(host, { globalTypingsCacheLocation: cachePath, typesRegistry: createTypesRegistry("node", "commander") });
}
installWorker(_requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction) {
const installedTypings = ["@types/node", "@types/commander"];
const typingFiles = [node, commander];
executeCommand(this, host, installedTypings, typingFiles, cb);
@@ -888,7 +888,7 @@ namespace ts.projectSystem {
constructor() {
super(host, { globalTypingsCacheLocation: "/tmp", typesRegistry: createTypesRegistry("foo") });
}
installWorker(_requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction) {
executeCommand(this, host, ["foo"], [], cb);
}
})();
@@ -996,7 +996,7 @@ namespace ts.projectSystem {
constructor() {
super(host, { globalTypingsCacheLocation: "/tmp" }, { isEnabled: () => true, writeLine: msg => messages.push(msg) });
}
installWorker(_requestId: number, _args: string[], _cwd: string, _cb: server.typingsInstaller.RequestCompletedAction) {
installWorker(_requestId: number, _args: string[], _cwd: string, _cb: TI.RequestCompletedAction) {
assert(false, "runCommand should not be invoked");
}
})();
@@ -1060,7 +1060,7 @@ namespace ts.projectSystem {
constructor() {
super(host, { globalTypingsCacheLocation: cachePath, typesRegistry: createTypesRegistry("commander") });
}
installWorker(_requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction) {
const installedTypings = ["@types/commander"];
const typingFiles = [commander];
executeCommand(this, host, installedTypings, typingFiles, cb);
@@ -1110,7 +1110,7 @@ namespace ts.projectSystem {
constructor() {
super(host, { globalTypingsCacheLocation: cachePath, typesRegistry: createTypesRegistry("commander") });
}
installWorker(_requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction) {
const installedTypings = ["@types/commander"];
const typingFiles = [commander];
executeCommand(this, host, installedTypings, typingFiles, cb);
@@ -1157,7 +1157,7 @@ namespace ts.projectSystem {
constructor() {
super(host, { globalTypingsCacheLocation: cachePath, typesRegistry: createTypesRegistry("commander") });
}
installWorker(_requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction) {
executeCommand(this, host, "", [], cb);
}
sendResponse(response: server.SetTypings | server.InvalidateCachedTypings | server.BeginInstallTypes | server.EndInstallTypes) {
+2 -1
View File
@@ -1,4 +1,5 @@
/// <reference path="lib.es2016.d.ts" />
/// <reference path="lib.es2017.object.d.ts" />
/// <reference path="lib.es2017.sharedmemory.d.ts" />
/// <reference path="lib.es2017.string.d.ts" />
/// <reference path="lib.es2017.string.d.ts" />
/// <reference path="lib.es2017.intl.d.ts" />
+10
View File
@@ -0,0 +1,10 @@
type DateTimeFormatPartTypes = "day" | "dayPeriod" | "era" | "hour" | "literal" | "minute" | "month" | "second" | "timeZoneName" | "weekday" | "year";
interface DateTimeFormatPart {
type: DateTimeFormatPartTypes;
value: string;
}
interface DateTimeFormat {
formatToParts(date?: Date | number): DateTimeFormatPart[];
}
+100 -3
View File
@@ -13,6 +13,7 @@ namespace ts.server {
export const ContextEvent = "context";
export const ConfigFileDiagEvent = "configFileDiag";
export const ProjectLanguageServiceStateEvent = "projectLanguageServiceState";
export const ProjectInfoTelemetryEvent = "projectInfo";
export interface ContextEvent {
eventName: typeof ContextEvent;
@@ -29,7 +30,52 @@ namespace ts.server {
data: { project: Project, languageServiceEnabled: boolean };
}
export type ProjectServiceEvent = ContextEvent | ConfigFileDiagEvent | ProjectLanguageServiceStateEvent;
/** This will be converted to the payload of a protocol.TelemetryEvent in session.defaultEventHandler. */
export interface ProjectInfoTelemetryEvent {
readonly eventName: typeof ProjectInfoTelemetryEvent;
readonly data: ProjectInfoTelemetryEventData;
}
export interface ProjectInfoTelemetryEventData {
/** Count of file extensions seen in the project. */
readonly fileStats: FileStats;
/**
* Any compiler options that might contain paths will be taken out.
* Enum compiler options will be converted to strings.
*/
readonly compilerOptions: ts.CompilerOptions;
// "extends", "files", "include", or "exclude" will be undefined if an external config is used.
// Otherwise, we will use "true" if the property is present and "false" if it is missing.
readonly extends: boolean | undefined;
readonly files: boolean | undefined;
readonly include: boolean | undefined;
readonly exclude: boolean | undefined;
readonly compileOnSave: boolean;
readonly typeAcquisition: ProjectInfoTypeAcquisitionData;
readonly configFileName: "tsconfig.json" | "jsconfig.json" | "other";
readonly projectType: "external" | "configured";
readonly languageServiceEnabled: boolean;
/** TypeScript version used by the server. */
readonly version: string;
}
export interface ProjectInfoTypeAcquisitionData {
readonly enable: boolean;
// Actual values of include/exclude entries are scrubbed.
readonly include: boolean;
readonly exclude: boolean;
}
export interface FileStats {
readonly js: number;
readonly jsx: number;
readonly ts: number;
readonly tsx: number;
readonly dts: number;
}
export type ProjectServiceEvent = ContextEvent | ConfigFileDiagEvent | ProjectLanguageServiceStateEvent | ProjectInfoTelemetryEvent;
export interface ProjectServiceEventHandler {
(event: ProjectServiceEvent): void;
@@ -345,6 +391,9 @@ namespace ts.server {
public readonly pluginProbeLocations: ReadonlyArray<string>;
public readonly allowLocalPluginLoads: boolean;
/** Tracks projects that we have already sent telemetry for. */
private readonly seenProjects = createMap<true>();
constructor(opts: ProjectServiceOptions) {
this.host = opts.host;
this.logger = opts.logger;
@@ -934,7 +983,10 @@ namespace ts.server {
const projectOptions: ProjectOptions = {
files: parsedCommandLine.fileNames,
compilerOptions: parsedCommandLine.options,
configHasFilesProperty: config["files"] !== undefined,
configHasExtendsProperty: config.extends !== undefined,
configHasFilesProperty: config.files !== undefined,
configHasIncludeProperty: config.include !== undefined,
configHasExcludeProperty: config.exclude !== undefined,
wildcardDirectories: createMapFromTemplate(parsedCommandLine.wildcardDirectories),
typeAcquisition: parsedCommandLine.typeAcquisition,
compileOnSave: parsedCommandLine.compileOnSave
@@ -984,9 +1036,53 @@ namespace ts.server {
this.addFilesToProjectAndUpdateGraph(project, files, externalFilePropertyReader, /*clientFileName*/ undefined, typeAcquisition, /*configFileErrors*/ undefined);
this.externalProjects.push(project);
this.sendProjectTelemetry(project.externalProjectName, project);
return project;
}
private sendProjectTelemetry(projectKey: string, project: server.ExternalProject | server.ConfiguredProject, projectOptions?: ProjectOptions): void {
if (this.seenProjects.has(projectKey)) {
return;
}
this.seenProjects.set(projectKey, true);
if (!this.eventHandler) return;
const data: ProjectInfoTelemetryEventData = {
fileStats: countEachFileTypes(project.getScriptInfos()),
compilerOptions: convertCompilerOptionsForTelemetry(project.getCompilerOptions()),
typeAcquisition: convertTypeAcquisition(project.getTypeAcquisition()),
extends: projectOptions && projectOptions.configHasExtendsProperty,
files: projectOptions && projectOptions.configHasFilesProperty,
include: projectOptions && projectOptions.configHasIncludeProperty,
exclude: projectOptions && projectOptions.configHasExcludeProperty,
compileOnSave: project.compileOnSaveEnabled,
configFileName: configFileName(),
projectType: project instanceof server.ExternalProject ? "external" : "configured",
languageServiceEnabled: project.languageServiceEnabled,
version: ts.version,
};
this.eventHandler({ eventName: ProjectInfoTelemetryEvent, data });
function configFileName(): ProjectInfoTelemetryEventData["configFileName"] {
if (!(project instanceof server.ConfiguredProject)) {
return "other";
}
const configFilePath = project instanceof server.ConfiguredProject && project.getConfigFilePath();
const base = ts.getBaseFileName(configFilePath);
return base === "tsconfig.json" || base === "jsconfig.json" ? base : "other";
}
function convertTypeAcquisition({ enable, include, exclude }: TypeAcquisition): ProjectInfoTypeAcquisitionData {
return {
enable,
include: include !== undefined && include.length !== 0,
exclude: exclude !== undefined && exclude.length !== 0,
};
}
}
private reportConfigFileDiagnostics(configFileName: string, diagnostics: Diagnostic[], triggerFile: string) {
if (!this.eventHandler) {
return;
@@ -1020,6 +1116,7 @@ namespace ts.server {
project.watchTypeRoots((project, path) => this.onTypeRootFileChanged(project, path));
this.configuredProjects.push(project);
this.sendProjectTelemetry(project.getConfigFilePath(), project, projectOptions);
return project;
}
@@ -1052,7 +1149,7 @@ namespace ts.server {
const conversionResult = this.convertConfigFileContentToProjectOptions(configFileName);
const projectOptions: ProjectOptions = conversionResult.success
? conversionResult.projectOptions
: { files: [], compilerOptions: {}, typeAcquisition: { enable: false } };
: { files: [], compilerOptions: {}, configHasExtendsProperty: false, configHasFilesProperty: false, configHasIncludeProperty: false, configHasExcludeProperty: false, typeAcquisition: { enable: false } };
const project = this.createAndAddConfiguredProject(configFileName, projectOptions, conversionResult.configFileErrors, clientFileName);
return {
success: conversionResult.success,
+16 -9
View File
@@ -13,14 +13,8 @@ namespace ts.server {
External
}
function remove<T>(items: T[], item: T) {
const index = items.indexOf(item);
if (index >= 0) {
items.splice(index, 1);
}
}
function countEachFileTypes(infos: ScriptInfo[]): { js: number, jsx: number, ts: number, tsx: number, dts: number } {
/* @internal */
export function countEachFileTypes(infos: ScriptInfo[]): FileStats {
const result = { js: 0, jsx: 0, ts: 0, tsx: 0, dts: 0 };
for (const info of infos) {
switch (info.scriptKind) {
@@ -732,11 +726,15 @@ namespace ts.server {
// remove a root file from project
protected removeRoot(info: ScriptInfo): void {
remove(this.rootFiles, info);
orderedRemoveItem(this.rootFiles, info);
this.rootFilesMap.remove(info.path);
}
}
/**
* If a file is opened and no tsconfig (or jsconfig) is found,
* the file and its imports/references are put into an InferredProject.
*/
export class InferredProject extends Project {
private static newName = (() => {
@@ -830,6 +828,11 @@ namespace ts.server {
}
}
/**
* If a file is opened, the server will look for a tsconfig (or jsconfig)
* and if successfull create a ConfiguredProject for it.
* Otherwise it will create an InferredProject.
*/
export class ConfiguredProject extends Project {
private typeAcquisition: TypeAcquisition;
private projectFileWatcher: FileWatcher;
@@ -1055,6 +1058,10 @@ namespace ts.server {
}
}
/**
* Project whose configuration is handled externally, such as in a '.csproj'.
* These are created only if a host explicitly calls `openExternalProject`.
*/
export class ExternalProject extends Project {
private typeAcquisition: TypeAcquisition;
constructor(public externalProjectName: string,
+21 -15
View File
@@ -13,6 +13,7 @@ namespace ts.server {
globalTypingsCacheLocation: string;
logger: Logger;
typingSafeListLocation: string;
npmLocation: string | undefined;
telemetryEnabled: boolean;
globalPlugins: string[];
pluginProbeLocations: string[];
@@ -234,6 +235,7 @@ namespace ts.server {
eventPort: number,
readonly globalTypingsCacheLocation: string,
readonly typingSafeListLocation: string,
private readonly npmLocation: string | undefined,
private newLine: string) {
this.throttledOperations = new ThrottledOperations(host);
if (eventPort) {
@@ -278,19 +280,21 @@ namespace ts.server {
if (this.typingSafeListLocation) {
args.push(Arguments.TypingSafeListLocation, this.typingSafeListLocation);
}
if (this.npmLocation) {
args.push(Arguments.NpmLocation, this.npmLocation);
}
const execArgv: string[] = [];
{
for (const arg of process.execArgv) {
const match = /^--(debug|inspect)(=(\d+))?$/.exec(arg);
if (match) {
// if port is specified - use port + 1
// otherwise pick a default port depending on if 'debug' or 'inspect' and use its value + 1
const currentPort = match[3] !== undefined
? +match[3]
: match[1] === "debug" ? 5858 : 9229;
execArgv.push(`--${match[1]}=${currentPort + 1}`);
break;
}
for (const arg of process.execArgv) {
const match = /^--(debug|inspect)(=(\d+))?$/.exec(arg);
if (match) {
// if port is specified - use port + 1
// otherwise pick a default port depending on if 'debug' or 'inspect' and use its value + 1
const currentPort = match[3] !== undefined
? +match[3]
: match[1] === "debug" ? 5858 : 9229;
execArgv.push(`--${match[1]}=${currentPort + 1}`);
break;
}
}
@@ -389,10 +393,10 @@ namespace ts.server {
class IOSession extends Session {
constructor(options: IOSessionOptions) {
const { host, installerEventPort, globalTypingsCacheLocation, typingSafeListLocation, canUseEvents } = options;
const { host, installerEventPort, globalTypingsCacheLocation, typingSafeListLocation, npmLocation, canUseEvents } = options;
const typingsInstaller = disableAutomaticTypingAcquisition
? undefined
: new NodeTypingsInstaller(telemetryEnabled, logger, host, installerEventPort, globalTypingsCacheLocation, typingSafeListLocation, host.newLine);
: new NodeTypingsInstaller(telemetryEnabled, logger, host, installerEventPort, globalTypingsCacheLocation, typingSafeListLocation, npmLocation, host.newLine);
super({
host,
@@ -741,7 +745,8 @@ namespace ts.server {
validateLocaleAndSetLanguage(localeStr, sys);
}
const typingSafeListLocation = findArgument("--typingSafeListLocation");
const typingSafeListLocation = findArgument(Arguments.TypingSafeListLocation);
const npmLocation = findArgument(Arguments.NpmLocation);
const globalPlugins = (findArgument("--globalPlugins") || "").split(",");
const pluginProbeLocations = (findArgument("--pluginProbeLocations") || "").split(",");
@@ -760,6 +765,7 @@ namespace ts.server {
disableAutomaticTypingAcquisition,
globalTypingsCacheLocation: getGlobalTypingsCacheLocation(),
typingSafeListLocation,
npmLocation,
telemetryEnabled,
logger,
globalPlugins,
+10 -1
View File
@@ -337,13 +337,22 @@ namespace ts.server {
const { triggerFile, configFileName, diagnostics } = event.data;
this.configFileDiagnosticEvent(triggerFile, configFileName, diagnostics);
break;
case ProjectLanguageServiceStateEvent:
case ProjectLanguageServiceStateEvent: {
const eventName: protocol.ProjectLanguageServiceStateEventName = "projectLanguageServiceState";
this.event<protocol.ProjectLanguageServiceStateEventBody>({
projectName: event.data.project.getProjectName(),
languageServiceEnabled: event.data.languageServiceEnabled
}, eventName);
break;
}
case ProjectInfoTelemetryEvent: {
const eventName: protocol.TelemetryEventName = "telemetry";
this.event<protocol.TelemetryEventBody>({
telemetryEventName: event.eventName,
payload: event.data,
}, eventName);
break;
}
}
}
+6 -1
View File
@@ -12,13 +12,18 @@ namespace ts.server {
export const LogFile = "--logFile";
export const EnableTelemetry = "--enableTelemetry";
export const TypingSafeListLocation = "--typingSafeListLocation";
/**
* This argument specifies the location of the NPM executable.
* typingsInstaller will run the command with `${npmLocation} install ...`.
*/
export const NpmLocation = "--npmLocation";
}
export function hasArgument(argumentName: string) {
return sys.args.indexOf(argumentName) >= 0;
}
export function findArgument(argumentName: string) {
export function findArgument(argumentName: string): string | undefined {
const index = sys.args.indexOf(argumentName);
return index >= 0 && index < sys.args.length - 1
? sys.args[index + 1]
@@ -30,7 +30,8 @@ namespace ts.server.typingsInstaller {
}
}
function getNPMLocation(processName: string) {
/** Used if `--npmLocation` is not passed. */
function getDefaultNPMLocation(processName: string) {
if (path.basename(processName).indexOf("node") === 0) {
return `"${path.join(path.dirname(process.argv[0]), "npm")}"`;
}
@@ -76,17 +77,23 @@ namespace ts.server.typingsInstaller {
private delayedInitializationError: InitializationFailedResponse;
constructor(globalTypingsCacheLocation: string, typingSafeListLocation: string, throttleLimit: number, log: Log) {
constructor(globalTypingsCacheLocation: string, typingSafeListLocation: string, npmLocation: string | undefined, throttleLimit: number, log: Log) {
super(
sys,
globalTypingsCacheLocation,
typingSafeListLocation ? toPath(typingSafeListLocation, "", createGetCanonicalFileName(sys.useCaseSensitiveFileNames)) : toPath("typingSafeList.json", __dirname, createGetCanonicalFileName(sys.useCaseSensitiveFileNames)),
throttleLimit,
log);
this.npmPath = npmLocation !== undefined ? npmLocation : getDefaultNPMLocation(process.argv[0]);
// If the NPM path contains spaces and isn't wrapped in quotes, do so.
if (this.npmPath.indexOf(" ") !== -1 && this.npmPath[0] !== `"`) {
this.npmPath = `"${this.npmPath}"`;
}
if (this.log.isEnabled()) {
this.log.writeLine(`Process id: ${process.pid}`);
this.log.writeLine(`NPM location: ${this.npmPath} (explicit '${Arguments.NpmLocation}' ${npmLocation === undefined ? "not " : ""} provided)`);
}
this.npmPath = getNPMLocation(process.argv[0]);
({ execSync: this.execSync } = require("child_process"));
this.ensurePackageDirectoryExists(globalTypingsCacheLocation);
@@ -168,6 +175,7 @@ namespace ts.server.typingsInstaller {
const logFilePath = findArgument(server.Arguments.LogFile);
const globalTypingsCacheLocation = findArgument(server.Arguments.GlobalCacheLocation);
const typingSafeListLocation = findArgument(server.Arguments.TypingSafeListLocation);
const npmLocation = findArgument(server.Arguments.NpmLocation);
const log = new FileLog(logFilePath);
if (log.isEnabled()) {
@@ -181,6 +189,6 @@ namespace ts.server.typingsInstaller {
}
process.exit(0);
});
const installer = new NodeTypingsInstaller(globalTypingsCacheLocation, typingSafeListLocation, /*throttleLimit*/5, log);
const installer = new NodeTypingsInstaller(globalTypingsCacheLocation, typingSafeListLocation, npmLocation, /*throttleLimit*/5, log);
installer.listen();
}
}
+4 -1
View File
@@ -164,10 +164,13 @@ namespace ts.server {
}
export interface ProjectOptions {
configHasExtendsProperty: boolean;
/**
* true if config file explicitly listed files
*/
configHasFilesProperty?: boolean;
configHasFilesProperty: boolean;
configHasIncludeProperty: boolean;
configHasExcludeProperty: boolean;
/**
* these fields can be present in the project file
*/
+5 -5
View File
@@ -685,9 +685,9 @@ namespace ts {
continue;
}
// for the ======== add a comment for the first line, and then lex all
// subsequent lines up until the end of the conflict marker.
Debug.assert(ch === CharacterCodes.equals);
// for the ||||||| and ======== markers, add a comment for the first line,
// and then lex all subsequent lines up until the end of the conflict marker.
Debug.assert(ch === CharacterCodes.bar || ch === CharacterCodes.equals);
classifyDisabledMergeCode(text, start, end);
}
}
@@ -782,8 +782,8 @@ namespace ts {
}
function classifyDisabledMergeCode(text: string, start: number, end: number) {
// Classify the line that the ======= marker is on as a comment. Then just lex
// all further tokens and add them to the result.
// Classify the line that the ||||||| or ======= marker is on as a comment.
// Then just lex all further tokens and add them to the result.
let i: number;
for (i = start; i < end; i++) {
if (isLineBreak(text.charCodeAt(i))) {
+62 -85
View File
@@ -176,7 +176,7 @@ namespace ts.FindAllReferences {
fileName: node.getSourceFile().fileName,
textSpan: getTextSpan(node),
isWriteAccess: isWriteAccess(node),
isDefinition: isDeclarationName(node) || isLiteralComputedPropertyDeclarationName(node),
isDefinition: isAnyDeclarationName(node) || isLiteralComputedPropertyDeclarationName(node),
isInString
};
}
@@ -242,22 +242,20 @@ 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 (node.kind === SyntaxKind.Identifier && isDeclarationName(node)) {
if (isAnyDeclarationName(node)) {
return true;
}
const parent = node.parent;
if (parent) {
if (parent.kind === SyntaxKind.PostfixUnaryExpression || parent.kind === SyntaxKind.PrefixUnaryExpression) {
const { parent } = node;
switch (parent && parent.kind) {
case SyntaxKind.PostfixUnaryExpression:
case SyntaxKind.PrefixUnaryExpression:
return true;
}
else if (parent.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>parent).left === node) {
const operator = (<BinaryExpression>parent).operatorToken.kind;
return SyntaxKind.FirstAssignment <= operator && operator <= SyntaxKind.LastAssignment;
}
case SyntaxKind.BinaryExpression:
return (<BinaryExpression>parent).left === node && isAssignmentOperator((<BinaryExpression>parent).operatorToken.kind);
default:
return false;
}
return false;
}
}
@@ -388,7 +386,7 @@ namespace ts.FindAllReferences.Core {
const searchMeaning = getIntersectingMeaningFromDeclarations(getMeaningFromLocation(node), symbol.declarations);
const result: SymbolAndEntries[] = [];
const state = createState(sourceFiles, node, checker, cancellationToken, searchMeaning, options, result);
const state = new State(sourceFiles, /*isForConstructor*/ node.kind === SyntaxKind.ConstructorKeyword, checker, cancellationToken, searchMeaning, options, result);
const search = state.createSearch(node, symbol, /*comingFrom*/ undefined, { allSearchSymbols: populateSearchSymbolSet(symbol, node, checker, options.implementations) });
// Try to get the smallest valid scope that we can limit our search to;
@@ -448,35 +446,9 @@ namespace ts.FindAllReferences.Core {
* Holds all state needed for the finding references.
* Unlike `Search`, there is only one `State`.
*/
interface State extends Options {
/** True if we're searching for constructor references. */
readonly isForConstructor: boolean;
readonly sourceFiles: SourceFile[];
readonly checker: TypeChecker;
readonly cancellationToken: CancellationToken;
readonly searchMeaning: SemanticMeaning;
class State {
/** Cache for `explicitlyinheritsFrom`. */
readonly inheritsFromCache: Map<boolean>;
/** Gets every place to look for references of an exported symbols. See `ImportsResult` in `importTracker.ts` for more documentation. */
getImportSearches(exportSymbol: Symbol, exportInfo: ExportInfo): ImportsResult;
/** @param allSearchSymbols set of additinal symbols for use by `includes`. */
createSearch(location: Node, symbol: Symbol, comingFrom: ImportExport | undefined, searchOptions?: { text?: string, allSearchSymbols?: Symbol[] }): Search;
/**
* Callback to add references for a particular searched symbol.
* This initializes a reference group, so only call this if you will add at least one reference.
*/
referenceAdder(searchSymbol: Symbol, searchLocation: Node): (node: Node) => void;
/** Add a reference with no associated definition. */
addStringOrCommentReference(fileName: string, textSpan: TextSpan): void;
/** Returns `true` the first time we search for a symbol in a file and `false` afterwards. */
markSearchedSymbol(sourceFile: SourceFile, symbol: Symbol): boolean;
readonly inheritsFromCache = createMap<boolean>();
/**
* Type nodes can contain multiple references to the same type. For example:
@@ -485,7 +457,7 @@ namespace ts.FindAllReferences.Core {
* duplicate entries would be returned here as each of the type references is part of
* the same implementation. For that reason, check before we add a new entry.
*/
markSeenContainingTypeReference(containingTypeReference: Node): boolean;
readonly markSeenContainingTypeReference = nodeSeenTracker();
/**
* It's possible that we will encounter the right side of `export { foo as bar } from "x";` more than once.
@@ -498,33 +470,31 @@ namespace ts.FindAllReferences.Core {
* But another reference to it may appear in the same source file.
* See `tests/cases/fourslash/transitiveExportImports3.ts`.
*/
markSeenReExportRHS(rhs: Identifier): boolean;
}
readonly markSeenReExportRHS = nodeSeenTracker();
function createState(sourceFiles: SourceFile[], originalLocation: Node, checker: TypeChecker, cancellationToken: CancellationToken, searchMeaning: SemanticMeaning, options: Options, result: Push<SymbolAndEntries>): State {
const symbolIdToReferences: Entry[][] = [];
const inheritsFromCache = createMap<boolean>();
// Source file ID → symbol ID → Whether the symbol has been searched for in the source file.
const sourceFileToSeenSymbols: Array<Array<true>> = [];
const isForConstructor = originalLocation.kind === SyntaxKind.ConstructorKeyword;
let importTracker: ImportTracker | undefined;
constructor(
readonly sourceFiles: SourceFile[],
/** True if we're searching for constructor references. */
readonly isForConstructor: boolean,
readonly checker: TypeChecker,
readonly cancellationToken: CancellationToken,
readonly searchMeaning: SemanticMeaning,
readonly options: Options,
private readonly result: Push<SymbolAndEntries>) {}
return {
...options,
sourceFiles, isForConstructor, checker, cancellationToken, searchMeaning, inheritsFromCache, getImportSearches, createSearch, referenceAdder, addStringOrCommentReference,
markSearchedSymbol, markSeenContainingTypeReference: nodeSeenTracker(), markSeenReExportRHS: nodeSeenTracker(),
};
function getImportSearches(exportSymbol: Symbol, exportInfo: ExportInfo): ImportsResult {
if (!importTracker) importTracker = createImportTracker(sourceFiles, checker, cancellationToken);
return importTracker(exportSymbol, exportInfo, options.isForRename);
private importTracker: ImportTracker | undefined;
/** Gets every place to look for references of an exported symbols. See `ImportsResult` in `importTracker.ts` for more documentation. */
getImportSearches(exportSymbol: Symbol, exportInfo: ExportInfo): ImportsResult {
if (!this.importTracker) this.importTracker = createImportTracker(this.sourceFiles, this.checker, this.cancellationToken);
return this.importTracker(exportSymbol, exportInfo, this.options.isForRename);
}
function createSearch(location: Node, symbol: Symbol, comingFrom: ImportExport, searchOptions: { text?: string, allSearchSymbols?: Symbol[] } = {}): Search {
/** @param allSearchSymbols set of additinal symbols for use by `includes`. */
createSearch(location: Node, symbol: Symbol, comingFrom: ImportExport | undefined, searchOptions: { text?: string, allSearchSymbols?: Symbol[] } = {}): Search {
// Note: if this is an external module symbol, the name doesn't include quotes.
const { text = stripQuotes(getDeclaredName(checker, symbol, location)), allSearchSymbols = undefined } = searchOptions;
const { text = stripQuotes(getDeclaredName(this.checker, symbol, location)), allSearchSymbols = undefined } = searchOptions;
const escapedText = escapeIdentifier(text);
const parents = options.implementations && getParentSymbolsOfPropertyAccess(location, symbol, checker);
const parents = this.options.implementations && getParentSymbolsOfPropertyAccess(location, symbol, this.checker);
return { location, symbol, comingFrom, text, escapedText, parents, includes };
function includes(referenceSymbol: Symbol): boolean {
@@ -532,27 +502,36 @@ namespace ts.FindAllReferences.Core {
}
}
function referenceAdder(referenceSymbol: Symbol, searchLocation: Node): (node: Node) => void {
const symbolId = getSymbolId(referenceSymbol);
let references = symbolIdToReferences[symbolId];
private readonly symbolIdToReferences: Entry[][] = [];
/**
* Callback to add references for a particular searched symbol.
* This initializes a reference group, so only call this if you will add at least one reference.
*/
referenceAdder(searchSymbol: Symbol, searchLocation: Node): (node: Node) => void {
const symbolId = getSymbolId(searchSymbol);
let references = this.symbolIdToReferences[symbolId];
if (!references) {
references = symbolIdToReferences[symbolId] = [];
result.push({ definition: { type: "symbol", symbol: referenceSymbol, node: searchLocation }, references });
references = this.symbolIdToReferences[symbolId] = [];
this.result.push({ definition: { type: "symbol", symbol: searchSymbol, node: searchLocation }, references });
}
return node => references.push(nodeEntry(node));
}
function addStringOrCommentReference(fileName: string, textSpan: TextSpan): void {
result.push({
/** Add a reference with no associated definition. */
addStringOrCommentReference(fileName: string, textSpan: TextSpan): void {
this.result.push({
definition: undefined,
references: [{ type: "span", fileName, textSpan }]
});
}
function markSearchedSymbol(sourceFile: SourceFile, symbol: Symbol): boolean {
// Source file ID → symbol ID → Whether the symbol has been searched for in the source file.
private readonly sourceFileToSeenSymbols: Array<Array<true>> = [];
/** Returns `true` the first time we search for a symbol in a file and `false` afterwards. */
markSearchedSymbol(sourceFile: SourceFile, symbol: Symbol): boolean {
const sourceId = getNodeId(sourceFile);
const symbolId = getSymbolId(symbol);
const seenSymbols = sourceFileToSeenSymbols[sourceId] || (sourceFileToSeenSymbols[sourceId] = []);
const seenSymbols = this.sourceFileToSeenSymbols[sourceId] || (this.sourceFileToSeenSymbols[sourceId] = []);
return !seenSymbols[symbolId] && (seenSymbols[symbolId] = true);
}
}
@@ -582,7 +561,7 @@ namespace ts.FindAllReferences.Core {
break;
case ExportKind.Default:
// Search for a property access to '.default'. This can't be renamed.
indirectSearch = state.isForRename ? undefined : state.createSearch(exportLocation, exportSymbol, ImportExport.Export, { text: "default" });
indirectSearch = state.options.isForRename ? undefined : state.createSearch(exportLocation, exportSymbol, ImportExport.Export, { text: "default" });
break;
case ExportKind.ExportEquals:
break;
@@ -652,10 +631,12 @@ namespace ts.FindAllReferences.Core {
// If this is private property or method, the scope is the containing class
if (flags & (SymbolFlags.Property | SymbolFlags.Method)) {
const privateDeclaration = find(declarations, d => !!(getModifierFlags(d) & ModifierFlags.Private));
const privateDeclaration = find(declarations, d => hasModifier(d, ModifierFlags.Private));
if (privateDeclaration) {
return getAncestor(privateDeclaration, SyntaxKind.ClassDeclaration);
}
// Else this is a public property and could be accessed from anywhere.
return undefined;
}
// If symbol is of object binding pattern element without property name we would want to
@@ -671,11 +652,6 @@ namespace ts.FindAllReferences.Core {
return undefined;
}
// If this is a synthetic property, it's a property and must be searched for globally.
if ((flags & SymbolFlags.Transient && (<TransientSymbol>symbol).checkFlags & CheckFlags.Synthetic)) {
return undefined;
}
let scope: Node | undefined;
for (const declaration of declarations) {
const container = getContainerNode(declaration);
@@ -808,7 +784,8 @@ namespace ts.FindAllReferences.Core {
return;
}
for (const position of getPossibleSymbolReferencePositions(sourceFile, search.text, container, /*fullStart*/ state.findInComments || container.jsDoc !== undefined)) {
const fullStart = state.options.findInComments || container.jsDoc !== undefined || forEach(search.symbol.declarations, d => d.kind === ts.SyntaxKind.JSDocTypedefTag);
for (const position of getPossibleSymbolReferencePositions(sourceFile, search.text, container, fullStart)) {
getReferencesAtLocation(sourceFile, position, search, state);
}
}
@@ -820,7 +797,7 @@ namespace ts.FindAllReferences.Core {
// This wasn't the start of a token. Check to see if it might be a
// match in a comment or string if that's what the caller is asking
// for.
if (!state.implementations && (state.findInStrings && isInString(sourceFile, position) || state.findInComments && isInNonReferenceComment(sourceFile, position))) {
if (!state.options.implementations && (state.options.findInStrings && isInString(sourceFile, position) || state.options.findInComments && isInNonReferenceComment(sourceFile, position))) {
// In the case where we're looking inside comments/strings, we don't have
// an actual definition. So just use 'undefined' here. Features like
// 'Rename' won't care (as they ignore the definitions), and features like
@@ -886,7 +863,7 @@ namespace ts.FindAllReferences.Core {
addRef();
}
if (!state.isForRename && state.markSeenReExportRHS(name)) {
if (!state.options.isForRename && state.markSeenReExportRHS(name)) {
addReference(name, referenceSymbol, name, state);
}
}
@@ -897,7 +874,7 @@ namespace ts.FindAllReferences.Core {
}
// For `export { foo as bar }`, rename `foo`, but not `bar`.
if (!(referenceLocation === propertyName && state.isForRename)) {
if (!(referenceLocation === propertyName && state.options.isForRename)) {
const exportKind = (referenceLocation as Identifier).originalKeywordKind === ts.SyntaxKind.DefaultKeyword ? ExportKind.Default : ExportKind.Named;
const exportInfo = getExportInfo(referenceSymbol, exportKind, state.checker);
Debug.assert(!!exportInfo);
@@ -939,7 +916,7 @@ namespace ts.FindAllReferences.Core {
const { symbol } = importOrExport;
if (importOrExport.kind === ImportExport.Import) {
if (!state.isForRename || importOrExport.isNamedImport) {
if (!state.options.isForRename || importOrExport.isNamedImport) {
searchForImportedSymbol(symbol, state);
}
}
@@ -965,7 +942,7 @@ namespace ts.FindAllReferences.Core {
function addReference(referenceLocation: Node, relatedSymbol: Symbol, searchLocation: Node, state: State): void {
const addRef = state.referenceAdder(relatedSymbol, searchLocation);
if (state.implementations) {
if (state.options.implementations) {
addImplementationReferences(referenceLocation, addRef, state);
}
else {
+1 -1
View File
@@ -8,7 +8,7 @@ namespace ts.GoToDefinition {
if (referenceFile) {
return [getDefinitionInfoForFileReference(comment.fileName, referenceFile.fileName)];
}
return undefined;
// Might still be on jsdoc, so keep looking.
}
// Type reference directives
+23 -9
View File
@@ -39,13 +39,14 @@ namespace ts {
case SyntaxKind.TypeLiteral:
return SemanticMeaning.Type;
case SyntaxKind.JSDocTypedefTag:
// If it has no name node, it shares the name with the value declaration below it.
return (node as JSDocTypedefTag).name === undefined ? SemanticMeaning.Value | SemanticMeaning.Type : SemanticMeaning.Type;
case SyntaxKind.EnumMember:
case SyntaxKind.ClassDeclaration:
return SemanticMeaning.Value | SemanticMeaning.Type;
case SyntaxKind.EnumDeclaration:
return SemanticMeaning.All;
case SyntaxKind.ModuleDeclaration:
if (isAmbientModule(<ModuleDeclaration>node)) {
return SemanticMeaning.Namespace | SemanticMeaning.Value;
@@ -57,6 +58,7 @@ namespace ts {
return SemanticMeaning.Namespace;
}
case SyntaxKind.EnumDeclaration:
case SyntaxKind.NamedImports:
case SyntaxKind.ImportSpecifier:
case SyntaxKind.ImportEqualsDeclaration:
@@ -70,7 +72,7 @@ namespace ts {
return SemanticMeaning.Namespace | SemanticMeaning.Value;
}
return SemanticMeaning.Value | SemanticMeaning.Type | SemanticMeaning.Namespace;
return SemanticMeaning.All;
}
export function getMeaningFromLocation(node: Node): SemanticMeaning {
@@ -78,7 +80,7 @@ namespace ts {
return SemanticMeaning.Value;
}
else if (node.parent.kind === SyntaxKind.ExportAssignment) {
return SemanticMeaning.Value | SemanticMeaning.Type | SemanticMeaning.Namespace;
return SemanticMeaning.All;
}
else if (isInRightSideOfImport(node)) {
return getMeaningFromRightHandSideOfImportEquals(node);
@@ -162,10 +164,22 @@ namespace ts {
node = node.parent;
}
return node.parent.kind === SyntaxKind.TypeReference ||
(node.parent.kind === SyntaxKind.ExpressionWithTypeArguments && !isExpressionWithTypeArgumentsInClassExtendsClause(<ExpressionWithTypeArguments>node.parent)) ||
(node.kind === SyntaxKind.ThisKeyword && !isPartOfExpression(node)) ||
node.kind === SyntaxKind.ThisType;
switch (node.kind) {
case SyntaxKind.ThisKeyword:
return !isPartOfExpression(node);
case SyntaxKind.ThisType:
return true;
}
switch (node.parent.kind) {
case SyntaxKind.TypeReference:
case SyntaxKind.JSDocTypeReference:
return true;
case SyntaxKind.ExpressionWithTypeArguments:
return !isExpressionWithTypeArgumentsInClassExtendsClause(<ExpressionWithTypeArguments>node.parent);
}
return false;
}
export function isCallExpressionTarget(node: Node): boolean {
@@ -6,7 +6,7 @@
"0": {
"kind": "JSDocParameterTag",
"pos": 8,
"end": 27,
"end": 28,
"atToken": {
"kind": "AtToken",
"pos": 8,
@@ -34,7 +34,7 @@
"end": 27,
"text": "name1"
},
"parameterName": {
"name": {
"kind": "Identifier",
"pos": 22,
"end": 27,
@@ -44,6 +44,6 @@
},
"length": 1,
"pos": 8,
"end": 27
"end": 28
}
}
@@ -6,7 +6,7 @@
"0": {
"kind": "JSDocParameterTag",
"pos": 8,
"end": 32,
"end": 33,
"atToken": {
"kind": "AtToken",
"pos": 8,
@@ -34,7 +34,7 @@
"end": 32,
"text": "name1"
},
"parameterName": {
"name": {
"kind": "Identifier",
"pos": 27,
"end": 32,
@@ -44,6 +44,6 @@
},
"length": 1,
"pos": 8,
"end": 32
"end": 33
}
}
@@ -6,7 +6,7 @@
"0": {
"kind": "JSDocParameterTag",
"pos": 8,
"end": 29,
"end": 30,
"atToken": {
"kind": "AtToken",
"pos": 8,
@@ -34,7 +34,7 @@
"end": 29,
"text": "name1"
},
"parameterName": {
"name": {
"kind": "Identifier",
"pos": 24,
"end": 29,
@@ -44,6 +44,6 @@
},
"length": 1,
"pos": 8,
"end": 29
"end": 30
}
}
@@ -6,7 +6,7 @@
"0": {
"kind": "JSDocParameterTag",
"pos": 8,
"end": 29,
"end": 30,
"atToken": {
"kind": "AtToken",
"pos": 8,
@@ -34,7 +34,7 @@
"end": 29,
"text": "name1"
},
"parameterName": {
"name": {
"kind": "Identifier",
"pos": 24,
"end": 29,
@@ -44,6 +44,6 @@
},
"length": 1,
"pos": 8,
"end": 29
"end": 30
}
}
@@ -34,7 +34,7 @@
"end": 30,
"text": "name1"
},
"parameterName": {
"name": {
"kind": "Identifier",
"pos": 25,
"end": 30,
@@ -34,7 +34,7 @@
"end": 31,
"text": "name1"
},
"parameterName": {
"name": {
"kind": "Identifier",
"pos": 26,
"end": 31,
@@ -34,7 +34,7 @@
"end": 28
}
},
"parameterName": {
"name": {
"kind": "Identifier",
"pos": 15,
"end": 20,
@@ -34,7 +34,7 @@
"end": 28
}
},
"parameterName": {
"name": {
"kind": "Identifier",
"pos": 15,
"end": 20,
@@ -6,7 +6,7 @@
"0": {
"kind": "JSDocParameterTag",
"pos": 8,
"end": 18,
"end": 19,
"atToken": {
"kind": "AtToken",
"pos": 8,
@@ -24,7 +24,7 @@
"end": 18,
"text": "foo"
},
"parameterName": {
"name": {
"kind": "Identifier",
"pos": 15,
"end": 18,
@@ -34,6 +34,6 @@
},
"length": 1,
"pos": 8,
"end": 18
"end": 19
}
}
@@ -6,7 +6,7 @@
"0": {
"kind": "JSDocParameterTag",
"pos": 8,
"end": 29,
"end": 32,
"atToken": {
"kind": "AtToken",
"pos": 8,
@@ -34,7 +34,7 @@
"end": 29,
"text": "name1"
},
"parameterName": {
"name": {
"kind": "Identifier",
"pos": 24,
"end": 29,
@@ -45,7 +45,7 @@
"1": {
"kind": "JSDocParameterTag",
"pos": 34,
"end": 55,
"end": 56,
"atToken": {
"kind": "AtToken",
"pos": 34,
@@ -73,7 +73,7 @@
"end": 55,
"text": "name2"
},
"parameterName": {
"name": {
"kind": "Identifier",
"pos": 50,
"end": 55,
@@ -83,6 +83,6 @@
},
"length": 2,
"pos": 8,
"end": 55
"end": 56
}
}
@@ -6,7 +6,7 @@
"0": {
"kind": "JSDocParameterTag",
"pos": 8,
"end": 29,
"end": 30,
"atToken": {
"kind": "AtToken",
"pos": 8,
@@ -34,7 +34,7 @@
"end": 29,
"text": "name1"
},
"parameterName": {
"name": {
"kind": "Identifier",
"pos": 24,
"end": 29,
@@ -45,7 +45,7 @@
"1": {
"kind": "JSDocParameterTag",
"pos": 30,
"end": 51,
"end": 52,
"atToken": {
"kind": "AtToken",
"pos": 30,
@@ -73,7 +73,7 @@
"end": 51,
"text": "name2"
},
"parameterName": {
"name": {
"kind": "Identifier",
"pos": 46,
"end": 51,
@@ -83,6 +83,6 @@
},
"length": 2,
"pos": 8,
"end": 51
"end": 52
}
}
@@ -82,12 +82,6 @@
"end": 56,
"text": "property"
},
"name": {
"kind": "Identifier",
"pos": 66,
"end": 69,
"text": "age"
},
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 57,
@@ -97,6 +91,18 @@
"pos": 58,
"end": 64
}
},
"postParameterName": {
"kind": "Identifier",
"pos": 66,
"end": 69,
"text": "age"
},
"name": {
"kind": "Identifier",
"pos": 66,
"end": 69,
"text": "age"
}
},
{
@@ -114,12 +120,6 @@
"end": 83,
"text": "property"
},
"name": {
"kind": "Identifier",
"pos": 93,
"end": 97,
"text": "name"
},
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 84,
@@ -129,6 +129,18 @@
"pos": 85,
"end": 91
}
},
"postParameterName": {
"kind": "Identifier",
"pos": 93,
"end": 97,
"text": "name"
},
"name": {
"kind": "Identifier",
"pos": 93,
"end": 97,
"text": "name"
}
}
]
@@ -4,5 +4,4 @@ export const a = 1;
//// [alwaysStrictModule3.js]
// module ES2015
// module ES2015
export var a = 1;
@@ -4,5 +4,4 @@ export const a = 1;
//// [alwaysStrictModule5.js]
// Targeting ES6
// Targeting ES6
export const a = 1;
@@ -83,25 +83,25 @@ var p5 = ([a = 1]) => { };
>1 : 1
var p6 = ({ a }) => { };
>p6 : ({a}: { a: any; }) => void
>({ a }) => { } : ({a}: { a: any; }) => void
>p6 : ({ a }: { a: any; }) => void
>({ a }) => { } : ({ a }: { a: any; }) => void
>a : any
var p7 = ({ a: { b } }) => { };
>p7 : ({a: {b}}: { a: { b: any; }; }) => void
>({ a: { b } }) => { } : ({a: {b}}: { a: { b: any; }; }) => void
>p7 : ({ a: { b } }: { a: { b: any; }; }) => void
>({ a: { b } }) => { } : ({ a: { b } }: { a: { b: any; }; }) => void
>a : any
>b : any
var p8 = ({ a = 1 }) => { };
>p8 : ({a}: { a?: number; }) => void
>({ a = 1 }) => { } : ({a}: { a?: number; }) => void
>p8 : ({ a }: { a?: number; }) => void
>({ a = 1 }) => { } : ({ a }: { a?: number; }) => void
>a : number
>1 : 1
var p9 = ({ a: { b = 1 } = { b: 1 } }) => { };
>p9 : ({a: {b}}: { a?: { b?: number; }; }) => void
>({ a: { b = 1 } = { b: 1 } }) => { } : ({a: {b}}: { a?: { b?: number; }; }) => void
>p9 : ({ a: { b } }: { a?: { b?: number; }; }) => void
>({ a: { b = 1 } = { b: 1 } }) => { } : ({ a: { b } }: { a?: { b?: number; }; }) => void
>a : any
>b : number
>1 : 1
@@ -110,8 +110,8 @@ var p9 = ({ a: { b = 1 } = { b: 1 } }) => { };
>1 : 1
var p10 = ([{ value, done }]) => { };
>p10 : ([{value, done}]: [{ value: any; done: any; }]) => void
>([{ value, done }]) => { } : ([{value, done}]: [{ value: any; done: any; }]) => void
>p10 : ([{ value, done }]: [{ value: any; done: any; }]) => void
>([{ value, done }]) => { } : ([{ value, done }]: [{ value: any; done: any; }]) => void
>value : any
>done : any
@@ -144,7 +144,6 @@ for (const y = 0; y < 1;) {
//// [capturedLetConstInLoop4_ES6.js]
//======let
//======let
export function exportedFoo() {
return v0 + v00 + v1 + v2 + v3 + v4 + v5 + v6 + v7 + v8;
}
@@ -0,0 +1,84 @@
//// [0.js]
// @ts-check
/**
* @typedef {Object} Opts
* @property {string} x
* @property {string=} y
* @property {string} [z]
* @property {string} [w="hi"]
*
* @param {Opts} opts
*/
function foo(opts) {
opts.x;
}
foo({x: 'abc'});
/**
* @typedef {Object} AnotherOpts
* @property anotherX {string}
* @property anotherY {string=}
*
* @param {AnotherOpts} opts
*/
function foo1(opts) {
opts.anotherX;
}
foo1({anotherX: "world"});
/**
* @typedef {object} Opts1
* @property {string} x
* @property {string=} y
* @property {string} [z]
* @property {string} [w="hi"]
*
* @param {Opts1} opts
*/
function foo2(opts) {
opts.x;
}
foo2({x: 'abc'});
//// [0.js]
// @ts-check
/**
* @typedef {Object} Opts
* @property {string} x
* @property {string=} y
* @property {string} [z]
* @property {string} [w="hi"]
*
* @param {Opts} opts
*/
function foo(opts) {
opts.x;
}
foo({ x: 'abc' });
/**
* @typedef {Object} AnotherOpts
* @property anotherX {string}
* @property anotherY {string=}
*
* @param {AnotherOpts} opts
*/
function foo1(opts) {
opts.anotherX;
}
foo1({ anotherX: "world" });
/**
* @typedef {object} Opts1
* @property {string} x
* @property {string=} y
* @property {string} [z]
* @property {string} [w="hi"]
*
* @param {Opts1} opts
*/
function foo2(opts) {
opts.x;
}
foo2({ x: 'abc' });
@@ -0,0 +1,68 @@
=== tests/cases/conformance/jsdoc/0.js ===
// @ts-check
/**
* @typedef {Object} Opts
* @property {string} x
* @property {string=} y
* @property {string} [z]
* @property {string} [w="hi"]
*
* @param {Opts} opts
*/
function foo(opts) {
>foo : Symbol(foo, Decl(0.js, 0, 0))
>opts : Symbol(opts, Decl(0.js, 10, 13))
opts.x;
>opts.x : Symbol(x, Decl(0.js, 3, 3))
>opts : Symbol(opts, Decl(0.js, 10, 13))
>x : Symbol(x, Decl(0.js, 3, 3))
}
foo({x: 'abc'});
>foo : Symbol(foo, Decl(0.js, 0, 0))
>x : Symbol(x, Decl(0.js, 14, 5))
/**
* @typedef {Object} AnotherOpts
* @property anotherX {string}
* @property anotherY {string=}
*
* @param {AnotherOpts} opts
*/
function foo1(opts) {
>foo1 : Symbol(foo1, Decl(0.js, 14, 16))
>opts : Symbol(opts, Decl(0.js, 23, 14))
opts.anotherX;
>opts.anotherX : Symbol(anotherX, Decl(0.js, 18, 3))
>opts : Symbol(opts, Decl(0.js, 23, 14))
>anotherX : Symbol(anotherX, Decl(0.js, 18, 3))
}
foo1({anotherX: "world"});
>foo1 : Symbol(foo1, Decl(0.js, 14, 16))
>anotherX : Symbol(anotherX, Decl(0.js, 27, 6))
/**
* @typedef {object} Opts1
* @property {string} x
* @property {string=} y
* @property {string} [z]
* @property {string} [w="hi"]
*
* @param {Opts1} opts
*/
function foo2(opts) {
>foo2 : Symbol(foo2, Decl(0.js, 27, 26))
>opts : Symbol(opts, Decl(0.js, 38, 14))
opts.x;
>opts.x : Symbol(x, Decl(0.js, 31, 3))
>opts : Symbol(opts, Decl(0.js, 38, 14))
>x : Symbol(x, Decl(0.js, 31, 3))
}
foo2({x: 'abc'});
>foo2 : Symbol(foo2, Decl(0.js, 27, 26))
>x : Symbol(x, Decl(0.js, 41, 6))
@@ -0,0 +1,77 @@
=== tests/cases/conformance/jsdoc/0.js ===
// @ts-check
/**
* @typedef {Object} Opts
* @property {string} x
* @property {string=} y
* @property {string} [z]
* @property {string} [w="hi"]
*
* @param {Opts} opts
*/
function foo(opts) {
>foo : (opts: { x: string; y?: string; z?: string; w?: string; }) => void
>opts : { x: string; y?: string; z?: string; w?: string; }
opts.x;
>opts.x : string
>opts : { x: string; y?: string; z?: string; w?: string; }
>x : string
}
foo({x: 'abc'});
>foo({x: 'abc'}) : void
>foo : (opts: { x: string; y?: string; z?: string; w?: string; }) => void
>{x: 'abc'} : { x: string; }
>x : string
>'abc' : "abc"
/**
* @typedef {Object} AnotherOpts
* @property anotherX {string}
* @property anotherY {string=}
*
* @param {AnotherOpts} opts
*/
function foo1(opts) {
>foo1 : (opts: { anotherX: string; anotherY?: string; }) => void
>opts : { anotherX: string; anotherY?: string; }
opts.anotherX;
>opts.anotherX : string
>opts : { anotherX: string; anotherY?: string; }
>anotherX : string
}
foo1({anotherX: "world"});
>foo1({anotherX: "world"}) : void
>foo1 : (opts: { anotherX: string; anotherY?: string; }) => void
>{anotherX: "world"} : { anotherX: string; }
>anotherX : string
>"world" : "world"
/**
* @typedef {object} Opts1
* @property {string} x
* @property {string=} y
* @property {string} [z]
* @property {string} [w="hi"]
*
* @param {Opts1} opts
*/
function foo2(opts) {
>foo2 : (opts: { x: string; y?: string; z?: string; w?: string; }) => void
>opts : { x: string; y?: string; z?: string; w?: string; }
opts.x;
>opts.x : string
>opts : { x: string; y?: string; z?: string; w?: string; }
>x : string
}
foo2({x: 'abc'});
>foo2({x: 'abc'}) : void
>foo2 : (opts: { x: string; y?: string; z?: string; w?: string; }) => void
>{x: 'abc'} : { x: string; }
>x : string
>'abc' : "abc"
@@ -0,0 +1,57 @@
//// [file.tsx]
import React = require('react');
<div>
// Not Comment
</div>;
<div>
// Not Comment
{
//Comment just Fine
}
// Another not Comment
</div>;
<div>
// Not Comment
{
//Comment just Fine
"Hi"
}
// Another not Comment
</div>;
<div>
/* Not Comment */
{
//Comment just Fine
"Hi"
}
</div>;
//// [file.jsx]
"use strict";
exports.__esModule = true;
var React = require("react");
<div>
// Not Comment
</div>;
<div>
// Not Comment
// Another not Comment
</div>;
<div>
// Not Comment
{
//Comment just Fine
"Hi"}
// Another not Comment
</div>;
<div>
/* Not Comment */
{
//Comment just Fine
"Hi"}
</div>;
@@ -0,0 +1,45 @@
=== tests/cases/conformance/jsx/file.tsx ===
import React = require('react');
>React : Symbol(React, Decl(file.tsx, 0, 0))
<div>
>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45))
// Not Comment
</div>;
>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45))
<div>
>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45))
// Not Comment
{
//Comment just Fine
}
// Another not Comment
</div>;
>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45))
<div>
>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45))
// Not Comment
{
//Comment just Fine
"Hi"
}
// Another not Comment
</div>;
>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45))
<div>
>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45))
/* Not Comment */
{
//Comment just Fine
"Hi"
}
</div>;
>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45))
@@ -0,0 +1,51 @@
=== tests/cases/conformance/jsx/file.tsx ===
import React = require('react');
>React : typeof React
<div>
><div> // Not Comment</div> : JSX.Element
>div : any
// Not Comment
</div>;
>div : any
<div>
><div> // Not Comment { //Comment just Fine } // Another not Comment</div> : JSX.Element
>div : any
// Not Comment
{
//Comment just Fine
}
// Another not Comment
</div>;
>div : any
<div>
><div> // Not Comment { //Comment just Fine "Hi" } // Another not Comment</div> : JSX.Element
>div : any
// Not Comment
{
//Comment just Fine
"Hi"
>"Hi" : "Hi"
}
// Another not Comment
</div>;
>div : any
<div>
><div> /* Not Comment */ { //Comment just Fine "Hi" }</div> : JSX.Element
>div : any
/* Not Comment */
{
//Comment just Fine
"Hi"
>"Hi" : "Hi"
}
</div>;
>div : any
@@ -0,0 +1,31 @@
//// [commentsAfterCaseClauses1.ts]
function getSecurity(level) {
switch(level){
case 0: // Zero
case 1: // one
case 2: // two
return "Hi";
case 3: // three
case 4 : // four
return "hello";
case 5: // five
default: // default
return "world";
}
}
//// [commentsAfterCaseClauses1.js]
function getSecurity(level) {
switch (level) {
case 0: // Zero
case 1: // one
case 2:// two
return "Hi";
case 3: // three
case 4:// four
return "hello";
case 5: // five
default:// default
return "world";
}
}
@@ -0,0 +1,20 @@
=== tests/cases/compiler/commentsAfterCaseClauses1.ts ===
function getSecurity(level) {
>getSecurity : Symbol(getSecurity, Decl(commentsAfterCaseClauses1.ts, 0, 0))
>level : Symbol(level, Decl(commentsAfterCaseClauses1.ts, 0, 21))
switch(level){
>level : Symbol(level, Decl(commentsAfterCaseClauses1.ts, 0, 21))
case 0: // Zero
case 1: // one
case 2: // two
return "Hi";
case 3: // three
case 4 : // four
return "hello";
case 5: // five
default: // default
return "world";
}
}
@@ -0,0 +1,37 @@
=== tests/cases/compiler/commentsAfterCaseClauses1.ts ===
function getSecurity(level) {
>getSecurity : (level: any) => "Hi" | "hello" | "world"
>level : any
switch(level){
>level : any
case 0: // Zero
>0 : 0
case 1: // one
>1 : 1
case 2: // two
>2 : 2
return "Hi";
>"Hi" : "Hi"
case 3: // three
>3 : 3
case 4 : // four
>4 : 4
return "hello";
>"hello" : "hello"
case 5: // five
>5 : 5
default: // default
return "world";
>"world" : "world"
}
}
@@ -0,0 +1,36 @@
//// [commentsAfterCaseClauses2.ts]
function getSecurity(level) {
switch(level){
case 0: // Zero
case 1: // one
case 2: // two
// Leading comments
return "Hi";
case 3: // three
case 4: // four
return "hello";
case 5: // five
default: // default
return "world";
// Comment After
} /*Comment 1*/ // Comment After 1
// Comment After 2
}
//// [commentsAfterCaseClauses2.js]
function getSecurity(level) {
switch (level) {
case 0: // Zero
case 1: // one
case 2:// two
// Leading comments
return "Hi";
case 3: // three
case 4:// four
return "hello";
case 5: // five
default:// default
return "world";
} /*Comment 1*/ // Comment After 1
// Comment After 2
}
@@ -0,0 +1,23 @@
=== tests/cases/compiler/commentsAfterCaseClauses2.ts ===
function getSecurity(level) {
>getSecurity : Symbol(getSecurity, Decl(commentsAfterCaseClauses2.ts, 0, 0))
>level : Symbol(level, Decl(commentsAfterCaseClauses2.ts, 0, 21))
switch(level){
>level : Symbol(level, Decl(commentsAfterCaseClauses2.ts, 0, 21))
case 0: // Zero
case 1: // one
case 2: // two
// Leading comments
return "Hi";
case 3: // three
case 4: // four
return "hello";
case 5: // five
default: // default
return "world";
// Comment After
} /*Comment 1*/ // Comment After 1
// Comment After 2
}
@@ -0,0 +1,41 @@
=== tests/cases/compiler/commentsAfterCaseClauses2.ts ===
function getSecurity(level) {
>getSecurity : (level: any) => "Hi" | "hello" | "world"
>level : any
switch(level){
>level : any
case 0: // Zero
>0 : 0
case 1: // one
>1 : 1
case 2: // two
>2 : 2
// Leading comments
return "Hi";
>"Hi" : "Hi"
case 3: // three
>3 : 3
case 4: // four
>4 : 4
return "hello";
>"hello" : "hello"
case 5: // five
>5 : 5
default: // default
return "world";
>"world" : "world"
// Comment After
} /*Comment 1*/ // Comment After 1
// Comment After 2
}
@@ -0,0 +1,34 @@
//// [commentsAfterCaseClauses3.ts]
function getSecurity(level) {
switch(level){
case 0: /*Zero*/
case 1: /*One*/
case 2: /*two*/
// Leading comments
return "Hi";
case 3: /*three*/
case 4: /*four*/
return "hello";
case 5: /*five*/
default: /*six*/
return "world";
}
}
//// [commentsAfterCaseClauses3.js]
function getSecurity(level) {
switch (level) {
case 0: /*Zero*/
case 1: /*One*/
case 2:/*two*/
// Leading comments
return "Hi";
case 3: /*three*/
case 4:/*four*/
return "hello";
case 5: /*five*/
default:/*six*/
return "world";
}
}
@@ -0,0 +1,22 @@
=== tests/cases/compiler/commentsAfterCaseClauses3.ts ===
function getSecurity(level) {
>getSecurity : Symbol(getSecurity, Decl(commentsAfterCaseClauses3.ts, 0, 0))
>level : Symbol(level, Decl(commentsAfterCaseClauses3.ts, 0, 21))
switch(level){
>level : Symbol(level, Decl(commentsAfterCaseClauses3.ts, 0, 21))
case 0: /*Zero*/
case 1: /*One*/
case 2: /*two*/
// Leading comments
return "Hi";
case 3: /*three*/
case 4: /*four*/
return "hello";
case 5: /*five*/
default: /*six*/
return "world";
}
}
@@ -0,0 +1,39 @@
=== tests/cases/compiler/commentsAfterCaseClauses3.ts ===
function getSecurity(level) {
>getSecurity : (level: any) => "Hi" | "hello" | "world"
>level : any
switch(level){
>level : any
case 0: /*Zero*/
>0 : 0
case 1: /*One*/
>1 : 1
case 2: /*two*/
>2 : 2
// Leading comments
return "Hi";
>"Hi" : "Hi"
case 3: /*three*/
>3 : 3
case 4: /*four*/
>4 : 4
return "hello";
>"hello" : "hello"
case 5: /*five*/
>5 : 5
default: /*six*/
return "world";
>"world" : "world"
}
}
@@ -0,0 +1,24 @@
tests/cases/compiler/conflictMarkerDiff3Trivia1.ts(2,1): error TS1185: Merge conflict marker encountered.
tests/cases/compiler/conflictMarkerDiff3Trivia1.ts(4,1): error TS1185: Merge conflict marker encountered.
tests/cases/compiler/conflictMarkerDiff3Trivia1.ts(6,1): error TS1185: Merge conflict marker encountered.
tests/cases/compiler/conflictMarkerDiff3Trivia1.ts(8,1): error TS1185: Merge conflict marker encountered.
==== tests/cases/compiler/conflictMarkerDiff3Trivia1.ts (4 errors) ====
class C {
<<<<<<< HEAD
~~~~~~~
!!! error TS1185: Merge conflict marker encountered.
v = 1;
||||||| merged common ancestors
~~~~~~~
!!! error TS1185: Merge conflict marker encountered.
v = 3;
=======
~~~~~~~
!!! error TS1185: Merge conflict marker encountered.
v = 2;
>>>>>>> Branch-a
~~~~~~~
!!! error TS1185: Merge conflict marker encountered.
}
@@ -0,0 +1,18 @@
//// [conflictMarkerDiff3Trivia1.ts]
class C {
<<<<<<< HEAD
v = 1;
||||||| merged common ancestors
v = 3;
=======
v = 2;
>>>>>>> Branch-a
}
//// [conflictMarkerDiff3Trivia1.js]
var C = (function () {
function C() {
this.v = 1;
}
return C;
}());
@@ -0,0 +1,34 @@
tests/cases/compiler/conflictMarkerDiff3Trivia2.ts(3,1): error TS1185: Merge conflict marker encountered.
tests/cases/compiler/conflictMarkerDiff3Trivia2.ts(4,6): error TS2304: Cannot find name 'a'.
tests/cases/compiler/conflictMarkerDiff3Trivia2.ts(6,1): error TS1185: Merge conflict marker encountered.
tests/cases/compiler/conflictMarkerDiff3Trivia2.ts(9,1): error TS1185: Merge conflict marker encountered.
tests/cases/compiler/conflictMarkerDiff3Trivia2.ts(12,1): error TS1185: Merge conflict marker encountered.
==== tests/cases/compiler/conflictMarkerDiff3Trivia2.ts (5 errors) ====
class C {
foo() {
<<<<<<< B
~~~~~~~
!!! error TS1185: Merge conflict marker encountered.
a();
~
!!! error TS2304: Cannot find name 'a'.
}
||||||| merged common ancestors
~~~~~~~
!!! error TS1185: Merge conflict marker encountered.
c();
}
=======
~~~~~~~
!!! error TS1185: Merge conflict marker encountered.
b();
}
>>>>>>> A
~~~~~~~
!!! error TS1185: Merge conflict marker encountered.
public bar() { }
}
@@ -0,0 +1,28 @@
//// [conflictMarkerDiff3Trivia2.ts]
class C {
foo() {
<<<<<<< B
a();
}
||||||| merged common ancestors
c();
}
=======
b();
}
>>>>>>> A
public bar() { }
}
//// [conflictMarkerDiff3Trivia2.js]
var C = (function () {
function C() {
}
C.prototype.foo = function () {
a();
};
C.prototype.bar = function () { };
return C;
}());
@@ -7,7 +7,7 @@ interface Show {
>x : number
}
function f({ show = v => v.toString() }: Show) {}
>f : ({show}: Show) => void
>f : ({ show }: Show) => void
>show : (x: number) => string
>v => v.toString() : (v: number) => string
>v : number
@@ -18,7 +18,7 @@ function f({ show = v => v.toString() }: Show) {}
>Show : Show
function f2({ "show": showRename = v => v.toString() }: Show) {}
>f2 : ({"show": showRename}: Show) => void
>f2 : ({ "show": showRename }: Show) => void
>showRename : (x: number) => string
>v => v.toString() : (v: number) => string
>v : number
@@ -29,7 +29,7 @@ function f2({ "show": showRename = v => v.toString() }: Show) {}
>Show : Show
function f3({ ["show"]: showRename = v => v.toString() }: Show) {}
>f3 : ({["show"]: showRename}: Show) => void
>f3 : ({ ["show"]: showRename }: Show) => void
>"show" : "show"
>showRename : (x: number) => string
>v => v.toString() : (v: number) => string
@@ -48,7 +48,7 @@ interface Nested {
>Show : Show
}
function ff({ nested = { show: v => v.toString() } }: Nested) {}
>ff : ({nested}: Nested) => void
>ff : ({ nested }: Nested) => void
>nested : Show
>{ show: v => v.toString() } : { show: (v: number) => string; }
>show : (v: number) => string
@@ -67,7 +67,7 @@ interface Tuples {
>prop : [string, number]
}
function g({ prop = ["hello", 1234] }: Tuples) {}
>g : ({prop}: Tuples) => void
>g : ({ prop }: Tuples) => void
>prop : [string, number]
>["hello", 1234] : [string, number]
>"hello" : "hello"
@@ -81,7 +81,7 @@ interface StringUnion {
>prop : "foo" | "bar"
}
function h({ prop = "foo" }: StringUnion) {}
>h : ({prop}: StringUnion) => void
>h : ({ prop }: StringUnion) => void
>prop : "foo" | "bar"
>"foo" : "foo"
>StringUnion : StringUnion
@@ -7,7 +7,7 @@ interface Show {
>x : number
}
function f({ show: showRename = v => v }: Show) {}
>f : ({show: showRename}: Show) => void
>f : ({ show: showRename }: Show) => void
>show : any
>showRename : ((x: number) => string) | ((v: number) => number)
>v => v : (v: number) => number
@@ -16,7 +16,7 @@ function f({ show: showRename = v => v }: Show) {}
>Show : Show
function f2({ "show": showRename = v => v }: Show) {}
>f2 : ({"show": showRename}: Show) => void
>f2 : ({ "show": showRename }: Show) => void
>showRename : ((x: number) => string) | ((v: number) => number)
>v => v : (v: number) => number
>v : number
@@ -24,7 +24,7 @@ function f2({ "show": showRename = v => v }: Show) {}
>Show : Show
function f3({ ["show"]: showRename = v => v }: Show) {}
>f3 : ({["show"]: showRename}: Show) => void
>f3 : ({ ["show"]: showRename }: Show) => void
>"show" : "show"
>showRename : ((x: number) => string) | ((v: number) => number)
>v => v : (v: number) => number
@@ -40,7 +40,7 @@ interface Nested {
>Show : Show
}
function ff({ nested: nestedRename = { show: v => v } }: Nested) {}
>ff : ({nested: nestedRename}: Nested) => void
>ff : ({ nested: nestedRename }: Nested) => void
>nested : any
>nestedRename : Show | { show: (v: number) => number; }
>{ show: v => v } : { show: (v: number) => number; }
@@ -79,7 +79,7 @@ interface Tuples {
>prop : [string, number]
}
function g({ prop = [101, 1234] }: Tuples) {}
>g : ({prop}: Tuples) => void
>g : ({ prop }: Tuples) => void
>prop : [string, number] | [number, number]
>[101, 1234] : [number, number]
>101 : 101
@@ -93,7 +93,7 @@ interface StringUnion {
>prop : "foo" | "bar"
}
function h({ prop = "baz" }: StringUnion) {}
>h : ({prop}: StringUnion) => void
>h : ({ prop }: StringUnion) => void
>prop : "foo" | "bar" | "baz"
>"baz" : "baz"
>StringUnion : StringUnion
@@ -175,8 +175,8 @@
// destructuring parameters (with defaults too!)
(({ q }) => q)({ q : 13 });
>(({ q }) => q)({ q : 13 }) : number
>(({ q }) => q) : ({q}: { q: number; }) => number
>({ q }) => q : ({q}: { q: number; }) => number
>(({ q }) => q) : ({ q }: { q: number; }) => number
>({ q }) => q : ({ q }: { q: number; }) => number
>q : number
>q : number
>{ q : 13 } : { q: number; }
@@ -185,8 +185,8 @@
(({ p = 14 }) => p)({ p : 15 });
>(({ p = 14 }) => p)({ p : 15 }) : number
>(({ p = 14 }) => p) : ({p}: { p: number; }) => number
>({ p = 14 }) => p : ({p}: { p: number; }) => number
>(({ p = 14 }) => p) : ({ p }: { p: number; }) => number
>({ p = 14 }) => p : ({ p }: { p: number; }) => number
>p : number
>14 : 14
>p : number
@@ -196,8 +196,8 @@
(({ r = 17 } = { r: 18 }) => r)({r : 19});
>(({ r = 17 } = { r: 18 }) => r)({r : 19}) : number
>(({ r = 17 } = { r: 18 }) => r) : ({r}?: { r: number; }) => number
>({ r = 17 } = { r: 18 }) => r : ({r}?: { r: number; }) => number
>(({ r = 17 } = { r: 18 }) => r) : ({ r }?: { r: number; }) => number
>({ r = 17 } = { r: 18 }) => r : ({ r }?: { r: number; }) => number
>r : number
>17 : 17
>{ r: 18 } : { r: number; }
@@ -210,8 +210,8 @@
(({ u = 22 } = { u: 23 }) => u)();
>(({ u = 22 } = { u: 23 }) => u)() : number
>(({ u = 22 } = { u: 23 }) => u) : ({u}?: { u?: number; }) => number
>({ u = 22 } = { u: 23 }) => u : ({u}?: { u?: number; }) => number
>(({ u = 22 } = { u: 23 }) => u) : ({ u }?: { u?: number; }) => number
>({ u = 22 } = { u: 23 }) => u : ({ u }?: { u?: number; }) => number
>u : number
>22 : 22
>{ u: 23 } : { u?: number; }
@@ -12,7 +12,7 @@
>map : { <U>(this: [{ x: number; }, { x: number; }, { x: number; }, { x: number; }, { x: number; }], callbackfn: (this: void, value: { x: number; }, index: number, array: { x: number; }[]) => U): [U, U, U, U, U]; <U>(this: [{ x: number; }, { x: number; }, { x: number; }, { x: number; }, { x: number; }], callbackfn: (this: void, value: { x: number; }, index: number, array: { x: number; }[]) => U, thisArg: undefined): [U, U, U, U, U]; <Z, U>(this: [{ x: number; }, { x: number; }, { x: number; }, { x: number; }, { x: number; }], callbackfn: (this: Z, value: { x: number; }, index: number, array: { x: number; }[]) => U, thisArg: Z): [U, U, U, U, U]; <U>(this: [{ x: number; }, { x: number; }, { x: number; }, { x: number; }], callbackfn: (this: void, value: { x: number; }, index: number, array: { x: number; }[]) => U): [U, U, U, U]; <U>(this: [{ x: number; }, { x: number; }, { x: number; }, { x: number; }], callbackfn: (this: void, value: { x: number; }, index: number, array: { x: number; }[]) => U, thisArg: undefined): [U, U, U, U]; <Z, U>(this: [{ x: number; }, { x: number; }, { x: number; }, { x: number; }], callbackfn: (this: Z, value: { x: number; }, index: number, array: { x: number; }[]) => U, thisArg: Z): [U, U, U, U]; <U>(this: [{ x: number; }, { x: number; }, { x: number; }], callbackfn: (this: void, value: { x: number; }, index: number, array: { x: number; }[]) => U): [U, U, U]; <U>(this: [{ x: number; }, { x: number; }, { x: number; }], callbackfn: (this: void, value: { x: number; }, index: number, array: { x: number; }[]) => U, thisArg: undefined): [U, U, U]; <Z, U>(this: [{ x: number; }, { x: number; }, { x: number; }], callbackfn: (this: Z, value: { x: number; }, index: number, array: { x: number; }[]) => U, thisArg: Z): [U, U, U]; <U>(this: [{ x: number; }, { x: number; }], callbackfn: (this: void, value: { x: number; }, index: number, array: { x: number; }[]) => U): [U, U]; <U>(this: [{ x: number; }, { x: number; }], callbackfn: (this: void, value: { x: number; }, index: number, array: { x: number; }[]) => U, thisArg: undefined): [U, U]; <Z, U>(this: [{ x: number; }, { x: number; }], callbackfn: (this: Z, value: { x: number; }, index: number, array: { x: number; }[]) => U, thisArg: Z): [U, U]; <U>(callbackfn: (this: void, value: { x: number; }, index: number, array: { x: number; }[]) => U): U[]; <U>(callbackfn: (this: void, value: { x: number; }, index: number, array: { x: number; }[]) => U, thisArg: undefined): U[]; <Z, U>(callbackfn: (this: Z, value: { x: number; }, index: number, array: { x: number; }[]) => U, thisArg: Z): U[]; }
({ x }) => x
>({ x }) => x : (this: void, {x}: { x: number; }) => number
>({ x }) => x : (this: void, { x }: { x: number; }) => number
>x : number
>x : number
@@ -1,7 +1,7 @@
=== tests/cases/compiler/declarationEmitBindingPatterns.ts ===
const k = ({x: z = 'y'}) => { }
>k : ({x: z}: { x?: string; }) => void
>({x: z = 'y'}) => { } : ({x: z}: { x?: string; }) => void
>k : ({ x: z }: { x?: string; }) => void
>({x: z = 'y'}) => { } : ({ x: z }: { x?: string; }) => void
>x : any
>z : string
>'y' : "y"
@@ -10,7 +10,7 @@ var a;
>a : any
function f({} = a, [] = a, { p: {} = a} = a) {
>f : ({}?: any, []?: any, {p: {}}?: any) => void
>f : ({}?: any, []?: any, { p: {} }?: any) => void
>a : any
>a : any
>p : any
@@ -12,7 +12,7 @@ function far([a, [b], [[c]]]: [number, boolean[], string[][]]): void { }
>c : string
function bar({a1, b1, c1}: { a1: number, b1: boolean, c1: string }): void { }
>bar : ({a1, b1, c1}: { a1: number; b1: boolean; c1: string; }) => void
>bar : ({ a1, b1, c1 }: { a1: number; b1: boolean; c1: string; }) => void
>a1 : number
>b1 : boolean
>c1 : string
@@ -21,7 +21,7 @@ function bar({a1, b1, c1}: { a1: number, b1: boolean, c1: string }): void { }
>c1 : string
function baz({a2, b2: {b1, c1}}: { a2: number, b2: { b1: boolean, c1: string } }): void { }
>baz : ({a2, b2: {b1, c1}}: { a2: number; b2: { b1: boolean; c1: string; }; }) => void
>baz : ({ a2, b2: { b1, c1 } }: { a2: number; b2: { b1: boolean; c1: string; }; }) => void
>a2 : number
>b2 : any
>b1 : boolean
@@ -11,7 +11,7 @@ function foo(...rest: any[]) {
}
function foo2( { x, y, z }?: { x: string; y: number; z: boolean });
>foo2 : ({x, y, z}?: { x: string; y: number; z: boolean; }) => any
>foo2 : ({ x, y, z }?: { x: string; y: number; z: boolean; }) => any
>x : string
>y : number
>z : boolean
@@ -20,7 +20,7 @@ function foo2( { x, y, z }?: { x: string; y: number; z: boolean });
>z : boolean
function foo2(...rest: any[]) {
>foo2 : ({x, y, z}?: { x: string; y: number; z: boolean; }) => any
>foo2 : ({ x, y, z }?: { x: string; y: number; z: boolean; }) => any
>rest : any[]
}
@@ -1,13 +1,13 @@
=== tests/cases/compiler/destructureOptionalParameter.ts ===
declare function f1({ a, b }?: { a: number, b: string }): void;
>f1 : ({a, b}?: { a: number; b: string; } | undefined) => void
>f1 : ({ a, b }?: { a: number; b: string; } | undefined) => void
>a : number
>b : string
>a : number
>b : string
function f2({ a, b }: { a: number, b: number } = { a: 0, b: 0 }) {
>f2 : ({a, b}?: { a: number; b: number; }) => void
>f2 : ({ a, b }?: { a: number; b: number; }) => void
>a : number
>b : number
>a : number
@@ -38,7 +38,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(47,13): error TS2463: A binding pattern parameter cannot be optional in an implementation signature.
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(55,7): error TS2420: Class 'C4' incorrectly implements interface 'F2'.
Types of property 'd4' are incompatible.
Type '({x, y, c}: { x: any; y: any; c: any; }) => void' is not assignable to type '({x, y, z}?: { x: any; y: any; z: any; }) => any'.
Type '({ x, y, c }: { x: any; y: any; c: any; }) => void' is not assignable to type '({ x, y, z }?: { x: any; y: any; z: any; }) => any'.
Types of parameters '__0' and '__0' are incompatible.
Type '{ x: any; y: any; z: any; }' is not assignable to type '{ x: any; y: any; c: any; }'.
Property 'c' is missing in type '{ x: any; y: any; z: any; }'.
@@ -162,7 +162,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(
~~
!!! error TS2420: Class 'C4' incorrectly implements interface 'F2'.
!!! error TS2420: Types of property 'd4' are incompatible.
!!! error TS2420: Type '({x, y, c}: { x: any; y: any; c: any; }) => void' is not assignable to type '({x, y, z}?: { x: any; y: any; z: any; }) => any'.
!!! error TS2420: Type '({ x, y, c }: { x: any; y: any; c: any; }) => void' is not assignable to type '({ x, y, z }?: { x: any; y: any; z: any; }) => any'.
!!! error TS2420: Types of parameters '__0' and '__0' are incompatible.
!!! error TS2420: Type '{ x: any; y: any; z: any; }' is not assignable to type '{ x: any; y: any; c: any; }'.
!!! error TS2420: Property 'c' is missing in type '{ x: any; y: any; z: any; }'.
@@ -10,13 +10,13 @@ interface ISomething {
}
function foo({}, {foo, bar}: ISomething) {}
>foo : ({}: {}, {foo, bar}: ISomething) => void
>foo : ({}: {}, { foo, bar }: ISomething) => void
>foo : string
>bar : string
>ISomething : ISomething
function baz([], {foo, bar}: ISomething) {}
>baz : ([]: any[], {foo, bar}: ISomething) => void
>baz : ([]: any[], { foo, bar }: ISomething) => void
>foo : string
>bar : string
>ISomething : ISomething
@@ -10,13 +10,13 @@ interface ISomething {
}
function foo({}, {foo, bar}: ISomething) {}
>foo : ({}: {}, {foo, bar}: ISomething) => void
>foo : ({}: {}, { foo, bar }: ISomething) => void
>foo : string
>bar : string
>ISomething : ISomething
function baz([], {foo, bar}: ISomething) {}
>baz : ([]: any[], {foo, bar}: ISomething) => void
>baz : ([]: any[], { foo, bar }: ISomething) => void
>foo : string
>bar : string
>ISomething : ISomething
@@ -36,7 +36,7 @@ genericFunction(genericObject, ({greeting}) => {
>genericFunction(genericObject, ({greeting}) => { var s = greeting.toLocaleLowerCase(); // Greeting should be of type string}) : void
>genericFunction : <T>(object: GenericClass<T>, callback: (payload: T) => void) => void
>genericObject : GenericClass<{ greeting: string; }>
>({greeting}) => { var s = greeting.toLocaleLowerCase(); // Greeting should be of type string} : ({greeting}: { greeting: string; }) => void
>({greeting}) => { var s = greeting.toLocaleLowerCase(); // Greeting should be of type string} : ({ greeting }: { greeting: string; }) => void
>greeting : string
var s = greeting.toLocaleLowerCase(); // Greeting should be of type string
@@ -1,13 +1,13 @@
=== tests/cases/conformance/es6/destructuring/destructuringWithLiteralInitializers.ts ===
// (arg: { x: any, y: any }) => void
function f1({ x, y }) { }
>f1 : ({x, y}: { x: any; y: any; }) => void
>f1 : ({ x, y }: { x: any; y: any; }) => void
>x : any
>y : any
f1({ x: 1, y: 1 });
>f1({ x: 1, y: 1 }) : void
>f1 : ({x, y}: { x: any; y: any; }) => void
>f1 : ({ x, y }: { x: any; y: any; }) => void
>{ x: 1, y: 1 } : { x: number; y: number; }
>x : number
>1 : 1
@@ -16,21 +16,21 @@ f1({ x: 1, y: 1 });
// (arg: { x: any, y?: number }) => void
function f2({ x, y = 0 }) { }
>f2 : ({x, y}: { x: any; y?: number; }) => void
>f2 : ({ x, y }: { x: any; y?: number; }) => void
>x : any
>y : number
>0 : 0
f2({ x: 1 });
>f2({ x: 1 }) : void
>f2 : ({x, y}: { x: any; y?: number; }) => void
>f2 : ({ x, y }: { x: any; y?: number; }) => void
>{ x: 1 } : { x: number; }
>x : number
>1 : 1
f2({ x: 1, y: 1 });
>f2({ x: 1, y: 1 }) : void
>f2 : ({x, y}: { x: any; y?: number; }) => void
>f2 : ({ x, y }: { x: any; y?: number; }) => void
>{ x: 1, y: 1 } : { x: number; y: number; }
>x : number
>1 : 1
@@ -39,7 +39,7 @@ f2({ x: 1, y: 1 });
// (arg: { x?: number, y?: number }) => void
function f3({ x = 0, y = 0 }) { }
>f3 : ({x, y}: { x?: number; y?: number; }) => void
>f3 : ({ x, y }: { x?: number; y?: number; }) => void
>x : number
>0 : 0
>y : number
@@ -47,26 +47,26 @@ function f3({ x = 0, y = 0 }) { }
f3({});
>f3({}) : void
>f3 : ({x, y}: { x?: number; y?: number; }) => void
>f3 : ({ x, y }: { x?: number; y?: number; }) => void
>{} : {}
f3({ x: 1 });
>f3({ x: 1 }) : void
>f3 : ({x, y}: { x?: number; y?: number; }) => void
>f3 : ({ x, y }: { x?: number; y?: number; }) => void
>{ x: 1 } : { x: number; }
>x : number
>1 : 1
f3({ y: 1 });
>f3({ y: 1 }) : void
>f3 : ({x, y}: { x?: number; y?: number; }) => void
>f3 : ({ x, y }: { x?: number; y?: number; }) => void
>{ y: 1 } : { y: number; }
>y : number
>1 : 1
f3({ x: 1, y: 1 });
>f3({ x: 1, y: 1 }) : void
>f3 : ({x, y}: { x?: number; y?: number; }) => void
>f3 : ({ x, y }: { x?: number; y?: number; }) => void
>{ x: 1, y: 1 } : { x: number; y: number; }
>x : number
>1 : 1
@@ -75,7 +75,7 @@ f3({ x: 1, y: 1 });
// (arg?: { x: number, y: number }) => void
function f4({ x, y } = { x: 0, y: 0 }) { }
>f4 : ({x, y}?: { x: number; y: number; }) => void
>f4 : ({ x, y }?: { x: number; y: number; }) => void
>x : number
>y : number
>{ x: 0, y: 0 } : { x: number; y: number; }
@@ -86,11 +86,11 @@ function f4({ x, y } = { x: 0, y: 0 }) { }
f4();
>f4() : void
>f4 : ({x, y}?: { x: number; y: number; }) => void
>f4 : ({ x, y }?: { x: number; y: number; }) => void
f4({ x: 1, y: 1 });
>f4({ x: 1, y: 1 }) : void
>f4 : ({x, y}?: { x: number; y: number; }) => void
>f4 : ({ x, y }?: { x: number; y: number; }) => void
>{ x: 1, y: 1 } : { x: number; y: number; }
>x : number
>1 : 1
@@ -99,7 +99,7 @@ f4({ x: 1, y: 1 });
// (arg?: { x: number, y?: number }) => void
function f5({ x, y = 0 } = { x: 0 }) { }
>f5 : ({x, y}?: { x: number; y?: number; }) => void
>f5 : ({ x, y }?: { x: number; y?: number; }) => void
>x : number
>y : number
>0 : 0
@@ -109,18 +109,18 @@ function f5({ x, y = 0 } = { x: 0 }) { }
f5();
>f5() : void
>f5 : ({x, y}?: { x: number; y?: number; }) => void
>f5 : ({ x, y }?: { x: number; y?: number; }) => void
f5({ x: 1 });
>f5({ x: 1 }) : void
>f5 : ({x, y}?: { x: number; y?: number; }) => void
>f5 : ({ x, y }?: { x: number; y?: number; }) => void
>{ x: 1 } : { x: number; }
>x : number
>1 : 1
f5({ x: 1, y: 1 });
>f5({ x: 1, y: 1 }) : void
>f5 : ({x, y}?: { x: number; y?: number; }) => void
>f5 : ({ x, y }?: { x: number; y?: number; }) => void
>{ x: 1, y: 1 } : { x: number; y: number; }
>x : number
>1 : 1
@@ -129,7 +129,7 @@ f5({ x: 1, y: 1 });
// (arg?: { x?: number, y?: number }) => void
function f6({ x = 0, y = 0 } = {}) { }
>f6 : ({x, y}?: { x?: number; y?: number; }) => void
>f6 : ({ x, y }?: { x?: number; y?: number; }) => void
>x : number
>0 : 0
>y : number
@@ -138,30 +138,30 @@ function f6({ x = 0, y = 0 } = {}) { }
f6();
>f6() : void
>f6 : ({x, y}?: { x?: number; y?: number; }) => void
>f6 : ({ x, y }?: { x?: number; y?: number; }) => void
f6({});
>f6({}) : void
>f6 : ({x, y}?: { x?: number; y?: number; }) => void
>f6 : ({ x, y }?: { x?: number; y?: number; }) => void
>{} : {}
f6({ x: 1 });
>f6({ x: 1 }) : void
>f6 : ({x, y}?: { x?: number; y?: number; }) => void
>f6 : ({ x, y }?: { x?: number; y?: number; }) => void
>{ x: 1 } : { x: number; }
>x : number
>1 : 1
f6({ y: 1 });
>f6({ y: 1 }) : void
>f6 : ({x, y}?: { x?: number; y?: number; }) => void
>f6 : ({ x, y }?: { x?: number; y?: number; }) => void
>{ y: 1 } : { y: number; }
>y : number
>1 : 1
f6({ x: 1, y: 1 });
>f6({ x: 1, y: 1 }) : void
>f6 : ({x, y}?: { x?: number; y?: number; }) => void
>f6 : ({ x, y }?: { x?: number; y?: number; }) => void
>{ x: 1, y: 1 } : { x: number; y: number; }
>x : number
>1 : 1
@@ -170,7 +170,7 @@ f6({ x: 1, y: 1 });
// (arg?: { a: { x?: number, y?: number } }) => void
function f7({ a: { x = 0, y = 0 } } = { a: {} }) { }
>f7 : ({a: {x, y}}?: { a: { x?: number; y?: number; }; }) => void
>f7 : ({ a: { x, y } }?: { a: { x?: number; y?: number; }; }) => void
>a : any
>x : number
>0 : 0
@@ -182,18 +182,18 @@ function f7({ a: { x = 0, y = 0 } } = { a: {} }) { }
f7();
>f7() : void
>f7 : ({a: {x, y}}?: { a: { x?: number; y?: number; }; }) => void
>f7 : ({ a: { x, y } }?: { a: { x?: number; y?: number; }; }) => void
f7({ a: {} });
>f7({ a: {} }) : void
>f7 : ({a: {x, y}}?: { a: { x?: number; y?: number; }; }) => void
>f7 : ({ a: { x, y } }?: { a: { x?: number; y?: number; }; }) => void
>{ a: {} } : { a: {}; }
>a : {}
>{} : {}
f7({ a: { x: 1 } });
>f7({ a: { x: 1 } }) : void
>f7 : ({a: {x, y}}?: { a: { x?: number; y?: number; }; }) => void
>f7 : ({ a: { x, y } }?: { a: { x?: number; y?: number; }; }) => void
>{ a: { x: 1 } } : { a: { x: number; }; }
>a : { x: number; }
>{ x: 1 } : { x: number; }
@@ -202,7 +202,7 @@ f7({ a: { x: 1 } });
f7({ a: { y: 1 } });
>f7({ a: { y: 1 } }) : void
>f7 : ({a: {x, y}}?: { a: { x?: number; y?: number; }; }) => void
>f7 : ({ a: { x, y } }?: { a: { x?: number; y?: number; }; }) => void
>{ a: { y: 1 } } : { a: { y: number; }; }
>a : { y: number; }
>{ y: 1 } : { y: number; }
@@ -211,7 +211,7 @@ f7({ a: { y: 1 } });
f7({ a: { x: 1, y: 1 } });
>f7({ a: { x: 1, y: 1 } }) : void
>f7 : ({a: {x, y}}?: { a: { x?: number; y?: number; }; }) => void
>f7 : ({ a: { x, y } }?: { a: { x?: number; y?: number; }; }) => void
>{ a: { x: 1, y: 1 } } : { a: { x: number; y: number; }; }
>a : { x: number; y: number; }
>{ x: 1, y: 1 } : { x: number; y: number; }
@@ -70,25 +70,25 @@ var p5 = ([a = 1]) => { };
>1 : 1
var p6 = ({ a }) => { };
>p6 : ({a}: { a: any; }) => void
>({ a }) => { } : ({a}: { a: any; }) => void
>p6 : ({ a }: { a: any; }) => void
>({ a }) => { } : ({ a }: { a: any; }) => void
>a : any
var p7 = ({ a: { b } }) => { };
>p7 : ({a: {b}}: { a: { b: any; }; }) => void
>({ a: { b } }) => { } : ({a: {b}}: { a: { b: any; }; }) => void
>p7 : ({ a: { b } }: { a: { b: any; }; }) => void
>({ a: { b } }) => { } : ({ a: { b } }: { a: { b: any; }; }) => void
>a : any
>b : any
var p8 = ({ a = 1 }) => { };
>p8 : ({a}: { a?: number; }) => void
>({ a = 1 }) => { } : ({a}: { a?: number; }) => void
>p8 : ({ a }: { a?: number; }) => void
>({ a = 1 }) => { } : ({ a }: { a?: number; }) => void
>a : number
>1 : 1
var p9 = ({ a: { b = 1 } = { b: 1 } }) => { };
>p9 : ({a: {b}}: { a?: { b?: number; }; }) => void
>({ a: { b = 1 } = { b: 1 } }) => { } : ({a: {b}}: { a?: { b?: number; }; }) => void
>p9 : ({ a: { b } }: { a?: { b?: number; }; }) => void
>({ a: { b = 1 } = { b: 1 } }) => { } : ({ a: { b } }: { a?: { b?: number; }; }) => void
>a : any
>b : number
>1 : 1
@@ -97,8 +97,8 @@ var p9 = ({ a: { b = 1 } = { b: 1 } }) => { };
>1 : 1
var p10 = ([{ value, done }]) => { };
>p10 : ([{value, done}]: [{ value: any; done: any; }]) => void
>([{ value, done }]) => { } : ([{value, done}]: [{ value: any; done: any; }]) => void
>p10 : ([{ value, done }]: [{ value: any; done: any; }]) => void
>([{ value, done }]) => { } : ([{ value, done }]: [{ value: any; done: any; }]) => void
>value : any
>done : any
@@ -61,7 +61,7 @@
}
function f({} = a, [] = a, { p: {} = a} = a) {
>f : ({}?: any, []?: any, {p: {}}?: any) => ({}?: any, []?: any, {p: {}}?: any) => any
>f : ({}?: any, []?: any, { p: {} }?: any) => ({}?: any, []?: any, { p: {} }?: any) => any
>a : any
>a : any
>p : any
@@ -69,7 +69,7 @@
>a : any
return ({} = a, [] = a, { p: {} = a } = a) => a;
>({} = a, [] = a, { p: {} = a } = a) => a : ({}?: any, []?: any, {p: {}}?: any) => any
>({} = a, [] = a, { p: {} = a } = a) => a : ({}?: any, []?: any, { p: {} }?: any) => any
>a : any
>a : any
>p : any
@@ -61,7 +61,7 @@
}
function f({} = a, [] = a, { p: {} = a} = a) {
>f : ({}?: any, []?: any, {p: {}}?: any) => ({}?: any, []?: any, {p: {}}?: any) => any
>f : ({}?: any, []?: any, { p: {} }?: any) => ({}?: any, []?: any, { p: {} }?: any) => any
>a : any
>a : any
>p : any
@@ -69,7 +69,7 @@
>a : any
return ({} = a, [] = a, { p: {} = a } = a) => a;
>({} = a, [] = a, { p: {} = a } = a) => a : ({}?: any, []?: any, {p: {}}?: any) => any
>({} = a, [] = a, { p: {} = a } = a) => a : ({}?: any, []?: any, { p: {} }?: any) => any
>a : any
>a : any
>p : any
@@ -61,7 +61,7 @@
}
function f({} = a, [] = a, { p: {} = a} = a) {
>f : ({}?: any, []?: any, {p: {}}?: any) => ({}?: any, []?: any, {p: {}}?: any) => any
>f : ({}?: any, []?: any, { p: {} }?: any) => ({}?: any, []?: any, { p: {} }?: any) => any
>a : any
>a : any
>p : any
@@ -69,7 +69,7 @@
>a : any
return ({} = a, [] = a, { p: {} = a } = a) => a;
>({} = a, [] = a, { p: {} = a } = a) => a : ({}?: any, []?: any, {p: {}}?: any) => any
>({} = a, [] = a, { p: {} = a } = a) => a : ({}?: any, []?: any, { p: {} }?: any) => any
>a : any
>a : any
>p : any
@@ -1,14 +1,29 @@
//// [tests/cases/compiler/exportDefaultAbstractClass.ts] ////
//// [a.ts]
export default abstract class A {}
export default abstract class A { a: number; }
class B extends A {}
new B().a.toExponential();
//// [b.ts]
import A from './a'
import A from './a';
class C extends A {}
new C().a.toExponential();
//// [a.js]
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
exports.__esModule = true;
var A = (function () {
function A() {
@@ -16,6 +31,33 @@ var A = (function () {
return A;
}());
exports["default"] = A;
var B = (function (_super) {
__extends(B, _super);
function B() {
return _super !== null && _super.apply(this, arguments) || this;
}
return B;
}(A));
new B().a.toExponential();
//// [b.js]
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
exports.__esModule = true;
var a_1 = require("./a");
var C = (function (_super) {
__extends(C, _super);
function C() {
return _super !== null && _super.apply(this, arguments) || this;
}
return C;
}(a_1["default"]));
new C().a.toExponential();
@@ -1,8 +1,31 @@
=== tests/cases/compiler/a.ts ===
export default abstract class A {}
export default abstract class A { a: number; }
>A : Symbol(A, Decl(a.ts, 0, 0))
>a : Symbol(A.a, Decl(a.ts, 0, 33))
class B extends A {}
>B : Symbol(B, Decl(a.ts, 0, 46))
>A : Symbol(A, Decl(a.ts, 0, 0))
new B().a.toExponential();
>new B().a.toExponential : Symbol(Number.toExponential, Decl(lib.d.ts, --, --))
>new B().a : Symbol(A.a, Decl(a.ts, 0, 33))
>B : Symbol(B, Decl(a.ts, 0, 46))
>a : Symbol(A.a, Decl(a.ts, 0, 33))
>toExponential : Symbol(Number.toExponential, Decl(lib.d.ts, --, --))
=== tests/cases/compiler/b.ts ===
import A from './a'
import A from './a';
>A : Symbol(A, Decl(b.ts, 0, 6))
class C extends A {}
>C : Symbol(C, Decl(b.ts, 0, 20))
>A : Symbol(A, Decl(b.ts, 0, 6))
new C().a.toExponential();
>new C().a.toExponential : Symbol(Number.toExponential, Decl(lib.d.ts, --, --))
>new C().a : Symbol(A.a, Decl(a.ts, 0, 33))
>C : Symbol(C, Decl(b.ts, 0, 20))
>a : Symbol(A.a, Decl(a.ts, 0, 33))
>toExponential : Symbol(Number.toExponential, Decl(lib.d.ts, --, --))

Some files were not shown because too many files have changed in this diff Show More