Merge branch 'master' into typeToStringViaTypeNode
This commit is contained in:
commit
11019e4a4a
82 changed files with 2552 additions and 371 deletions
10
Gulpfile.ts
10
Gulpfile.ts
|
@ -935,7 +935,7 @@ gulp.task(loggedIOJsPath, /*help*/ false, [], (done) => {
|
|||
const temp = path.join(builtLocalDirectory, "temp");
|
||||
mkdirP(temp, (err) => {
|
||||
if (err) { console.error(err); done(err); process.exit(1); }
|
||||
exec(host, [LKGCompiler, "--types --outdir", temp, loggedIOpath], () => {
|
||||
exec(host, [LKGCompiler, "--types", "--target es5", "--lib es5", "--outdir", temp, loggedIOpath], () => {
|
||||
fs.renameSync(path.join(temp, "/harness/loggedIO.js"), loggedIOJsPath);
|
||||
del(temp).then(() => done(), done);
|
||||
}, done);
|
||||
|
@ -946,7 +946,13 @@ const instrumenterPath = path.join(harnessDirectory, "instrumenter.ts");
|
|||
const instrumenterJsPath = path.join(builtLocalDirectory, "instrumenter.js");
|
||||
gulp.task(instrumenterJsPath, /*help*/ false, [servicesFile], () => {
|
||||
const settings: tsc.Settings = getCompilerSettings({
|
||||
outFile: instrumenterJsPath
|
||||
outFile: instrumenterJsPath,
|
||||
target: "es5",
|
||||
lib: [
|
||||
"es6",
|
||||
"dom",
|
||||
"scripthost"
|
||||
]
|
||||
}, /*useBuiltCompiler*/ true);
|
||||
return gulp.src(instrumenterPath)
|
||||
.pipe(newer(instrumenterJsPath))
|
||||
|
|
|
@ -685,10 +685,6 @@ namespace ts {
|
|||
return type.flags & TypeFlags.Object ? (<ObjectType>type).objectFlags : 0;
|
||||
}
|
||||
|
||||
function getCheckFlags(symbol: Symbol): CheckFlags {
|
||||
return symbol.flags & SymbolFlags.Transient ? (<TransientSymbol>symbol).checkFlags : 0;
|
||||
}
|
||||
|
||||
function isGlobalSourceFile(node: Node) {
|
||||
return node.kind === SyntaxKind.SourceFile && !isExternalOrCommonJsModule(<SourceFile>node);
|
||||
}
|
||||
|
@ -1284,7 +1280,7 @@ namespace ts {
|
|||
else if (result.flags & SymbolFlags.Class) {
|
||||
error(errorLocation, Diagnostics.Class_0_used_before_its_declaration, declarationNameToString(getNameOfDeclaration(declaration)));
|
||||
}
|
||||
else if (result.flags & SymbolFlags.Enum) {
|
||||
else if (result.flags & SymbolFlags.RegularEnum) {
|
||||
error(errorLocation, Diagnostics.Enum_0_used_before_its_declaration, declarationNameToString(getNameOfDeclaration(declaration)));
|
||||
}
|
||||
}
|
||||
|
@ -1304,7 +1300,7 @@ namespace ts {
|
|||
return <ImportEqualsDeclaration>node;
|
||||
}
|
||||
|
||||
return findAncestor(node, n => n.kind === SyntaxKind.ImportDeclaration) as ImportDeclaration;
|
||||
return findAncestor(node, isImportDeclaration);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2814,7 +2810,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function symbolToParameterDeclaration(parameterSymbol: Symbol, context: NodeBuilderContext): ParameterDeclaration {
|
||||
const parameterDeclaration = <ParameterDeclaration>getDeclarationOfKind(parameterSymbol, SyntaxKind.Parameter);
|
||||
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 ?
|
||||
|
@ -4193,7 +4189,7 @@ namespace ts {
|
|||
const func = <FunctionLikeDeclaration>declaration.parent;
|
||||
// For a parameter of a set accessor, use the type of the get accessor if one is present
|
||||
if (func.kind === SyntaxKind.SetAccessor && !hasDynamicName(func)) {
|
||||
const getter = <AccessorDeclaration>getDeclarationOfKind(declaration.parent.symbol, SyntaxKind.GetAccessor);
|
||||
const getter = getDeclarationOfKind<AccessorDeclaration>(declaration.parent.symbol, SyntaxKind.GetAccessor);
|
||||
if (getter) {
|
||||
const getterSignature = getSignatureFromDeclaration(getter);
|
||||
const thisParameter = getAccessorThisParameter(func as AccessorDeclaration);
|
||||
|
@ -4482,8 +4478,8 @@ namespace ts {
|
|||
function getTypeOfAccessors(symbol: Symbol): Type {
|
||||
const links = getSymbolLinks(symbol);
|
||||
if (!links.type) {
|
||||
const getter = <AccessorDeclaration>getDeclarationOfKind(symbol, SyntaxKind.GetAccessor);
|
||||
const setter = <AccessorDeclaration>getDeclarationOfKind(symbol, SyntaxKind.SetAccessor);
|
||||
const getter = getDeclarationOfKind<AccessorDeclaration>(symbol, SyntaxKind.GetAccessor);
|
||||
const setter = getDeclarationOfKind<AccessorDeclaration>(symbol, SyntaxKind.SetAccessor);
|
||||
|
||||
if (getter && getter.flags & NodeFlags.JavaScriptFile) {
|
||||
const jsDocType = getTypeForDeclarationFromJSDocComment(getter);
|
||||
|
@ -4532,7 +4528,7 @@ namespace ts {
|
|||
if (!popTypeResolution()) {
|
||||
type = anyType;
|
||||
if (noImplicitAny) {
|
||||
const getter = <AccessorDeclaration>getDeclarationOfKind(symbol, SyntaxKind.GetAccessor);
|
||||
const getter = getDeclarationOfKind<AccessorDeclaration>(symbol, SyntaxKind.GetAccessor);
|
||||
error(getter, Diagnostics._0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions, symbolToString(symbol));
|
||||
}
|
||||
}
|
||||
|
@ -5009,7 +5005,7 @@ namespace ts {
|
|||
return unknownType;
|
||||
}
|
||||
|
||||
let declaration: JSDocTypedefTag | TypeAliasDeclaration = <JSDocTypedefTag>getDeclarationOfKind(symbol, SyntaxKind.JSDocTypedefTag);
|
||||
let declaration: JSDocTypedefTag | TypeAliasDeclaration = getDeclarationOfKind<JSDocTypedefTag>(symbol, SyntaxKind.JSDocTypedefTag);
|
||||
let type: Type;
|
||||
if (declaration) {
|
||||
if (declaration.jsDocTypeLiteral) {
|
||||
|
@ -5020,7 +5016,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
else {
|
||||
declaration = <TypeAliasDeclaration>getDeclarationOfKind(symbol, SyntaxKind.TypeAliasDeclaration);
|
||||
declaration = getDeclarationOfKind<TypeAliasDeclaration>(symbol, SyntaxKind.TypeAliasDeclaration);
|
||||
type = getTypeFromTypeNode(declaration.type);
|
||||
}
|
||||
|
||||
|
@ -6313,7 +6309,7 @@ namespace ts {
|
|||
!hasDynamicName(declaration) &&
|
||||
(!hasThisParameter || !thisParameter)) {
|
||||
const otherKind = declaration.kind === SyntaxKind.GetAccessor ? SyntaxKind.SetAccessor : SyntaxKind.GetAccessor;
|
||||
const other = <AccessorDeclaration>getDeclarationOfKind(declaration.symbol, otherKind);
|
||||
const other = getDeclarationOfKind<AccessorDeclaration>(declaration.symbol, otherKind);
|
||||
if (other) {
|
||||
thisParameter = getAnnotatedAccessorThisParameter(other);
|
||||
}
|
||||
|
@ -6356,7 +6352,7 @@ namespace ts {
|
|||
// TypeScript 1.0 spec (April 2014):
|
||||
// If only one accessor includes a type annotation, the other behaves as if it had the same type annotation.
|
||||
if (declaration.kind === SyntaxKind.GetAccessor && !hasDynamicName(declaration)) {
|
||||
const setter = <AccessorDeclaration>getDeclarationOfKind(declaration.symbol, SyntaxKind.SetAccessor);
|
||||
const setter = getDeclarationOfKind<AccessorDeclaration>(declaration.symbol, SyntaxKind.SetAccessor);
|
||||
return getAnnotatedAccessorType(setter);
|
||||
}
|
||||
|
||||
|
@ -6569,7 +6565,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function getConstraintDeclaration(type: TypeParameter) {
|
||||
return (<TypeParameterDeclaration>getDeclarationOfKind(type.symbol, SyntaxKind.TypeParameter)).constraint;
|
||||
return getDeclarationOfKind<TypeParameterDeclaration>(type.symbol, SyntaxKind.TypeParameter).constraint;
|
||||
}
|
||||
|
||||
function getConstraintFromTypeParameter(typeParameter: TypeParameter): Type {
|
||||
|
@ -10190,22 +10186,11 @@ namespace ts {
|
|||
}
|
||||
|
||||
function inferTypes(typeVariables: TypeVariable[], typeInferences: TypeInferences[], originalSource: Type, originalTarget: Type) {
|
||||
let sourceStack: Type[];
|
||||
let targetStack: Type[];
|
||||
let depth = 0;
|
||||
let symbolStack: Symbol[];
|
||||
let visited: Map<boolean>;
|
||||
let inferiority = 0;
|
||||
const visited = createMap<boolean>();
|
||||
inferFromTypes(originalSource, originalTarget);
|
||||
|
||||
function isInProcess(source: Type, target: Type) {
|
||||
for (let i = 0; i < depth; i++) {
|
||||
if (source === sourceStack[i] && target === targetStack[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function inferFromTypes(source: Type, target: Type) {
|
||||
if (!couldContainTypeVariables(target)) {
|
||||
return;
|
||||
|
@ -10333,26 +10318,29 @@ namespace ts {
|
|||
else {
|
||||
source = getApparentType(source);
|
||||
if (source.flags & TypeFlags.Object) {
|
||||
if (isInProcess(source, target)) {
|
||||
return;
|
||||
}
|
||||
if (isDeeplyNestedType(source, sourceStack, depth) && isDeeplyNestedType(target, targetStack, depth)) {
|
||||
return;
|
||||
}
|
||||
const key = source.id + "," + target.id;
|
||||
if (visited.get(key)) {
|
||||
if (visited && visited.get(key)) {
|
||||
return;
|
||||
}
|
||||
visited.set(key, true);
|
||||
if (depth === 0) {
|
||||
sourceStack = [];
|
||||
targetStack = [];
|
||||
(visited || (visited = createMap<boolean>())).set(key, true);
|
||||
// If we are already processing another target type with the same associated symbol (such as
|
||||
// an instantiation of the same generic type), we do not explore this target as it would yield
|
||||
// no further inferences. We exclude the static side of classes from this check since it shares
|
||||
// its symbol with the instance side which would lead to false positives.
|
||||
const isNonConstructorObject = target.flags & TypeFlags.Object &&
|
||||
!(getObjectFlags(target) & ObjectFlags.Anonymous && target.symbol && target.symbol.flags & SymbolFlags.Class);
|
||||
const symbol = isNonConstructorObject ? target.symbol : undefined;
|
||||
if (symbol) {
|
||||
if (contains(symbolStack, symbol)) {
|
||||
return;
|
||||
}
|
||||
(symbolStack || (symbolStack = [])).push(symbol);
|
||||
inferFromObjectTypes(source, target);
|
||||
symbolStack.pop();
|
||||
}
|
||||
else {
|
||||
inferFromObjectTypes(source, target);
|
||||
}
|
||||
sourceStack[depth] = source;
|
||||
targetStack[depth] = target;
|
||||
depth++;
|
||||
inferFromObjectTypes(source, target);
|
||||
depth--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12660,7 +12648,7 @@ namespace ts {
|
|||
// corresponding set accessor has a type annotation, return statements in the function are contextually typed
|
||||
if (functionDecl.type ||
|
||||
functionDecl.kind === SyntaxKind.Constructor ||
|
||||
functionDecl.kind === SyntaxKind.GetAccessor && getSetAccessorTypeAnnotationNode(<SetAccessorDeclaration>getDeclarationOfKind(functionDecl.symbol, SyntaxKind.SetAccessor))) {
|
||||
functionDecl.kind === SyntaxKind.GetAccessor && getSetAccessorTypeAnnotationNode(getDeclarationOfKind<SetAccessorDeclaration>(functionDecl.symbol, SyntaxKind.SetAccessor))) {
|
||||
return getReturnTypeOfSignature(getSignatureFromDeclaration(functionDecl));
|
||||
}
|
||||
|
||||
|
@ -13407,6 +13395,7 @@ namespace ts {
|
|||
let spread: Type = emptyObjectType;
|
||||
let attributesArray: Symbol[] = [];
|
||||
let hasSpreadAnyType = false;
|
||||
let typeToIntersect: Type;
|
||||
let explicitlySpecifyChildrenAttribute = false;
|
||||
const jsxChildrenPropertyName = getJsxElementChildrenPropertyname();
|
||||
|
||||
|
@ -13438,11 +13427,16 @@ namespace ts {
|
|||
attributesArray = [];
|
||||
attributesTable = createMap<Symbol>();
|
||||
}
|
||||
const exprType = getApparentType(checkExpression(attributeDecl.expression));
|
||||
const exprType = checkExpression(attributeDecl.expression);
|
||||
if (isTypeAny(exprType)) {
|
||||
hasSpreadAnyType = true;
|
||||
}
|
||||
spread = getSpreadType(spread, exprType);
|
||||
if (isValidSpreadType(exprType)) {
|
||||
spread = getSpreadType(spread, exprType);
|
||||
}
|
||||
else {
|
||||
typeToIntersect = typeToIntersect ? getIntersectionType([typeToIntersect, exprType]) : exprType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13497,7 +13491,13 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
return hasSpreadAnyType ? anyType : createJsxAttributesType(attributes.symbol, attributesTable);
|
||||
if (hasSpreadAnyType) {
|
||||
return anyType;
|
||||
}
|
||||
|
||||
const attributeType = createJsxAttributesType(attributes.symbol, attributesTable);
|
||||
return typeToIntersect && attributesTable.size ? getIntersectionType([typeToIntersect, attributeType]) :
|
||||
typeToIntersect ? typeToIntersect : attributeType;
|
||||
|
||||
/**
|
||||
* Create anonymous type from given attributes symbol table.
|
||||
|
@ -13663,6 +13663,20 @@ namespace ts {
|
|||
return _jsxElementChildrenPropertyName;
|
||||
}
|
||||
|
||||
function getApparentTypeOfJsxPropsType(propsType: Type): Type {
|
||||
if (!propsType) {
|
||||
return undefined;
|
||||
}
|
||||
if (propsType.flags & TypeFlags.Intersection) {
|
||||
const propsApparentType: Type[] = [];
|
||||
for (const t of (<UnionOrIntersectionType>propsType).types) {
|
||||
propsApparentType.push(getApparentType(t));
|
||||
}
|
||||
return getIntersectionType(propsApparentType);
|
||||
}
|
||||
return getApparentType(propsType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get JSX attributes type by trying to resolve openingLikeElement as a stateless function component.
|
||||
* Return only attributes type of successfully resolved call signature.
|
||||
|
@ -13683,6 +13697,7 @@ namespace ts {
|
|||
if (callSignature !== unknownSignature) {
|
||||
const callReturnType = callSignature && getReturnTypeOfSignature(callSignature);
|
||||
let paramType = callReturnType && (callSignature.parameters.length === 0 ? emptyObjectType : getTypeOfSymbol(callSignature.parameters[0]));
|
||||
paramType = getApparentTypeOfJsxPropsType(paramType);
|
||||
if (callReturnType && isTypeAssignableTo(callReturnType, jsxStatelessElementType)) {
|
||||
// Intersect in JSX.IntrinsicAttributes if it exists
|
||||
const intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes);
|
||||
|
@ -13720,7 +13735,8 @@ namespace ts {
|
|||
let allMatchingAttributesType: Type;
|
||||
for (const candidate of candidatesOutArray) {
|
||||
const callReturnType = getReturnTypeOfSignature(candidate);
|
||||
const paramType = callReturnType && (candidate.parameters.length === 0 ? emptyObjectType : getTypeOfSymbol(candidate.parameters[0]));
|
||||
let paramType = callReturnType && (candidate.parameters.length === 0 ? emptyObjectType : getTypeOfSymbol(candidate.parameters[0]));
|
||||
paramType = getApparentTypeOfJsxPropsType(paramType);
|
||||
if (callReturnType && isTypeAssignableTo(callReturnType, jsxStatelessElementType)) {
|
||||
let shouldBeCandidate = true;
|
||||
for (const attribute of openingLikeElement.attributes.properties) {
|
||||
|
@ -14120,25 +14136,6 @@ namespace ts {
|
|||
return s.valueDeclaration ? s.valueDeclaration.kind : SyntaxKind.PropertyDeclaration;
|
||||
}
|
||||
|
||||
function getDeclarationModifierFlagsFromSymbol(s: Symbol): ModifierFlags {
|
||||
if (s.valueDeclaration) {
|
||||
const flags = getCombinedModifierFlags(s.valueDeclaration);
|
||||
return s.parent && s.parent.flags & SymbolFlags.Class ? flags : flags & ~ModifierFlags.AccessibilityModifier;
|
||||
}
|
||||
if (getCheckFlags(s) & CheckFlags.Synthetic) {
|
||||
const checkFlags = (<TransientSymbol>s).checkFlags;
|
||||
const accessModifier = checkFlags & CheckFlags.ContainsPrivate ? ModifierFlags.Private :
|
||||
checkFlags & CheckFlags.ContainsPublic ? ModifierFlags.Public :
|
||||
ModifierFlags.Protected;
|
||||
const staticModifier = checkFlags & CheckFlags.ContainsStatic ? ModifierFlags.Static : 0;
|
||||
return accessModifier | staticModifier;
|
||||
}
|
||||
if (s.flags & SymbolFlags.Prototype) {
|
||||
return ModifierFlags.Public | ModifierFlags.Static;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function getDeclarationNodeFlagsFromSymbol(s: Symbol): NodeFlags {
|
||||
return s.valueDeclaration ? getCombinedNodeFlags(s.valueDeclaration) : 0;
|
||||
}
|
||||
|
@ -18194,7 +18191,7 @@ namespace ts {
|
|||
// TypeScript 1.0 spec (April 2014): 8.4.3
|
||||
// Accessors for the same member name must specify the same accessibility.
|
||||
const otherKind = node.kind === SyntaxKind.GetAccessor ? SyntaxKind.SetAccessor : SyntaxKind.GetAccessor;
|
||||
const otherAccessor = <AccessorDeclaration>getDeclarationOfKind(node.symbol, otherKind);
|
||||
const otherAccessor = getDeclarationOfKind<AccessorDeclaration>(node.symbol, otherKind);
|
||||
if (otherAccessor) {
|
||||
if ((getModifierFlags(node) & ModifierFlags.AccessibilityModifier) !== (getModifierFlags(otherAccessor) & ModifierFlags.AccessibilityModifier)) {
|
||||
error(node.name, Diagnostics.Getter_and_setter_accessors_do_not_agree_in_visibility);
|
||||
|
@ -20326,7 +20323,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function isGetAccessorWithAnnotatedSetAccessor(node: FunctionLikeDeclaration) {
|
||||
return !!(node.kind === SyntaxKind.GetAccessor && getSetAccessorTypeAnnotationNode(<SetAccessorDeclaration>getDeclarationOfKind(node.symbol, SyntaxKind.SetAccessor)));
|
||||
return !!(node.kind === SyntaxKind.GetAccessor && getSetAccessorTypeAnnotationNode(getDeclarationOfKind<SetAccessorDeclaration>(node.symbol, SyntaxKind.SetAccessor)));
|
||||
}
|
||||
|
||||
function isUnwrappedReturnTypeVoidOrAny(func: FunctionLikeDeclaration, returnType: Type): boolean {
|
||||
|
@ -21014,7 +21011,7 @@ namespace ts {
|
|||
checkTypeParameterListsIdentical(symbol);
|
||||
|
||||
// Only check this symbol once
|
||||
const firstInterfaceDecl = <InterfaceDeclaration>getDeclarationOfKind(symbol, SyntaxKind.InterfaceDeclaration);
|
||||
const firstInterfaceDecl = getDeclarationOfKind<InterfaceDeclaration>(symbol, SyntaxKind.InterfaceDeclaration);
|
||||
if (node === firstInterfaceDecl) {
|
||||
const type = <InterfaceType>getDeclaredTypeOfSymbol(symbol);
|
||||
const typeWithThis = getTypeWithThisArgument(type);
|
||||
|
@ -22730,7 +22727,7 @@ namespace ts {
|
|||
const symbolIsUmdExport = symbolFile !== referenceFile;
|
||||
return symbolIsUmdExport ? undefined : symbolFile;
|
||||
}
|
||||
return findAncestor(node.parent, n => isModuleOrEnumDeclaration(n) && getSymbolOfNode(n) === parentSymbol) as ModuleDeclaration | EnumDeclaration;
|
||||
return findAncestor(node.parent, (n): n is ModuleDeclaration | EnumDeclaration => isModuleOrEnumDeclaration(n) && getSymbolOfNode(n) === parentSymbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -230,6 +230,8 @@ namespace ts {
|
|||
* If no such value is found, it applies the callback until the parent pointer is undefined or the callback returns "quit"
|
||||
* At that point findAncestor returns undefined.
|
||||
*/
|
||||
export function findAncestor<T extends Node>(node: Node, callback: (element: Node) => element is T): T | undefined;
|
||||
export function findAncestor(node: Node, callback: (element: Node) => boolean | "quit"): Node | undefined;
|
||||
export function findAncestor(node: Node, callback: (element: Node) => boolean | "quit"): Node {
|
||||
while (node) {
|
||||
const result = callback(node);
|
||||
|
@ -490,6 +492,35 @@ namespace ts {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps an array. If the mapped value is an array, it is spread into the result.
|
||||
* Avoids allocation if all elements map to themselves.
|
||||
*
|
||||
* @param array The array to map.
|
||||
* @param mapfn The callback used to map the result into one or more values.
|
||||
*/
|
||||
export function sameFlatMap<T>(array: T[], mapfn: (x: T, i: number) => T | T[]): T[] {
|
||||
let result: T[];
|
||||
if (array) {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
const item = array[i];
|
||||
const mapped = mapfn(item, i);
|
||||
if (result || item !== mapped || isArray(mapped)) {
|
||||
if (!result) {
|
||||
result = array.slice(0, i);
|
||||
}
|
||||
if (isArray(mapped)) {
|
||||
addRange(result, mapped);
|
||||
}
|
||||
else {
|
||||
result.push(mapped);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result || array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the first matching span of elements and returns a tuple of the first span
|
||||
* and the remaining elements.
|
||||
|
|
|
@ -740,6 +740,9 @@ namespace ts {
|
|||
// Transformation nodes
|
||||
case SyntaxKind.PartiallyEmittedExpression:
|
||||
return emitPartiallyEmittedExpression(<PartiallyEmittedExpression>node);
|
||||
|
||||
case SyntaxKind.CommaListExpression:
|
||||
return emitCommaList(<CommaListExpression>node);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2124,6 +2127,10 @@ namespace ts {
|
|||
emitExpression(node.expression);
|
||||
}
|
||||
|
||||
function emitCommaList(node: CommaListExpression) {
|
||||
emitExpressionList(node, node.elements, ListFormat.CommaListElements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits any prologue directives at the start of a Statement list, returning the
|
||||
* number of prologue directives written to the output.
|
||||
|
@ -2979,6 +2986,7 @@ namespace ts {
|
|||
ArrayBindingPatternElements = SingleLine | AllowTrailingComma | CommaDelimited | SpaceBetweenSiblings,
|
||||
ObjectLiteralExpressionProperties = PreserveLines | CommaDelimited | SpaceBetweenSiblings | SpaceBetweenBraces | Indented | Braces,
|
||||
ArrayLiteralExpressionElements = PreserveLines | CommaDelimited | SpaceBetweenSiblings | AllowTrailingComma | Indented | SquareBrackets,
|
||||
CommaListElements = CommaDelimited | SpaceBetweenSiblings | SingleLine,
|
||||
CallExpressionArguments = CommaDelimited | SpaceBetweenSiblings | SingleLine | Parenthesis,
|
||||
NewExpressionArguments = CommaDelimited | SpaceBetweenSiblings | SingleLine | Parenthesis | OptionalIfUndefined,
|
||||
TemplateExpressionSpans = SingleLine | NoInterveningComments,
|
||||
|
|
|
@ -2091,6 +2091,30 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
function flattenCommaElements(node: Expression): Expression | Expression[] {
|
||||
if (nodeIsSynthesized(node) && !isParseTreeNode(node) && !node.original && !node.emitNode && !node.id) {
|
||||
if (node.kind === SyntaxKind.CommaListExpression) {
|
||||
return (<CommaListExpression>node).elements;
|
||||
}
|
||||
if (isBinaryExpression(node) && node.operatorToken.kind === SyntaxKind.CommaToken) {
|
||||
return [node.left, node.right];
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
export function createCommaList(elements: Expression[]) {
|
||||
const node = <CommaListExpression>createSynthesizedNode(SyntaxKind.CommaListExpression);
|
||||
node.elements = createNodeArray(sameFlatMap(elements, flattenCommaElements));
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateCommaList(node: CommaListExpression, elements: Expression[]) {
|
||||
return node.elements !== elements
|
||||
? updateNode(createCommaList(elements), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createBundle(sourceFiles: SourceFile[]) {
|
||||
const node = <Bundle>createNode(SyntaxKind.Bundle);
|
||||
node.sourceFiles = sourceFiles;
|
||||
|
@ -2898,7 +2922,11 @@ namespace ts {
|
|||
}
|
||||
|
||||
export function inlineExpressions(expressions: Expression[]) {
|
||||
return reduceLeft(expressions, createComma);
|
||||
// Avoid deeply nested comma expressions as traversing them during emit can result in "Maximum call
|
||||
// stack size exceeded" errors.
|
||||
return expressions.length > 10
|
||||
? createCommaList(expressions)
|
||||
: reduceLeft(expressions, createComma);
|
||||
}
|
||||
|
||||
export function createExpressionFromEntityName(node: EntityName | Expression): Expression {
|
||||
|
|
|
@ -47,13 +47,11 @@ namespace ts {
|
|||
return resolved.path;
|
||||
}
|
||||
|
||||
/** Adds `isExernalLibraryImport` to a Resolved to get a ResolvedModule. */
|
||||
function resolvedModuleFromResolved({ path, extension }: Resolved, isExternalLibraryImport: boolean): ResolvedModuleFull {
|
||||
return { resolvedFileName: path, extension, isExternalLibraryImport };
|
||||
}
|
||||
|
||||
function createResolvedModuleWithFailedLookupLocations(resolved: Resolved | undefined, isExternalLibraryImport: boolean, failedLookupLocations: string[]): ResolvedModuleWithFailedLookupLocations {
|
||||
return { resolvedModule: resolved && resolvedModuleFromResolved(resolved, isExternalLibraryImport), failedLookupLocations };
|
||||
return {
|
||||
resolvedModule: resolved && { resolvedFileName: resolved.path, extension: resolved.extension, isExternalLibraryImport },
|
||||
failedLookupLocations
|
||||
};
|
||||
}
|
||||
|
||||
export function moduleHasNonRelativeName(moduleName: string): boolean {
|
||||
|
|
|
@ -23,19 +23,19 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function visitNode<T>(cbNode: (node: Node) => T, node: Node): T {
|
||||
function visitNode<T>(cbNode: (node: Node) => T, node: Node): T | undefined {
|
||||
if (node) {
|
||||
return cbNode(node);
|
||||
}
|
||||
}
|
||||
|
||||
function visitNodeArray<T>(cbNodes: (nodes: Node[]) => T, nodes: Node[]) {
|
||||
function visitNodeArray<T>(cbNodes: (nodes: Node[]) => T, nodes: Node[]): T | undefined {
|
||||
if (nodes) {
|
||||
return cbNodes(nodes);
|
||||
}
|
||||
}
|
||||
|
||||
function visitEachNode<T>(cbNode: (node: Node) => T, nodes: Node[]) {
|
||||
function visitEachNode<T>(cbNode: (node: Node) => T, nodes: Node[]): T | undefined {
|
||||
if (nodes) {
|
||||
for (const node of nodes) {
|
||||
const result = cbNode(node);
|
||||
|
@ -50,7 +50,7 @@ namespace ts {
|
|||
// stored in properties. If a 'cbNodes' callback is specified, it is invoked for embedded arrays; otherwise,
|
||||
// embedded arrays are flattened and the 'cbNode' callback is invoked for each element. If a callback returns
|
||||
// a truthy value, iteration stops and that value is returned. Otherwise, undefined is returned.
|
||||
export function forEachChild<T>(node: Node, cbNode: (node: Node) => T, cbNodeArray?: (nodes: Node[]) => T): T {
|
||||
export function forEachChild<T>(node: Node, cbNode: (node: Node) => T, cbNodeArray?: (nodes: Node[]) => T): T | undefined {
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
@ -362,6 +362,8 @@ namespace ts {
|
|||
return visitNode(cbNode, (<ExternalModuleReference>node).expression);
|
||||
case SyntaxKind.MissingDeclaration:
|
||||
return visitNodes(cbNodes, node.decorators);
|
||||
case SyntaxKind.CommaListExpression:
|
||||
return visitNodes(cbNodes, (<CommaListExpression>node).elements);
|
||||
|
||||
case SyntaxKind.JsxElement:
|
||||
return visitNode(cbNode, (<JsxElement>node).openingElement) ||
|
||||
|
|
|
@ -241,6 +241,101 @@ namespace ts {
|
|||
return output;
|
||||
}
|
||||
|
||||
const redForegroundEscapeSequence = "\u001b[91m";
|
||||
const yellowForegroundEscapeSequence = "\u001b[93m";
|
||||
const blueForegroundEscapeSequence = "\u001b[93m";
|
||||
const gutterStyleSequence = "\u001b[100;30m";
|
||||
const gutterSeparator = " ";
|
||||
const resetEscapeSequence = "\u001b[0m";
|
||||
const ellipsis = "...";
|
||||
function getCategoryFormat(category: DiagnosticCategory): string {
|
||||
switch (category) {
|
||||
case DiagnosticCategory.Warning: return yellowForegroundEscapeSequence;
|
||||
case DiagnosticCategory.Error: return redForegroundEscapeSequence;
|
||||
case DiagnosticCategory.Message: return blueForegroundEscapeSequence;
|
||||
}
|
||||
}
|
||||
|
||||
function formatAndReset(text: string, formatStyle: string) {
|
||||
return formatStyle + text + resetEscapeSequence;
|
||||
}
|
||||
|
||||
function padLeft(s: string, length: number) {
|
||||
while (s.length < length) {
|
||||
s = " " + s;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
export function formatDiagnosticsWithColorAndContext(diagnostics: Diagnostic[], host: FormatDiagnosticsHost): string {
|
||||
let output = "";
|
||||
for (const diagnostic of diagnostics) {
|
||||
if (diagnostic.file) {
|
||||
const { start, length, file } = diagnostic;
|
||||
const { line: firstLine, character: firstLineChar } = getLineAndCharacterOfPosition(file, start);
|
||||
const { line: lastLine, character: lastLineChar } = getLineAndCharacterOfPosition(file, start + length);
|
||||
const lastLineInFile = getLineAndCharacterOfPosition(file, file.text.length).line;
|
||||
const relativeFileName = host ? convertToRelativePath(file.fileName, host.getCurrentDirectory(), fileName => host.getCanonicalFileName(fileName)) : file.fileName;
|
||||
|
||||
const hasMoreThanFiveLines = (lastLine - firstLine) >= 4;
|
||||
let gutterWidth = (lastLine + 1 + "").length;
|
||||
if (hasMoreThanFiveLines) {
|
||||
gutterWidth = Math.max(ellipsis.length, gutterWidth);
|
||||
}
|
||||
|
||||
output += sys.newLine;
|
||||
for (let i = firstLine; i <= lastLine; i++) {
|
||||
// If the error spans over 5 lines, we'll only show the first 2 and last 2 lines,
|
||||
// so we'll skip ahead to the second-to-last line.
|
||||
if (hasMoreThanFiveLines && firstLine + 1 < i && i < lastLine - 1) {
|
||||
output += formatAndReset(padLeft(ellipsis, gutterWidth), gutterStyleSequence) + gutterSeparator + sys.newLine;
|
||||
i = lastLine - 1;
|
||||
}
|
||||
|
||||
const lineStart = getPositionOfLineAndCharacter(file, i, 0);
|
||||
const lineEnd = i < lastLineInFile ? getPositionOfLineAndCharacter(file, i + 1, 0) : file.text.length;
|
||||
let lineContent = file.text.slice(lineStart, lineEnd);
|
||||
lineContent = lineContent.replace(/\s+$/g, ""); // trim from end
|
||||
lineContent = lineContent.replace("\t", " "); // convert tabs to single spaces
|
||||
|
||||
// Output the gutter and the actual contents of the line.
|
||||
output += formatAndReset(padLeft(i + 1 + "", gutterWidth), gutterStyleSequence) + gutterSeparator;
|
||||
output += lineContent + sys.newLine;
|
||||
|
||||
// Output the gutter and the error span for the line using tildes.
|
||||
output += formatAndReset(padLeft("", gutterWidth), gutterStyleSequence) + gutterSeparator;
|
||||
output += redForegroundEscapeSequence;
|
||||
if (i === firstLine) {
|
||||
// If we're on the last line, then limit it to the last character of the last line.
|
||||
// Otherwise, we'll just squiggle the rest of the line, giving 'slice' no end position.
|
||||
const lastCharForLine = i === lastLine ? lastLineChar : undefined;
|
||||
|
||||
output += lineContent.slice(0, firstLineChar).replace(/\S/g, " ");
|
||||
output += lineContent.slice(firstLineChar, lastCharForLine).replace(/./g, "~");
|
||||
}
|
||||
else if (i === lastLine) {
|
||||
output += lineContent.slice(0, lastLineChar).replace(/./g, "~");
|
||||
}
|
||||
else {
|
||||
// Squiggle the entire line.
|
||||
output += lineContent.replace(/./g, "~");
|
||||
}
|
||||
output += resetEscapeSequence;
|
||||
|
||||
output += sys.newLine;
|
||||
}
|
||||
|
||||
output += sys.newLine;
|
||||
output += `${ relativeFileName }(${ firstLine + 1 },${ firstLineChar + 1 }): `;
|
||||
}
|
||||
|
||||
const categoryColor = getCategoryFormat(diagnostic.category);
|
||||
const category = DiagnosticCategory[diagnostic.category].toLowerCase();
|
||||
output += `${ formatAndReset(category, categoryColor) } TS${ diagnostic.code }: ${ flattenDiagnosticMessageText(diagnostic.messageText, sys.newLine) }`;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
export function flattenDiagnosticMessageText(messageText: string | DiagnosticMessageChain, newLine: string): string {
|
||||
if (typeof messageText === "string") {
|
||||
return messageText;
|
||||
|
|
|
@ -712,11 +712,11 @@ namespace ts {
|
|||
return accumulator;
|
||||
}
|
||||
|
||||
export function forEachLeadingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T) {
|
||||
export function forEachLeadingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined {
|
||||
return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ false, cb, state);
|
||||
}
|
||||
|
||||
export function forEachTrailingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T) {
|
||||
export function forEachTrailingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined {
|
||||
return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ true, cb, state);
|
||||
}
|
||||
|
||||
|
@ -746,10 +746,11 @@ namespace ts {
|
|||
}
|
||||
|
||||
/** Optionally, get the shebang */
|
||||
export function getShebang(text: string): string {
|
||||
return shebangTriviaRegex.test(text)
|
||||
? shebangTriviaRegex.exec(text)[0]
|
||||
: undefined;
|
||||
export function getShebang(text: string): string | undefined {
|
||||
const match = shebangTriviaRegex.exec(text);
|
||||
if (match) {
|
||||
return match[0];
|
||||
}
|
||||
}
|
||||
|
||||
export function isIdentifierStart(ch: number, languageVersion: ScriptTarget): boolean {
|
||||
|
|
|
@ -929,8 +929,8 @@ namespace ts {
|
|||
text: `
|
||||
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
|
||||
var i, p;
|
||||
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
|
||||
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
|
||||
};
|
||||
`
|
||||
};
|
||||
|
|
|
@ -60,93 +60,8 @@ namespace ts {
|
|||
sys.write(ts.formatDiagnostics([diagnostic], host));
|
||||
}
|
||||
|
||||
const redForegroundEscapeSequence = "\u001b[91m";
|
||||
const yellowForegroundEscapeSequence = "\u001b[93m";
|
||||
const blueForegroundEscapeSequence = "\u001b[93m";
|
||||
const gutterStyleSequence = "\u001b[100;30m";
|
||||
const gutterSeparator = " ";
|
||||
const resetEscapeSequence = "\u001b[0m";
|
||||
const ellipsis = "...";
|
||||
function getCategoryFormat(category: DiagnosticCategory): string {
|
||||
switch (category) {
|
||||
case DiagnosticCategory.Warning: return yellowForegroundEscapeSequence;
|
||||
case DiagnosticCategory.Error: return redForegroundEscapeSequence;
|
||||
case DiagnosticCategory.Message: return blueForegroundEscapeSequence;
|
||||
}
|
||||
}
|
||||
|
||||
function formatAndReset(text: string, formatStyle: string) {
|
||||
return formatStyle + text + resetEscapeSequence;
|
||||
}
|
||||
|
||||
function reportDiagnosticWithColorAndContext(diagnostic: Diagnostic, host: FormatDiagnosticsHost): void {
|
||||
let output = "";
|
||||
|
||||
if (diagnostic.file) {
|
||||
const { start, length, file } = diagnostic;
|
||||
const { line: firstLine, character: firstLineChar } = getLineAndCharacterOfPosition(file, start);
|
||||
const { line: lastLine, character: lastLineChar } = getLineAndCharacterOfPosition(file, start + length);
|
||||
const lastLineInFile = getLineAndCharacterOfPosition(file, file.text.length).line;
|
||||
const relativeFileName = host ? convertToRelativePath(file.fileName, host.getCurrentDirectory(), fileName => host.getCanonicalFileName(fileName)) : file.fileName;
|
||||
|
||||
const hasMoreThanFiveLines = (lastLine - firstLine) >= 4;
|
||||
let gutterWidth = (lastLine + 1 + "").length;
|
||||
if (hasMoreThanFiveLines) {
|
||||
gutterWidth = Math.max(ellipsis.length, gutterWidth);
|
||||
}
|
||||
|
||||
output += sys.newLine;
|
||||
for (let i = firstLine; i <= lastLine; i++) {
|
||||
// If the error spans over 5 lines, we'll only show the first 2 and last 2 lines,
|
||||
// so we'll skip ahead to the second-to-last line.
|
||||
if (hasMoreThanFiveLines && firstLine + 1 < i && i < lastLine - 1) {
|
||||
output += formatAndReset(padLeft(ellipsis, gutterWidth), gutterStyleSequence) + gutterSeparator + sys.newLine;
|
||||
i = lastLine - 1;
|
||||
}
|
||||
|
||||
const lineStart = getPositionOfLineAndCharacter(file, i, 0);
|
||||
const lineEnd = i < lastLineInFile ? getPositionOfLineAndCharacter(file, i + 1, 0) : file.text.length;
|
||||
let lineContent = file.text.slice(lineStart, lineEnd);
|
||||
lineContent = lineContent.replace(/\s+$/g, ""); // trim from end
|
||||
lineContent = lineContent.replace("\t", " "); // convert tabs to single spaces
|
||||
|
||||
// Output the gutter and the actual contents of the line.
|
||||
output += formatAndReset(padLeft(i + 1 + "", gutterWidth), gutterStyleSequence) + gutterSeparator;
|
||||
output += lineContent + sys.newLine;
|
||||
|
||||
// Output the gutter and the error span for the line using tildes.
|
||||
output += formatAndReset(padLeft("", gutterWidth), gutterStyleSequence) + gutterSeparator;
|
||||
output += redForegroundEscapeSequence;
|
||||
if (i === firstLine) {
|
||||
// If we're on the last line, then limit it to the last character of the last line.
|
||||
// Otherwise, we'll just squiggle the rest of the line, giving 'slice' no end position.
|
||||
const lastCharForLine = i === lastLine ? lastLineChar : undefined;
|
||||
|
||||
output += lineContent.slice(0, firstLineChar).replace(/\S/g, " ");
|
||||
output += lineContent.slice(firstLineChar, lastCharForLine).replace(/./g, "~");
|
||||
}
|
||||
else if (i === lastLine) {
|
||||
output += lineContent.slice(0, lastLineChar).replace(/./g, "~");
|
||||
}
|
||||
else {
|
||||
// Squiggle the entire line.
|
||||
output += lineContent.replace(/./g, "~");
|
||||
}
|
||||
output += resetEscapeSequence;
|
||||
|
||||
output += sys.newLine;
|
||||
}
|
||||
|
||||
output += sys.newLine;
|
||||
output += `${ relativeFileName }(${ firstLine + 1 },${ firstLineChar + 1 }): `;
|
||||
}
|
||||
|
||||
const categoryColor = getCategoryFormat(diagnostic.category);
|
||||
const category = DiagnosticCategory[diagnostic.category].toLowerCase();
|
||||
output += `${ formatAndReset(category, categoryColor) } TS${ diagnostic.code }: ${ flattenDiagnosticMessageText(diagnostic.messageText, sys.newLine) }`;
|
||||
output += sys.newLine + sys.newLine;
|
||||
|
||||
sys.write(output);
|
||||
sys.write(ts.formatDiagnosticsWithColorAndContext([diagnostic], host) + sys.newLine + sys.newLine);
|
||||
}
|
||||
|
||||
function reportWatchDiagnostic(diagnostic: Diagnostic) {
|
||||
|
|
|
@ -389,6 +389,7 @@ namespace ts {
|
|||
// Transformation nodes
|
||||
NotEmittedStatement,
|
||||
PartiallyEmittedExpression,
|
||||
CommaListExpression,
|
||||
MergeDeclarationMarker,
|
||||
EndOfDeclarationMarker,
|
||||
|
||||
|
@ -1604,6 +1605,14 @@ namespace ts {
|
|||
kind: SyntaxKind.EndOfDeclarationMarker;
|
||||
}
|
||||
|
||||
/**
|
||||
* A list of comma-seperated expressions. This node is only created by transformations.
|
||||
*/
|
||||
export interface CommaListExpression extends Expression {
|
||||
kind: SyntaxKind.CommaListExpression;
|
||||
elements: NodeArray<Expression>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the beginning of a merged transformed declaration.
|
||||
*/
|
||||
|
@ -2519,11 +2528,11 @@ namespace ts {
|
|||
indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): IndexSignatureDeclaration;
|
||||
|
||||
getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[];
|
||||
getSymbolAtLocation(node: Node): Symbol;
|
||||
getSymbolAtLocation(node: Node): Symbol | undefined;
|
||||
getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: string): Symbol[];
|
||||
getShorthandAssignmentValueSymbol(location: Node): Symbol;
|
||||
getExportSpecifierLocalTargetSymbol(location: ExportSpecifier): Symbol;
|
||||
getPropertySymbolOfDestructuringAssignment(location: Identifier): Symbol;
|
||||
getShorthandAssignmentValueSymbol(location: Node): Symbol | undefined;
|
||||
getExportSpecifierLocalTargetSymbol(location: ExportSpecifier): Symbol | undefined;
|
||||
getPropertySymbolOfDestructuringAssignment(location: Identifier): Symbol | undefined;
|
||||
getTypeAtLocation(node: Node): Type;
|
||||
getTypeFromTypeNode(node: TypeNode): Type;
|
||||
signatureToString(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): string;
|
||||
|
@ -2534,15 +2543,15 @@ namespace ts {
|
|||
getAugmentedPropertiesOfType(type: Type): Symbol[];
|
||||
getRootSymbols(symbol: Symbol): Symbol[];
|
||||
getContextualType(node: Expression): Type | undefined;
|
||||
getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[]): Signature;
|
||||
getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature;
|
||||
isImplementationOfOverload(node: FunctionLikeDeclaration): boolean;
|
||||
getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[]): Signature | undefined;
|
||||
getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature | undefined;
|
||||
isImplementationOfOverload(node: FunctionLikeDeclaration): boolean | undefined;
|
||||
isUndefinedSymbol(symbol: Symbol): boolean;
|
||||
isArgumentsSymbol(symbol: Symbol): boolean;
|
||||
isUnknownSymbol(symbol: Symbol): boolean;
|
||||
/* @internal */ getMergedSymbol(symbol: Symbol): Symbol;
|
||||
|
||||
getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number;
|
||||
getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number | undefined;
|
||||
isValidPropertyAccess(node: PropertyAccessExpression | QualifiedName, propertyName: string): boolean;
|
||||
/** Follow all aliases to get the original symbol. */
|
||||
getAliasedSymbol(symbol: Symbol): Symbol;
|
||||
|
@ -2552,7 +2561,7 @@ namespace ts {
|
|||
/** Unlike `getExportsOfModule`, this includes properties of an `export =` value. */
|
||||
/* @internal */ getExportsAndPropertiesOfModule(moduleSymbol: Symbol): Symbol[];
|
||||
|
||||
getAllAttributesTypeFromJsxOpeningLikeElement(elementNode: JsxOpeningLikeElement): Type;
|
||||
getAllAttributesTypeFromJsxOpeningLikeElement(elementNode: JsxOpeningLikeElement): Type | undefined;
|
||||
getJsxIntrinsicTagNames(): Symbol[];
|
||||
isOptionalParameter(node: ParameterDeclaration): boolean;
|
||||
getAmbientModules(): Symbol[];
|
||||
|
@ -2560,10 +2569,10 @@ namespace ts {
|
|||
tryGetMemberInModuleExports(memberName: string, moduleSymbol: Symbol): Symbol | undefined;
|
||||
getApparentType(type: Type): Type;
|
||||
getSuggestionForNonexistentProperty(node: Identifier, containingType: Type): string | undefined;
|
||||
getSuggestionForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): string;
|
||||
/* @internal */ getBaseConstraintOfType(type: Type): Type;
|
||||
getSuggestionForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): string | undefined;
|
||||
/* @internal */ getBaseConstraintOfType(type: Type): Type | undefined;
|
||||
|
||||
/* @internal */ tryFindAmbientModuleWithoutAugmentations(moduleName: string): Symbol;
|
||||
/* @internal */ tryFindAmbientModuleWithoutAugmentations(moduleName: string): Symbol | undefined;
|
||||
|
||||
// Should not be called directly. Should only be accessed through the Program instance.
|
||||
/* @internal */ getDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[];
|
||||
|
@ -2759,7 +2768,7 @@ namespace ts {
|
|||
getNodeCheckFlags(node: Node): NodeCheckFlags;
|
||||
isDeclarationVisible(node: Declaration): boolean;
|
||||
collectLinkedAliases(node: Identifier): Node[];
|
||||
isImplementationOfOverload(node: FunctionLikeDeclaration): boolean;
|
||||
isImplementationOfOverload(node: FunctionLikeDeclaration): boolean | undefined;
|
||||
isRequiredInitializedParameter(node: ParameterDeclaration): boolean;
|
||||
writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
|
||||
writeReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
|
||||
|
@ -3141,7 +3150,7 @@ namespace ts {
|
|||
*/
|
||||
export interface TypeReference extends ObjectType {
|
||||
target: GenericType; // Type reference target
|
||||
typeArguments: Type[]; // Type reference type arguments (undefined if none)
|
||||
typeArguments?: Type[]; // Type reference type arguments (undefined if none)
|
||||
}
|
||||
|
||||
// Generic class and interface types
|
||||
|
@ -3271,7 +3280,7 @@ namespace ts {
|
|||
|
||||
export interface Signature {
|
||||
declaration: SignatureDeclaration; // Originating declaration
|
||||
typeParameters: TypeParameter[]; // Type parameters (undefined if non-generic)
|
||||
typeParameters?: TypeParameter[]; // Type parameters (undefined if non-generic)
|
||||
parameters: Symbol[]; // Parameters
|
||||
/* @internal */
|
||||
thisParameter?: Symbol; // symbol of this-type parameter
|
||||
|
|
|
@ -11,12 +11,12 @@ namespace ts {
|
|||
isTypeReferenceDirective?: boolean;
|
||||
}
|
||||
|
||||
export function getDeclarationOfKind(symbol: Symbol, kind: SyntaxKind): Declaration {
|
||||
export function getDeclarationOfKind<T extends Declaration>(symbol: Symbol, kind: T["kind"]): T {
|
||||
const declarations = symbol.declarations;
|
||||
if (declarations) {
|
||||
for (const declaration of declarations) {
|
||||
if (declaration.kind === kind) {
|
||||
return declaration;
|
||||
return declaration as T;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2335,6 +2335,9 @@ namespace ts {
|
|||
case SyntaxKind.SpreadElement:
|
||||
return 1;
|
||||
|
||||
case SyntaxKind.CommaListExpression:
|
||||
return 0;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
@ -3924,6 +3927,7 @@ namespace ts {
|
|||
|| kind === SyntaxKind.SpreadElement
|
||||
|| kind === SyntaxKind.AsExpression
|
||||
|| kind === SyntaxKind.OmittedExpression
|
||||
|| kind === SyntaxKind.CommaListExpression
|
||||
|| isUnaryExpressionKind(kind);
|
||||
}
|
||||
|
||||
|
@ -4015,6 +4019,10 @@ namespace ts {
|
|||
return node.kind === SyntaxKind.ImportEqualsDeclaration;
|
||||
}
|
||||
|
||||
export function isImportDeclaration(node: Node): node is ImportDeclaration {
|
||||
return node.kind === SyntaxKind.ImportDeclaration;
|
||||
}
|
||||
|
||||
export function isImportClause(node: Node): node is ImportClause {
|
||||
return node.kind === SyntaxKind.ImportClause;
|
||||
}
|
||||
|
@ -4037,6 +4045,10 @@ namespace ts {
|
|||
return node.kind === SyntaxKind.ExportSpecifier;
|
||||
}
|
||||
|
||||
export function isExportAssignment(node: Node): node is ExportAssignment {
|
||||
return node.kind === SyntaxKind.ExportAssignment;
|
||||
}
|
||||
|
||||
export function isModuleOrEnumDeclaration(node: Node): node is ModuleDeclaration | EnumDeclaration {
|
||||
return node.kind === SyntaxKind.ModuleDeclaration || node.kind === SyntaxKind.EnumDeclaration;
|
||||
}
|
||||
|
@ -4244,6 +4256,29 @@ namespace ts {
|
|||
return options.watch && options.hasOwnProperty("watch");
|
||||
}
|
||||
|
||||
export function getCheckFlags(symbol: Symbol): CheckFlags {
|
||||
return symbol.flags & SymbolFlags.Transient ? (<TransientSymbol>symbol).checkFlags : 0;
|
||||
}
|
||||
|
||||
export function getDeclarationModifierFlagsFromSymbol(s: Symbol): ModifierFlags {
|
||||
if (s.valueDeclaration) {
|
||||
const flags = getCombinedModifierFlags(s.valueDeclaration);
|
||||
return s.parent && s.parent.flags & SymbolFlags.Class ? flags : flags & ~ModifierFlags.AccessibilityModifier;
|
||||
}
|
||||
if (getCheckFlags(s) & CheckFlags.Synthetic) {
|
||||
const checkFlags = (<TransientSymbol>s).checkFlags;
|
||||
const accessModifier = checkFlags & CheckFlags.ContainsPrivate ? ModifierFlags.Private :
|
||||
checkFlags & CheckFlags.ContainsPublic ? ModifierFlags.Public :
|
||||
ModifierFlags.Protected;
|
||||
const staticModifier = checkFlags & CheckFlags.ContainsStatic ? ModifierFlags.Static : 0;
|
||||
return accessModifier | staticModifier;
|
||||
}
|
||||
if (s.flags & SymbolFlags.Prototype) {
|
||||
return ModifierFlags.Public | ModifierFlags.Static;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
export function levenshtein(s1: string, s2: string): number {
|
||||
let previous: number[] = new Array(s2.length + 1);
|
||||
let current: number[] = new Array(s2.length + 1);
|
||||
|
|
|
@ -881,6 +881,10 @@ namespace ts {
|
|||
return updatePartiallyEmittedExpression(<PartiallyEmittedExpression>node,
|
||||
visitNode((<PartiallyEmittedExpression>node).expression, visitor, isExpression));
|
||||
|
||||
case SyntaxKind.CommaListExpression:
|
||||
return updateCommaList(<CommaListExpression>node,
|
||||
nodesVisitor((<CommaListExpression>node).elements, visitor, isExpression));
|
||||
|
||||
default:
|
||||
// No need to visit nodes with no children.
|
||||
return node;
|
||||
|
@ -1403,6 +1407,10 @@ namespace ts {
|
|||
result = reduceNode((<PartiallyEmittedExpression>node).expression, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.CommaListExpression:
|
||||
result = reduceNodes((<CommaListExpression>node).elements, cbNodes, result);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -3417,6 +3417,18 @@ namespace FourSlashInterface {
|
|||
|
||||
export class VerifyNegatable {
|
||||
public not: VerifyNegatable;
|
||||
public allowedClassElementKeywords = [
|
||||
"public",
|
||||
"private",
|
||||
"protected",
|
||||
"static",
|
||||
"abstract",
|
||||
"readonly",
|
||||
"get",
|
||||
"set",
|
||||
"constructor",
|
||||
"async"
|
||||
];
|
||||
|
||||
constructor(protected state: FourSlash.TestState, private negative = false) {
|
||||
if (!negative) {
|
||||
|
@ -3453,6 +3465,12 @@ namespace FourSlashInterface {
|
|||
this.state.verifyCompletionListIsEmpty(this.negative);
|
||||
}
|
||||
|
||||
public completionListContainsClassElementKeywords() {
|
||||
for (const keyword of this.allowedClassElementKeywords) {
|
||||
this.completionListContains(keyword, keyword, /*documentation*/ undefined, "keyword");
|
||||
}
|
||||
}
|
||||
|
||||
public completionListIsGlobal(expected: boolean) {
|
||||
this.state.verifyCompletionListIsGlobal(expected);
|
||||
}
|
||||
|
|
|
@ -2267,6 +2267,7 @@ namespace ts.server.protocol {
|
|||
insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean;
|
||||
insertSpaceAfterTypeAssertion?: boolean;
|
||||
insertSpaceBeforeFunctionParenthesis?: boolean;
|
||||
placeOpenBraceOnNewLineForFunctions?: boolean;
|
||||
placeOpenBraceOnNewLineForControlBlocks?: boolean;
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace ts.Completions {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
const { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, requestJsDocTagName, requestJsDocTag } = completionData;
|
||||
const { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, requestJsDocTagName, requestJsDocTag, hasFilteredClassMemberKeywords } = completionData;
|
||||
|
||||
if (requestJsDocTagName) {
|
||||
// If the current position is a jsDoc tag name, only tag names should be provided for completion
|
||||
|
@ -52,7 +52,7 @@ namespace ts.Completions {
|
|||
sortText: "0",
|
||||
});
|
||||
}
|
||||
else {
|
||||
else if (!hasFilteredClassMemberKeywords) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
@ -60,8 +60,11 @@ namespace ts.Completions {
|
|||
getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ true, typeChecker, compilerOptions.target, log);
|
||||
}
|
||||
|
||||
if (hasFilteredClassMemberKeywords) {
|
||||
addRange(entries, classMemberKeywordCompletions);
|
||||
}
|
||||
// Add keywords if this is not a member completion list
|
||||
if (!isMemberCompletion && !requestJsDocTag && !requestJsDocTagName) {
|
||||
else if (!isMemberCompletion && !requestJsDocTag && !requestJsDocTagName) {
|
||||
addRange(entries, keywordCompletions);
|
||||
}
|
||||
|
||||
|
@ -411,7 +414,7 @@ namespace ts.Completions {
|
|||
}
|
||||
|
||||
if (requestJsDocTagName || requestJsDocTag) {
|
||||
return { symbols: undefined, isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, requestJsDocTagName, requestJsDocTag };
|
||||
return { symbols: undefined, isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, requestJsDocTagName, requestJsDocTag, hasFilteredClassMemberKeywords: false };
|
||||
}
|
||||
|
||||
if (!insideJsDocTagExpression) {
|
||||
|
@ -510,6 +513,7 @@ namespace ts.Completions {
|
|||
let isGlobalCompletion = false;
|
||||
let isMemberCompletion: boolean;
|
||||
let isNewIdentifierLocation: boolean;
|
||||
let hasFilteredClassMemberKeywords = false;
|
||||
let symbols: Symbol[] = [];
|
||||
|
||||
if (isRightOfDot) {
|
||||
|
@ -547,7 +551,7 @@ namespace ts.Completions {
|
|||
|
||||
log("getCompletionData: Semantic work: " + (timestamp() - semanticStart));
|
||||
|
||||
return { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), requestJsDocTagName, requestJsDocTag };
|
||||
return { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), requestJsDocTagName, requestJsDocTag, hasFilteredClassMemberKeywords };
|
||||
|
||||
function getTypeScriptMemberSymbols(): void {
|
||||
// Right of dot member completion list
|
||||
|
@ -604,6 +608,7 @@ namespace ts.Completions {
|
|||
function tryGetGlobalSymbols(): boolean {
|
||||
let objectLikeContainer: ObjectLiteralExpression | BindingPattern;
|
||||
let namedImportsOrExports: NamedImportsOrExports;
|
||||
let classLikeContainer: ClassLikeDeclaration;
|
||||
let jsxContainer: JsxOpeningLikeElement;
|
||||
|
||||
if (objectLikeContainer = tryGetObjectLikeCompletionContainer(contextToken)) {
|
||||
|
@ -616,6 +621,12 @@ namespace ts.Completions {
|
|||
return tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports);
|
||||
}
|
||||
|
||||
if (classLikeContainer = tryGetClassLikeCompletionContainer(contextToken)) {
|
||||
// cursor inside class declaration
|
||||
getGetClassLikeCompletionSymbols(classLikeContainer);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (jsxContainer = tryGetContainingJsxElement(contextToken)) {
|
||||
let attrsType: Type;
|
||||
if ((jsxContainer.kind === SyntaxKind.JsxSelfClosingElement) || (jsxContainer.kind === SyntaxKind.JsxOpeningElement)) {
|
||||
|
@ -913,6 +924,62 @@ namespace ts.Completions {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Aggregates relevant symbols for completion in class declaration
|
||||
* Relevant symbols are stored in the captured 'symbols' variable.
|
||||
*/
|
||||
function getGetClassLikeCompletionSymbols(classLikeDeclaration: ClassLikeDeclaration) {
|
||||
// We're looking up possible property names from parent type.
|
||||
isMemberCompletion = true;
|
||||
// Declaring new property/method/accessor
|
||||
isNewIdentifierLocation = true;
|
||||
// Has keywords for class elements
|
||||
hasFilteredClassMemberKeywords = true;
|
||||
|
||||
const baseTypeNode = getClassExtendsHeritageClauseElement(classLikeDeclaration);
|
||||
const implementsTypeNodes = getClassImplementsHeritageClauseElements(classLikeDeclaration);
|
||||
if (baseTypeNode || implementsTypeNodes) {
|
||||
const classElement = contextToken.parent;
|
||||
let classElementModifierFlags = isClassElement(classElement) && getModifierFlags(classElement);
|
||||
// If this is context token is not something we are editing now, consider if this would lead to be modifier
|
||||
if (contextToken.kind === SyntaxKind.Identifier && !isCurrentlyEditingNode(contextToken)) {
|
||||
switch (contextToken.getText()) {
|
||||
case "private":
|
||||
classElementModifierFlags = classElementModifierFlags | ModifierFlags.Private;
|
||||
break;
|
||||
case "static":
|
||||
classElementModifierFlags = classElementModifierFlags | ModifierFlags.Static;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// No member list for private methods
|
||||
if (!(classElementModifierFlags & ModifierFlags.Private)) {
|
||||
let baseClassTypeToGetPropertiesFrom: Type;
|
||||
if (baseTypeNode) {
|
||||
baseClassTypeToGetPropertiesFrom = typeChecker.getTypeAtLocation(baseTypeNode);
|
||||
if (classElementModifierFlags & ModifierFlags.Static) {
|
||||
// Use static class to get property symbols from
|
||||
baseClassTypeToGetPropertiesFrom = typeChecker.getTypeOfSymbolAtLocation(
|
||||
baseClassTypeToGetPropertiesFrom.symbol, classLikeDeclaration);
|
||||
}
|
||||
}
|
||||
const implementedInterfaceTypePropertySymbols = (classElementModifierFlags & ModifierFlags.Static) ?
|
||||
undefined :
|
||||
flatMap(implementsTypeNodes, typeNode => typeChecker.getPropertiesOfType(typeChecker.getTypeAtLocation(typeNode)));
|
||||
|
||||
// List of property symbols of base type that are not private and already implemented
|
||||
symbols = filterClassMembersList(
|
||||
baseClassTypeToGetPropertiesFrom ?
|
||||
typeChecker.getPropertiesOfType(baseClassTypeToGetPropertiesFrom) :
|
||||
undefined,
|
||||
implementedInterfaceTypePropertySymbols,
|
||||
classLikeDeclaration.members,
|
||||
classElementModifierFlags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the immediate owning object literal or binding pattern of a context token,
|
||||
* on the condition that one exists and that the context implies completion should be given.
|
||||
|
@ -953,6 +1020,49 @@ namespace ts.Completions {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
function isFromClassElementDeclaration(node: Node) {
|
||||
return isClassElement(node.parent) && isClassLike(node.parent.parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the immediate owning class declaration of a context token,
|
||||
* on the condition that one exists and that the context implies completion should be given.
|
||||
*/
|
||||
function tryGetClassLikeCompletionContainer(contextToken: Node): ClassLikeDeclaration {
|
||||
if (contextToken) {
|
||||
switch (contextToken.kind) {
|
||||
case SyntaxKind.OpenBraceToken: // class c { |
|
||||
if (isClassLike(contextToken.parent)) {
|
||||
return contextToken.parent;
|
||||
}
|
||||
break;
|
||||
|
||||
// class c {getValue(): number; | }
|
||||
case SyntaxKind.CommaToken:
|
||||
case SyntaxKind.SemicolonToken:
|
||||
// class c { method() { } | }
|
||||
case SyntaxKind.CloseBraceToken:
|
||||
if (isClassLike(location)) {
|
||||
return location;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (isFromClassElementDeclaration(contextToken) &&
|
||||
(isClassMemberCompletionKeyword(contextToken.kind) ||
|
||||
isClassMemberCompletionKeywordText(contextToken.getText()))) {
|
||||
return contextToken.parent.parent as ClassLikeDeclaration;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// class c { method() { } | method2() { } }
|
||||
if (location && location.kind === SyntaxKind.SyntaxList && isClassLike(location.parent)) {
|
||||
return location.parent;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function tryGetContainingJsxElement(contextToken: Node): JsxOpeningLikeElement {
|
||||
if (contextToken) {
|
||||
const parent = contextToken.parent;
|
||||
|
@ -1081,7 +1191,7 @@ namespace ts.Completions {
|
|||
isFunction(containingNodeKind);
|
||||
|
||||
case SyntaxKind.StaticKeyword:
|
||||
return containingNodeKind === SyntaxKind.PropertyDeclaration;
|
||||
return containingNodeKind === SyntaxKind.PropertyDeclaration && !isClassLike(contextToken.parent.parent);
|
||||
|
||||
case SyntaxKind.DotDotDotToken:
|
||||
return containingNodeKind === SyntaxKind.Parameter ||
|
||||
|
@ -1098,13 +1208,17 @@ namespace ts.Completions {
|
|||
containingNodeKind === SyntaxKind.ExportSpecifier ||
|
||||
containingNodeKind === SyntaxKind.NamespaceImport;
|
||||
|
||||
case SyntaxKind.GetKeyword:
|
||||
case SyntaxKind.SetKeyword:
|
||||
if (isFromClassElementDeclaration(contextToken)) {
|
||||
return false;
|
||||
}
|
||||
// falls through
|
||||
case SyntaxKind.ClassKeyword:
|
||||
case SyntaxKind.EnumKeyword:
|
||||
case SyntaxKind.InterfaceKeyword:
|
||||
case SyntaxKind.FunctionKeyword:
|
||||
case SyntaxKind.VarKeyword:
|
||||
case SyntaxKind.GetKeyword:
|
||||
case SyntaxKind.SetKeyword:
|
||||
case SyntaxKind.ImportKeyword:
|
||||
case SyntaxKind.LetKeyword:
|
||||
case SyntaxKind.ConstKeyword:
|
||||
|
@ -1113,6 +1227,13 @@ namespace ts.Completions {
|
|||
return true;
|
||||
}
|
||||
|
||||
// If the previous token is keyword correspoding to class member completion keyword
|
||||
// there will be completion available here
|
||||
if (isClassMemberCompletionKeywordText(contextToken.getText()) &&
|
||||
isFromClassElementDeclaration(contextToken)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Previous token may have been a keyword that was converted to an identifier.
|
||||
switch (contextToken.getText()) {
|
||||
case "abstract":
|
||||
|
@ -1159,7 +1280,7 @@ namespace ts.Completions {
|
|||
|
||||
for (const element of namedImportsOrExports) {
|
||||
// If this is the current item we are editing right now, do not filter it out
|
||||
if (element.getStart() <= position && position <= element.getEnd()) {
|
||||
if (isCurrentlyEditingNode(element)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1198,7 +1319,7 @@ namespace ts.Completions {
|
|||
}
|
||||
|
||||
// If this is the current item we are editing right now, do not filter it out
|
||||
if (m.getStart() <= position && position <= m.getEnd()) {
|
||||
if (isCurrentlyEditingNode(m)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1223,6 +1344,58 @@ namespace ts.Completions {
|
|||
return filter(contextualMemberSymbols, m => !existingMemberNames.get(m.name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters out completion suggestions for class elements.
|
||||
*
|
||||
* @returns Symbols to be suggested in an class element depending on existing memebers and symbol flags
|
||||
*/
|
||||
function filterClassMembersList(baseSymbols: Symbol[], implementingTypeSymbols: Symbol[], existingMembers: ClassElement[], currentClassElementModifierFlags: ModifierFlags): Symbol[] {
|
||||
const existingMemberNames = createMap<boolean>();
|
||||
for (const m of existingMembers) {
|
||||
// Ignore omitted expressions for missing members
|
||||
if (m.kind !== SyntaxKind.PropertyDeclaration &&
|
||||
m.kind !== SyntaxKind.MethodDeclaration &&
|
||||
m.kind !== SyntaxKind.GetAccessor &&
|
||||
m.kind !== SyntaxKind.SetAccessor) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If this is the current item we are editing right now, do not filter it out
|
||||
if (isCurrentlyEditingNode(m)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Dont filter member even if the name matches if it is declared private in the list
|
||||
if (hasModifier(m, ModifierFlags.Private)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// do not filter it out if the static presence doesnt match
|
||||
const mIsStatic = hasModifier(m, ModifierFlags.Static);
|
||||
const currentElementIsStatic = !!(currentClassElementModifierFlags & ModifierFlags.Static);
|
||||
if ((mIsStatic && !currentElementIsStatic) ||
|
||||
(!mIsStatic && currentElementIsStatic)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const existingName = getPropertyNameForPropertyNameNode(m.name);
|
||||
if (existingName) {
|
||||
existingMemberNames.set(existingName, true);
|
||||
}
|
||||
}
|
||||
|
||||
return concatenate(
|
||||
filter(baseSymbols, baseProperty => isValidProperty(baseProperty, ModifierFlags.Private)),
|
||||
filter(implementingTypeSymbols, implementingProperty => isValidProperty(implementingProperty, ModifierFlags.NonPublicAccessibilityModifier))
|
||||
);
|
||||
|
||||
function isValidProperty(propertySymbol: Symbol, inValidModifierFlags: ModifierFlags) {
|
||||
return !existingMemberNames.get(propertySymbol.name) &&
|
||||
propertySymbol.getDeclarations() &&
|
||||
!(getDeclarationModifierFlagsFromSymbol(propertySymbol) & inValidModifierFlags);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters out completion suggestions from 'symbols' according to existing JSX attributes.
|
||||
*
|
||||
|
@ -1233,7 +1406,7 @@ namespace ts.Completions {
|
|||
const seenNames = createMap<boolean>();
|
||||
for (const attr of attributes) {
|
||||
// If this is the current item we are editing right now, do not filter it out
|
||||
if (attr.getStart() <= position && position <= attr.getEnd()) {
|
||||
if (isCurrentlyEditingNode(attr)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1244,6 +1417,10 @@ namespace ts.Completions {
|
|||
|
||||
return filter(symbols, a => !seenNames.get(a.name));
|
||||
}
|
||||
|
||||
function isCurrentlyEditingNode(node: Node): boolean {
|
||||
return node.getStart() <= position && position <= node.getEnd();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1306,6 +1483,29 @@ namespace ts.Completions {
|
|||
});
|
||||
}
|
||||
|
||||
function isClassMemberCompletionKeyword(kind: SyntaxKind) {
|
||||
switch (kind) {
|
||||
case SyntaxKind.PublicKeyword:
|
||||
case SyntaxKind.ProtectedKeyword:
|
||||
case SyntaxKind.PrivateKeyword:
|
||||
case SyntaxKind.AbstractKeyword:
|
||||
case SyntaxKind.StaticKeyword:
|
||||
case SyntaxKind.ConstructorKeyword:
|
||||
case SyntaxKind.ReadonlyKeyword:
|
||||
case SyntaxKind.GetKeyword:
|
||||
case SyntaxKind.SetKeyword:
|
||||
case SyntaxKind.AsyncKeyword:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function isClassMemberCompletionKeywordText(text: string) {
|
||||
return isClassMemberCompletionKeyword(stringToToken(text));
|
||||
}
|
||||
|
||||
const classMemberKeywordCompletions = filter(keywordCompletions, entry =>
|
||||
isClassMemberCompletionKeywordText(entry.name));
|
||||
|
||||
function isEqualityExpression(node: Node): node is BinaryExpression {
|
||||
return isBinaryExpression(node) && isEqualityOperatorKind(node.operatorToken.kind);
|
||||
}
|
||||
|
|
|
@ -550,7 +550,7 @@ namespace ts.FindAllReferences.Core {
|
|||
}
|
||||
|
||||
function isObjectBindingPatternElementWithoutPropertyName(symbol: Symbol): boolean {
|
||||
const bindingElement = <BindingElement>getDeclarationOfKind(symbol, SyntaxKind.BindingElement);
|
||||
const bindingElement = getDeclarationOfKind<BindingElement>(symbol, SyntaxKind.BindingElement);
|
||||
return bindingElement &&
|
||||
bindingElement.parent.kind === SyntaxKind.ObjectBindingPattern &&
|
||||
!bindingElement.propertyName;
|
||||
|
@ -558,7 +558,7 @@ namespace ts.FindAllReferences.Core {
|
|||
|
||||
function getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol: Symbol, checker: TypeChecker): Symbol | undefined {
|
||||
if (isObjectBindingPatternElementWithoutPropertyName(symbol)) {
|
||||
const bindingElement = <BindingElement>getDeclarationOfKind(symbol, SyntaxKind.BindingElement);
|
||||
const bindingElement = getDeclarationOfKind<BindingElement>(symbol, SyntaxKind.BindingElement);
|
||||
const typeOfPattern = checker.getTypeAtLocation(bindingElement.parent);
|
||||
return typeOfPattern && checker.getPropertyOfType(typeOfPattern, (<Identifier>bindingElement.name).text);
|
||||
}
|
||||
|
|
|
@ -526,17 +526,18 @@ namespace ts.FindAllReferences {
|
|||
return isExternalModuleSymbol(exportingModuleSymbol) ? { exportingModuleSymbol, exportKind } : undefined;
|
||||
}
|
||||
|
||||
function symbolName(symbol: Symbol): string {
|
||||
function symbolName(symbol: Symbol): string | undefined {
|
||||
if (symbol.name !== "default") {
|
||||
return symbol.name;
|
||||
}
|
||||
|
||||
const name = forEach(symbol.declarations, decl => {
|
||||
return forEach(symbol.declarations, decl => {
|
||||
if (isExportAssignment(decl)) {
|
||||
return isIdentifier(decl.expression) ? decl.expression.text : undefined;
|
||||
}
|
||||
const name = getNameOfDeclaration(decl);
|
||||
return name && name.kind === SyntaxKind.Identifier && name.text;
|
||||
});
|
||||
Debug.assert(!!name);
|
||||
return name;
|
||||
}
|
||||
|
||||
/** If at an export specifier, go to the symbol it refers to. */
|
||||
|
|
|
@ -200,27 +200,33 @@ namespace ts.SymbolDisplay {
|
|||
(location.kind === SyntaxKind.ConstructorKeyword && location.parent.kind === SyntaxKind.Constructor)) { // At constructor keyword of constructor declaration
|
||||
// get the signature from the declaration and write it
|
||||
const functionDeclaration = <FunctionLikeDeclaration>location.parent;
|
||||
const allSignatures = functionDeclaration.kind === SyntaxKind.Constructor ? type.getNonNullableType().getConstructSignatures() : type.getNonNullableType().getCallSignatures();
|
||||
if (!typeChecker.isImplementationOfOverload(functionDeclaration)) {
|
||||
signature = typeChecker.getSignatureFromDeclaration(functionDeclaration);
|
||||
}
|
||||
else {
|
||||
signature = allSignatures[0];
|
||||
}
|
||||
// Use function declaration to write the signatures only if the symbol corresponding to this declaration
|
||||
const locationIsSymbolDeclaration = findDeclaration(symbol, declaration =>
|
||||
declaration === (location.kind === SyntaxKind.ConstructorKeyword ? functionDeclaration.parent : functionDeclaration));
|
||||
|
||||
if (functionDeclaration.kind === SyntaxKind.Constructor) {
|
||||
// show (constructor) Type(...) signature
|
||||
symbolKind = ScriptElementKind.constructorImplementationElement;
|
||||
addPrefixForAnyFunctionOrVar(type.symbol, symbolKind);
|
||||
}
|
||||
else {
|
||||
// (function/method) symbol(..signature)
|
||||
addPrefixForAnyFunctionOrVar(functionDeclaration.kind === SyntaxKind.CallSignature &&
|
||||
!(type.symbol.flags & SymbolFlags.TypeLiteral || type.symbol.flags & SymbolFlags.ObjectLiteral) ? type.symbol : symbol, symbolKind);
|
||||
}
|
||||
if (locationIsSymbolDeclaration) {
|
||||
const allSignatures = functionDeclaration.kind === SyntaxKind.Constructor ? type.getNonNullableType().getConstructSignatures() : type.getNonNullableType().getCallSignatures();
|
||||
if (!typeChecker.isImplementationOfOverload(functionDeclaration)) {
|
||||
signature = typeChecker.getSignatureFromDeclaration(functionDeclaration);
|
||||
}
|
||||
else {
|
||||
signature = allSignatures[0];
|
||||
}
|
||||
|
||||
addSignatureDisplayParts(signature, allSignatures);
|
||||
hasAddedSymbolInfo = true;
|
||||
if (functionDeclaration.kind === SyntaxKind.Constructor) {
|
||||
// show (constructor) Type(...) signature
|
||||
symbolKind = ScriptElementKind.constructorImplementationElement;
|
||||
addPrefixForAnyFunctionOrVar(type.symbol, symbolKind);
|
||||
}
|
||||
else {
|
||||
// (function/method) symbol(..signature)
|
||||
addPrefixForAnyFunctionOrVar(functionDeclaration.kind === SyntaxKind.CallSignature &&
|
||||
!(type.symbol.flags & SymbolFlags.TypeLiteral || type.symbol.flags & SymbolFlags.ObjectLiteral) ? type.symbol : symbol, symbolKind);
|
||||
}
|
||||
|
||||
addSignatureDisplayParts(signature, allSignatures);
|
||||
hasAddedSymbolInfo = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -269,7 +275,7 @@ namespace ts.SymbolDisplay {
|
|||
}
|
||||
if (symbolFlags & SymbolFlags.Module) {
|
||||
addNewLineIfDisplayPartsExist();
|
||||
const declaration = <ModuleDeclaration>getDeclarationOfKind(symbol, SyntaxKind.ModuleDeclaration);
|
||||
const declaration = getDeclarationOfKind<ModuleDeclaration>(symbol, SyntaxKind.ModuleDeclaration);
|
||||
const isNamespace = declaration && declaration.name && declaration.name.kind === SyntaxKind.Identifier;
|
||||
displayParts.push(keywordPart(isNamespace ? SyntaxKind.NamespaceKeyword : SyntaxKind.ModuleKeyword));
|
||||
displayParts.push(spacePart());
|
||||
|
@ -290,9 +296,9 @@ namespace ts.SymbolDisplay {
|
|||
}
|
||||
else {
|
||||
// Method/function type parameter
|
||||
let declaration = <Node>getDeclarationOfKind(symbol, SyntaxKind.TypeParameter);
|
||||
Debug.assert(declaration !== undefined);
|
||||
declaration = declaration.parent;
|
||||
const decl = getDeclarationOfKind(symbol, SyntaxKind.TypeParameter);
|
||||
Debug.assert(decl !== undefined);
|
||||
const declaration = decl.parent;
|
||||
|
||||
if (declaration) {
|
||||
if (isFunctionLikeKind(declaration.kind)) {
|
||||
|
|
|
@ -651,44 +651,26 @@ namespace ts {
|
|||
return current;
|
||||
}
|
||||
|
||||
if (includeJsDocComment) {
|
||||
const jsDocChildren = ts.filter(current.getChildren(), isJSDocNode);
|
||||
for (const jsDocChild of jsDocChildren) {
|
||||
const start = allowPositionInLeadingTrivia ? jsDocChild.getFullStart() : jsDocChild.getStart(sourceFile, includeJsDocComment);
|
||||
if (start <= position) {
|
||||
const end = jsDocChild.getEnd();
|
||||
if (position < end || (position === end && jsDocChild.kind === SyntaxKind.EndOfFileToken)) {
|
||||
current = jsDocChild;
|
||||
continue outer;
|
||||
}
|
||||
else if (includeItemAtEndPosition && end === position) {
|
||||
const previousToken = findPrecedingToken(position, sourceFile, jsDocChild);
|
||||
if (previousToken && includeItemAtEndPosition(previousToken)) {
|
||||
return previousToken;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// find the child that contains 'position'
|
||||
for (const child of current.getChildren()) {
|
||||
// all jsDocComment nodes were already visited
|
||||
if (isJSDocNode(child)) {
|
||||
if (isJSDocNode(child) && !includeJsDocComment) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const start = allowPositionInLeadingTrivia ? child.getFullStart() : child.getStart(sourceFile, includeJsDocComment);
|
||||
if (start <= position) {
|
||||
const end = child.getEnd();
|
||||
if (position < end || (position === end && child.kind === SyntaxKind.EndOfFileToken)) {
|
||||
current = child;
|
||||
continue outer;
|
||||
}
|
||||
else if (includeItemAtEndPosition && end === position) {
|
||||
const previousToken = findPrecedingToken(position, sourceFile, child);
|
||||
if (previousToken && includeItemAtEndPosition(previousToken)) {
|
||||
return previousToken;
|
||||
}
|
||||
if (start > position) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const end = child.getEnd();
|
||||
if (position < end || (position === end && child.kind === SyntaxKind.EndOfFileToken)) {
|
||||
current = child;
|
||||
continue outer;
|
||||
}
|
||||
else if (includeItemAtEndPosition && end === position) {
|
||||
const previousToken = findPrecedingToken(position, sourceFile, child);
|
||||
if (previousToken && includeItemAtEndPosition(previousToken)) {
|
||||
return previousToken;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -128,8 +128,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
|
|||
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
|
||||
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
|
||||
var i, p;
|
||||
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
|
||||
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
|
||||
};
|
||||
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
|
||||
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
||||
|
@ -169,8 +169,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
|
|||
};
|
||||
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
|
||||
var i, p;
|
||||
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
|
||||
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
|
||||
};
|
||||
class C5 {
|
||||
f() {
|
||||
|
|
|
@ -264,8 +264,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
|
|||
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
|
||||
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
|
||||
var i, p;
|
||||
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
|
||||
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
|
||||
};
|
||||
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
|
||||
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
||||
|
@ -354,8 +354,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
|
|||
};
|
||||
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
|
||||
var i, p;
|
||||
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
|
||||
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
|
||||
};
|
||||
var __values = (this && this.__values) || function (o) {
|
||||
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
|
||||
|
|
|
@ -91,8 +91,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
|
|||
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
|
||||
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
|
||||
var i, p;
|
||||
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
|
||||
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
|
||||
};
|
||||
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
|
||||
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
||||
|
@ -130,8 +130,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
|
|||
};
|
||||
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
|
||||
var i, p;
|
||||
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
|
||||
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
|
||||
};
|
||||
function f5() {
|
||||
return __asyncGenerator(this, arguments, function* f5_1() {
|
||||
|
|
|
@ -218,8 +218,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
|
|||
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
|
||||
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
|
||||
var i, p;
|
||||
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
|
||||
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
|
||||
};
|
||||
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
|
||||
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
||||
|
@ -303,8 +303,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
|
|||
};
|
||||
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
|
||||
var i, p;
|
||||
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
|
||||
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
|
||||
};
|
||||
var __values = (this && this.__values) || function (o) {
|
||||
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
|
||||
|
|
|
@ -91,8 +91,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
|
|||
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
|
||||
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
|
||||
var i, p;
|
||||
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
|
||||
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
|
||||
};
|
||||
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
|
||||
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
||||
|
@ -130,8 +130,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
|
|||
};
|
||||
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
|
||||
var i, p;
|
||||
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
|
||||
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
|
||||
};
|
||||
const f5 = function () {
|
||||
return __asyncGenerator(this, arguments, function* () {
|
||||
|
|
|
@ -218,8 +218,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
|
|||
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
|
||||
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
|
||||
var i, p;
|
||||
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
|
||||
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
|
||||
};
|
||||
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
|
||||
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
||||
|
@ -303,8 +303,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
|
|||
};
|
||||
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
|
||||
var i, p;
|
||||
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
|
||||
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
|
||||
};
|
||||
var __values = (this && this.__values) || function (o) {
|
||||
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
|
||||
|
|
|
@ -111,8 +111,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
|
|||
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
|
||||
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
|
||||
var i, p;
|
||||
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
|
||||
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
|
||||
};
|
||||
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
|
||||
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
||||
|
@ -152,8 +152,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
|
|||
};
|
||||
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
|
||||
var i, p;
|
||||
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
|
||||
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
|
||||
};
|
||||
const o5 = {
|
||||
f() {
|
||||
|
|
|
@ -238,8 +238,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
|
|||
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
|
||||
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
|
||||
var i, p;
|
||||
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
|
||||
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
|
||||
};
|
||||
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
|
||||
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
||||
|
@ -325,8 +325,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
|
|||
};
|
||||
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
|
||||
var i, p;
|
||||
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
|
||||
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
|
||||
};
|
||||
var __values = (this && this.__values) || function (o) {
|
||||
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
tests/cases/compiler/enumUsedBeforeDeclaration.ts(1,18): error TS2450: Enum 'Color' used before its declaration.
|
||||
tests/cases/compiler/enumUsedBeforeDeclaration.ts(2,24): error TS2450: Enum 'ConstColor' used before its declaration.
|
||||
|
||||
|
||||
==== tests/cases/compiler/enumUsedBeforeDeclaration.ts (2 errors) ====
|
||||
==== tests/cases/compiler/enumUsedBeforeDeclaration.ts (1 errors) ====
|
||||
const v: Color = Color.Green;
|
||||
~~~~~
|
||||
!!! error TS2450: Enum 'Color' used before its declaration.
|
||||
const v2: ConstColor = ConstColor.Green;
|
||||
~~~~~~~~~~
|
||||
!!! error TS2450: Enum 'ConstColor' used before its declaration.
|
||||
enum Color { Red, Green, Blue }
|
||||
const enum ConstColor { Red, Green, Blue }
|
||||
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
tests/cases/conformance/jsx/file.tsx(21,16): error TS2322: Type '{ x: number; }' is not assignable to type 'Attribs1'.
|
||||
Types of property 'x' are incompatible.
|
||||
Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/conformance/jsx/file.tsx(25,16): error TS2322: Type '{ y: string; }' is not assignable to type 'Attribs1'.
|
||||
Property 'x' is missing in type '{ y: string; }'.
|
||||
tests/cases/conformance/jsx/file.tsx(21,16): error TS2322: Type 'T' is not assignable to type 'Attribs1'.
|
||||
Type '{ x: number; }' is not assignable to type 'Attribs1'.
|
||||
Types of property 'x' are incompatible.
|
||||
Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/conformance/jsx/file.tsx(25,16): error TS2322: Type 'T' is not assignable to type 'Attribs1'.
|
||||
Type '{ y: string; }' is not assignable to type 'Attribs1'.
|
||||
Property 'x' is missing in type '{ y: string; }'.
|
||||
tests/cases/conformance/jsx/file.tsx(29,8): error TS2322: Type '{}' is not assignable to type 'Attribs1'.
|
||||
Property 'x' is missing in type '{}'.
|
||||
|
||||
|
@ -30,16 +32,18 @@ tests/cases/conformance/jsx/file.tsx(29,8): error TS2322: Type '{}' is not assig
|
|||
function make2<T extends {x: number}> (obj: T) {
|
||||
return <test1 {...obj} />; // Error (x is number, not string)
|
||||
~~~~~~~~
|
||||
!!! error TS2322: Type '{ x: number; }' is not assignable to type 'Attribs1'.
|
||||
!!! error TS2322: Types of property 'x' are incompatible.
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'Attribs1'.
|
||||
!!! error TS2322: Type '{ x: number; }' is not assignable to type 'Attribs1'.
|
||||
!!! error TS2322: Types of property 'x' are incompatible.
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
}
|
||||
|
||||
function make3<T extends {y: string}> (obj: T) {
|
||||
return <test1 {...obj} />; // Error, missing x
|
||||
~~~~~~~~
|
||||
!!! error TS2322: Type '{ y: string; }' is not assignable to type 'Attribs1'.
|
||||
!!! error TS2322: Property 'x' is missing in type '{ y: string; }'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'Attribs1'.
|
||||
!!! error TS2322: Type '{ y: string; }' is not assignable to type 'Attribs1'.
|
||||
!!! error TS2322: Property 'x' is missing in type '{ y: string; }'.
|
||||
}
|
||||
|
||||
|
||||
|
|
28
tests/baselines/reference/tsxGenericAttributesType1.js
Normal file
28
tests/baselines/reference/tsxGenericAttributesType1.js
Normal file
|
@ -0,0 +1,28 @@
|
|||
//// [file.tsx]
|
||||
import React = require('react');
|
||||
|
||||
const decorator = function <T>(Component: React.StatelessComponent<T>): React.StatelessComponent<T> {
|
||||
return (props) => <Component {...props}></Component>
|
||||
};
|
||||
|
||||
const decorator2 = function <T extends { x: number }>(Component: React.StatelessComponent<T>): React.StatelessComponent<T> {
|
||||
return (props) => <Component {...props} x={2} ></Component>
|
||||
};
|
||||
|
||||
const decorator3 = function <T extends { x: number }, U extends { x: number } >(Component: React.StatelessComponent<T>): React.StatelessComponent<T> {
|
||||
return (props) => <Component x={2} {...props} ></Component>
|
||||
};
|
||||
|
||||
//// [file.jsx]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var React = require("react");
|
||||
var decorator = function (Component) {
|
||||
return function (props) { return <Component {...props}></Component>; };
|
||||
};
|
||||
var decorator2 = function (Component) {
|
||||
return function (props) { return <Component {...props} x={2}></Component>; };
|
||||
};
|
||||
var decorator3 = function (Component) {
|
||||
return function (props) { return <Component x={2} {...props}></Component>; };
|
||||
};
|
66
tests/baselines/reference/tsxGenericAttributesType1.symbols
Normal file
66
tests/baselines/reference/tsxGenericAttributesType1.symbols
Normal file
|
@ -0,0 +1,66 @@
|
|||
=== tests/cases/conformance/jsx/file.tsx ===
|
||||
import React = require('react');
|
||||
>React : Symbol(React, Decl(file.tsx, 0, 0))
|
||||
|
||||
const decorator = function <T>(Component: React.StatelessComponent<T>): React.StatelessComponent<T> {
|
||||
>decorator : Symbol(decorator, Decl(file.tsx, 2, 5))
|
||||
>T : Symbol(T, Decl(file.tsx, 2, 28))
|
||||
>Component : Symbol(Component, Decl(file.tsx, 2, 31))
|
||||
>React : Symbol(React, Decl(file.tsx, 0, 0))
|
||||
>StatelessComponent : Symbol(React.StatelessComponent, Decl(react.d.ts, 197, 40))
|
||||
>T : Symbol(T, Decl(file.tsx, 2, 28))
|
||||
>React : Symbol(React, Decl(file.tsx, 0, 0))
|
||||
>StatelessComponent : Symbol(React.StatelessComponent, Decl(react.d.ts, 197, 40))
|
||||
>T : Symbol(T, Decl(file.tsx, 2, 28))
|
||||
|
||||
return (props) => <Component {...props}></Component>
|
||||
>props : Symbol(props, Decl(file.tsx, 3, 12))
|
||||
>Component : Symbol(Component, Decl(file.tsx, 2, 31))
|
||||
>props : Symbol(props, Decl(file.tsx, 3, 12))
|
||||
>Component : Symbol(Component, Decl(file.tsx, 2, 31))
|
||||
|
||||
};
|
||||
|
||||
const decorator2 = function <T extends { x: number }>(Component: React.StatelessComponent<T>): React.StatelessComponent<T> {
|
||||
>decorator2 : Symbol(decorator2, Decl(file.tsx, 6, 5))
|
||||
>T : Symbol(T, Decl(file.tsx, 6, 29))
|
||||
>x : Symbol(x, Decl(file.tsx, 6, 40))
|
||||
>Component : Symbol(Component, Decl(file.tsx, 6, 54))
|
||||
>React : Symbol(React, Decl(file.tsx, 0, 0))
|
||||
>StatelessComponent : Symbol(React.StatelessComponent, Decl(react.d.ts, 197, 40))
|
||||
>T : Symbol(T, Decl(file.tsx, 6, 29))
|
||||
>React : Symbol(React, Decl(file.tsx, 0, 0))
|
||||
>StatelessComponent : Symbol(React.StatelessComponent, Decl(react.d.ts, 197, 40))
|
||||
>T : Symbol(T, Decl(file.tsx, 6, 29))
|
||||
|
||||
return (props) => <Component {...props} x={2} ></Component>
|
||||
>props : Symbol(props, Decl(file.tsx, 7, 12))
|
||||
>Component : Symbol(Component, Decl(file.tsx, 6, 54))
|
||||
>props : Symbol(props, Decl(file.tsx, 7, 12))
|
||||
>x : Symbol(x, Decl(file.tsx, 7, 43))
|
||||
>Component : Symbol(Component, Decl(file.tsx, 6, 54))
|
||||
|
||||
};
|
||||
|
||||
const decorator3 = function <T extends { x: number }, U extends { x: number } >(Component: React.StatelessComponent<T>): React.StatelessComponent<T> {
|
||||
>decorator3 : Symbol(decorator3, Decl(file.tsx, 10, 5))
|
||||
>T : Symbol(T, Decl(file.tsx, 10, 29))
|
||||
>x : Symbol(x, Decl(file.tsx, 10, 40))
|
||||
>U : Symbol(U, Decl(file.tsx, 10, 53))
|
||||
>x : Symbol(x, Decl(file.tsx, 10, 65))
|
||||
>Component : Symbol(Component, Decl(file.tsx, 10, 80))
|
||||
>React : Symbol(React, Decl(file.tsx, 0, 0))
|
||||
>StatelessComponent : Symbol(React.StatelessComponent, Decl(react.d.ts, 197, 40))
|
||||
>T : Symbol(T, Decl(file.tsx, 10, 29))
|
||||
>React : Symbol(React, Decl(file.tsx, 0, 0))
|
||||
>StatelessComponent : Symbol(React.StatelessComponent, Decl(react.d.ts, 197, 40))
|
||||
>T : Symbol(T, Decl(file.tsx, 10, 29))
|
||||
|
||||
return (props) => <Component x={2} {...props} ></Component>
|
||||
>props : Symbol(props, Decl(file.tsx, 11, 12))
|
||||
>Component : Symbol(Component, Decl(file.tsx, 10, 80))
|
||||
>x : Symbol(x, Decl(file.tsx, 11, 32))
|
||||
>props : Symbol(props, Decl(file.tsx, 11, 12))
|
||||
>Component : Symbol(Component, Decl(file.tsx, 10, 80))
|
||||
|
||||
};
|
77
tests/baselines/reference/tsxGenericAttributesType1.types
Normal file
77
tests/baselines/reference/tsxGenericAttributesType1.types
Normal file
|
@ -0,0 +1,77 @@
|
|||
=== tests/cases/conformance/jsx/file.tsx ===
|
||||
import React = require('react');
|
||||
>React : typeof React
|
||||
|
||||
const decorator = function <T>(Component: React.StatelessComponent<T>): React.StatelessComponent<T> {
|
||||
>decorator : <T>(Component: React.StatelessComponent<T>) => React.StatelessComponent<T>
|
||||
>function <T>(Component: React.StatelessComponent<T>): React.StatelessComponent<T> { return (props) => <Component {...props}></Component>} : <T>(Component: React.StatelessComponent<T>) => React.StatelessComponent<T>
|
||||
>T : T
|
||||
>Component : React.StatelessComponent<T>
|
||||
>React : any
|
||||
>StatelessComponent : React.StatelessComponent<P>
|
||||
>T : T
|
||||
>React : any
|
||||
>StatelessComponent : React.StatelessComponent<P>
|
||||
>T : T
|
||||
|
||||
return (props) => <Component {...props}></Component>
|
||||
>(props) => <Component {...props}></Component> : (props: T & { children?: React.ReactNode; }) => JSX.Element
|
||||
>props : T & { children?: React.ReactNode; }
|
||||
><Component {...props}></Component> : JSX.Element
|
||||
>Component : React.StatelessComponent<T>
|
||||
>props : T & { children?: React.ReactNode; }
|
||||
>Component : React.StatelessComponent<T>
|
||||
|
||||
};
|
||||
|
||||
const decorator2 = function <T extends { x: number }>(Component: React.StatelessComponent<T>): React.StatelessComponent<T> {
|
||||
>decorator2 : <T extends { x: number; }>(Component: React.StatelessComponent<T>) => React.StatelessComponent<T>
|
||||
>function <T extends { x: number }>(Component: React.StatelessComponent<T>): React.StatelessComponent<T> { return (props) => <Component {...props} x={2} ></Component>} : <T extends { x: number; }>(Component: React.StatelessComponent<T>) => React.StatelessComponent<T>
|
||||
>T : T
|
||||
>x : number
|
||||
>Component : React.StatelessComponent<T>
|
||||
>React : any
|
||||
>StatelessComponent : React.StatelessComponent<P>
|
||||
>T : T
|
||||
>React : any
|
||||
>StatelessComponent : React.StatelessComponent<P>
|
||||
>T : T
|
||||
|
||||
return (props) => <Component {...props} x={2} ></Component>
|
||||
>(props) => <Component {...props} x={2} ></Component> : (props: T & { children?: React.ReactNode; }) => JSX.Element
|
||||
>props : T & { children?: React.ReactNode; }
|
||||
><Component {...props} x={2} ></Component> : JSX.Element
|
||||
>Component : React.StatelessComponent<T>
|
||||
>props : T & { children?: React.ReactNode; }
|
||||
>x : number
|
||||
>2 : 2
|
||||
>Component : React.StatelessComponent<T>
|
||||
|
||||
};
|
||||
|
||||
const decorator3 = function <T extends { x: number }, U extends { x: number } >(Component: React.StatelessComponent<T>): React.StatelessComponent<T> {
|
||||
>decorator3 : <T extends { x: number; }, U extends { x: number; }>(Component: React.StatelessComponent<T>) => React.StatelessComponent<T>
|
||||
>function <T extends { x: number }, U extends { x: number } >(Component: React.StatelessComponent<T>): React.StatelessComponent<T> { return (props) => <Component x={2} {...props} ></Component>} : <T extends { x: number; }, U extends { x: number; }>(Component: React.StatelessComponent<T>) => React.StatelessComponent<T>
|
||||
>T : T
|
||||
>x : number
|
||||
>U : U
|
||||
>x : number
|
||||
>Component : React.StatelessComponent<T>
|
||||
>React : any
|
||||
>StatelessComponent : React.StatelessComponent<P>
|
||||
>T : T
|
||||
>React : any
|
||||
>StatelessComponent : React.StatelessComponent<P>
|
||||
>T : T
|
||||
|
||||
return (props) => <Component x={2} {...props} ></Component>
|
||||
>(props) => <Component x={2} {...props} ></Component> : (props: T & { children?: React.ReactNode; }) => JSX.Element
|
||||
>props : T & { children?: React.ReactNode; }
|
||||
><Component x={2} {...props} ></Component> : JSX.Element
|
||||
>Component : React.StatelessComponent<T>
|
||||
>x : number
|
||||
>2 : 2
|
||||
>props : T & { children?: React.ReactNode; }
|
||||
>Component : React.StatelessComponent<T>
|
||||
|
||||
};
|
|
@ -0,0 +1,11 @@
|
|||
tests/cases/conformance/jsx/file.tsx(4,45): error TS2339: Property 'y' does not exist on type 'IntrinsicAttributes & { x: number; } & { children?: ReactNode; }'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/jsx/file.tsx (1 errors) ====
|
||||
import React = require('react');
|
||||
|
||||
const decorator4 = function <T extends { x: number }>(Component: React.StatelessComponent<T>): React.StatelessComponent<T> {
|
||||
return (props) => <Component {...props} y={"blah"} ></Component>
|
||||
~~~~~~~~~~
|
||||
!!! error TS2339: Property 'y' does not exist on type 'IntrinsicAttributes & { x: number; } & { children?: ReactNode; }'.
|
||||
};
|
14
tests/baselines/reference/tsxGenericAttributesType2.js
Normal file
14
tests/baselines/reference/tsxGenericAttributesType2.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
//// [file.tsx]
|
||||
import React = require('react');
|
||||
|
||||
const decorator4 = function <T extends { x: number }>(Component: React.StatelessComponent<T>): React.StatelessComponent<T> {
|
||||
return (props) => <Component {...props} y={"blah"} ></Component>
|
||||
};
|
||||
|
||||
//// [file.jsx]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var React = require("react");
|
||||
var decorator4 = function (Component) {
|
||||
return function (props) { return <Component {...props} y={"blah"}></Component>; };
|
||||
};
|
48
tests/baselines/reference/tsxGenericAttributesType3.js
Normal file
48
tests/baselines/reference/tsxGenericAttributesType3.js
Normal file
|
@ -0,0 +1,48 @@
|
|||
//// [file.tsx]
|
||||
import React = require('react');
|
||||
|
||||
class B1<T extends { x: string } = { x:string } > extends React.Component<T, {}> {
|
||||
render() {
|
||||
return <div>hi</div>;
|
||||
}
|
||||
}
|
||||
class B<U> extends React.Component<U, {}> {
|
||||
render() {
|
||||
return <B1 {...this.props} x="hi" />;
|
||||
}
|
||||
}
|
||||
|
||||
//// [file.jsx]
|
||||
"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 React = require("react");
|
||||
var B1 = (function (_super) {
|
||||
__extends(B1, _super);
|
||||
function B1() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
B1.prototype.render = function () {
|
||||
return <div>hi</div>;
|
||||
};
|
||||
return B1;
|
||||
}(React.Component));
|
||||
var B = (function (_super) {
|
||||
__extends(B, _super);
|
||||
function B() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
B.prototype.render = function () {
|
||||
return <B1 {...this.props} x="hi"/>;
|
||||
};
|
||||
return B;
|
||||
}(React.Component));
|
41
tests/baselines/reference/tsxGenericAttributesType3.symbols
Normal file
41
tests/baselines/reference/tsxGenericAttributesType3.symbols
Normal file
|
@ -0,0 +1,41 @@
|
|||
=== tests/cases/conformance/jsx/file.tsx ===
|
||||
import React = require('react');
|
||||
>React : Symbol(React, Decl(file.tsx, 0, 0))
|
||||
|
||||
class B1<T extends { x: string } = { x:string } > extends React.Component<T, {}> {
|
||||
>B1 : Symbol(B1, Decl(file.tsx, 0, 32))
|
||||
>T : Symbol(T, Decl(file.tsx, 2, 9))
|
||||
>x : Symbol(x, Decl(file.tsx, 2, 20))
|
||||
>x : Symbol(x, Decl(file.tsx, 2, 36))
|
||||
>React.Component : Symbol(React.Component, Decl(react.d.ts, 158, 55))
|
||||
>React : Symbol(React, Decl(file.tsx, 0, 0))
|
||||
>Component : Symbol(React.Component, Decl(react.d.ts, 158, 55))
|
||||
>T : Symbol(T, Decl(file.tsx, 2, 9))
|
||||
|
||||
render() {
|
||||
>render : Symbol(B1.render, Decl(file.tsx, 2, 82))
|
||||
|
||||
return <div>hi</div>;
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45))
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45))
|
||||
}
|
||||
}
|
||||
class B<U> extends React.Component<U, {}> {
|
||||
>B : Symbol(B, Decl(file.tsx, 6, 1))
|
||||
>U : Symbol(U, Decl(file.tsx, 7, 8))
|
||||
>React.Component : Symbol(React.Component, Decl(react.d.ts, 158, 55))
|
||||
>React : Symbol(React, Decl(file.tsx, 0, 0))
|
||||
>Component : Symbol(React.Component, Decl(react.d.ts, 158, 55))
|
||||
>U : Symbol(U, Decl(file.tsx, 7, 8))
|
||||
|
||||
render() {
|
||||
>render : Symbol(B.render, Decl(file.tsx, 7, 43))
|
||||
|
||||
return <B1 {...this.props} x="hi" />;
|
||||
>B1 : Symbol(B1, Decl(file.tsx, 0, 32))
|
||||
>this.props : Symbol(React.Component.props, Decl(react.d.ts, 166, 37))
|
||||
>this : Symbol(B, Decl(file.tsx, 6, 1))
|
||||
>props : Symbol(React.Component.props, Decl(react.d.ts, 166, 37))
|
||||
>x : Symbol(x, Decl(file.tsx, 9, 34))
|
||||
}
|
||||
}
|
43
tests/baselines/reference/tsxGenericAttributesType3.types
Normal file
43
tests/baselines/reference/tsxGenericAttributesType3.types
Normal file
|
@ -0,0 +1,43 @@
|
|||
=== tests/cases/conformance/jsx/file.tsx ===
|
||||
import React = require('react');
|
||||
>React : typeof React
|
||||
|
||||
class B1<T extends { x: string } = { x:string } > extends React.Component<T, {}> {
|
||||
>B1 : B1<T>
|
||||
>T : T
|
||||
>x : string
|
||||
>x : string
|
||||
>React.Component : React.Component<T, {}>
|
||||
>React : typeof React
|
||||
>Component : typeof React.Component
|
||||
>T : T
|
||||
|
||||
render() {
|
||||
>render : () => JSX.Element
|
||||
|
||||
return <div>hi</div>;
|
||||
><div>hi</div> : JSX.Element
|
||||
>div : any
|
||||
>div : any
|
||||
}
|
||||
}
|
||||
class B<U> extends React.Component<U, {}> {
|
||||
>B : B<U>
|
||||
>U : U
|
||||
>React.Component : React.Component<U, {}>
|
||||
>React : typeof React
|
||||
>Component : typeof React.Component
|
||||
>U : U
|
||||
|
||||
render() {
|
||||
>render : () => JSX.Element
|
||||
|
||||
return <B1 {...this.props} x="hi" />;
|
||||
><B1 {...this.props} x="hi" /> : JSX.Element
|
||||
>B1 : typeof B1
|
||||
>this.props : U & { children?: React.ReactNode; }
|
||||
>this : this
|
||||
>props : U & { children?: React.ReactNode; }
|
||||
>x : string
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
tests/cases/conformance/jsx/file.tsx(11,36): error TS2339: Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<B1<{}>> & { children?: ReactNode; }'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/jsx/file.tsx (1 errors) ====
|
||||
import React = require('react');
|
||||
|
||||
class B1<T extends { x: string }> extends React.Component<T, {}> {
|
||||
render() {
|
||||
return <div>hi</div>;
|
||||
}
|
||||
}
|
||||
class B<U> extends React.Component<U, {}> {
|
||||
render() {
|
||||
// Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object
|
||||
return <B1 {...this.props} x="hi" />;
|
||||
~~~~~~
|
||||
!!! error TS2339: Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<B1<{}>> & { children?: ReactNode; }'.
|
||||
}
|
||||
}
|
50
tests/baselines/reference/tsxGenericAttributesType4.js
Normal file
50
tests/baselines/reference/tsxGenericAttributesType4.js
Normal file
|
@ -0,0 +1,50 @@
|
|||
//// [file.tsx]
|
||||
import React = require('react');
|
||||
|
||||
class B1<T extends { x: string }> extends React.Component<T, {}> {
|
||||
render() {
|
||||
return <div>hi</div>;
|
||||
}
|
||||
}
|
||||
class B<U> extends React.Component<U, {}> {
|
||||
render() {
|
||||
// Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object
|
||||
return <B1 {...this.props} x="hi" />;
|
||||
}
|
||||
}
|
||||
|
||||
//// [file.jsx]
|
||||
"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 React = require("react");
|
||||
var B1 = (function (_super) {
|
||||
__extends(B1, _super);
|
||||
function B1() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
B1.prototype.render = function () {
|
||||
return <div>hi</div>;
|
||||
};
|
||||
return B1;
|
||||
}(React.Component));
|
||||
var B = (function (_super) {
|
||||
__extends(B, _super);
|
||||
function B() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
B.prototype.render = function () {
|
||||
// Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object
|
||||
return <B1 {...this.props} x="hi"/>;
|
||||
};
|
||||
return B;
|
||||
}(React.Component));
|
|
@ -0,0 +1,20 @@
|
|||
tests/cases/conformance/jsx/file.tsx(12,36): error TS2339: Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<B1<{}>> & { children?: ReactNode; }'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/jsx/file.tsx (1 errors) ====
|
||||
import React = require('react');
|
||||
|
||||
class B1<T extends { x: string }> extends React.Component<T, {}> {
|
||||
render() {
|
||||
return <div>hi</div>;
|
||||
}
|
||||
}
|
||||
class B<U> extends React.Component<U, {}> {
|
||||
props: U;
|
||||
render() {
|
||||
// Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object
|
||||
return <B1 {...this.props} x="hi" />;
|
||||
~~~~~~
|
||||
!!! error TS2339: Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<B1<{}>> & { children?: ReactNode; }'.
|
||||
}
|
||||
}
|
51
tests/baselines/reference/tsxGenericAttributesType5.js
Normal file
51
tests/baselines/reference/tsxGenericAttributesType5.js
Normal file
|
@ -0,0 +1,51 @@
|
|||
//// [file.tsx]
|
||||
import React = require('react');
|
||||
|
||||
class B1<T extends { x: string }> extends React.Component<T, {}> {
|
||||
render() {
|
||||
return <div>hi</div>;
|
||||
}
|
||||
}
|
||||
class B<U> extends React.Component<U, {}> {
|
||||
props: U;
|
||||
render() {
|
||||
// Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object
|
||||
return <B1 {...this.props} x="hi" />;
|
||||
}
|
||||
}
|
||||
|
||||
//// [file.jsx]
|
||||
"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 React = require("react");
|
||||
var B1 = (function (_super) {
|
||||
__extends(B1, _super);
|
||||
function B1() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
B1.prototype.render = function () {
|
||||
return <div>hi</div>;
|
||||
};
|
||||
return B1;
|
||||
}(React.Component));
|
||||
var B = (function (_super) {
|
||||
__extends(B, _super);
|
||||
function B() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
B.prototype.render = function () {
|
||||
// Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object
|
||||
return <B1 {...this.props} x="hi"/>;
|
||||
};
|
||||
return B;
|
||||
}(React.Component));
|
49
tests/baselines/reference/tsxGenericAttributesType6.js
Normal file
49
tests/baselines/reference/tsxGenericAttributesType6.js
Normal file
|
@ -0,0 +1,49 @@
|
|||
//// [file.tsx]
|
||||
import React = require('react');
|
||||
|
||||
class B1<T extends { x: string } = { x:string } > extends React.Component<T, {}> {
|
||||
render() {
|
||||
return <div>hi</div>;
|
||||
}
|
||||
}
|
||||
class B<U> extends React.Component<U, {}> {
|
||||
props: U;
|
||||
render() {
|
||||
return <B1 {...this.props} x="hi" />;
|
||||
}
|
||||
}
|
||||
|
||||
//// [file.jsx]
|
||||
"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 React = require("react");
|
||||
var B1 = (function (_super) {
|
||||
__extends(B1, _super);
|
||||
function B1() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
B1.prototype.render = function () {
|
||||
return <div>hi</div>;
|
||||
};
|
||||
return B1;
|
||||
}(React.Component));
|
||||
var B = (function (_super) {
|
||||
__extends(B, _super);
|
||||
function B() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
B.prototype.render = function () {
|
||||
return <B1 {...this.props} x="hi"/>;
|
||||
};
|
||||
return B;
|
||||
}(React.Component));
|
45
tests/baselines/reference/tsxGenericAttributesType6.symbols
Normal file
45
tests/baselines/reference/tsxGenericAttributesType6.symbols
Normal file
|
@ -0,0 +1,45 @@
|
|||
=== tests/cases/conformance/jsx/file.tsx ===
|
||||
import React = require('react');
|
||||
>React : Symbol(React, Decl(file.tsx, 0, 0))
|
||||
|
||||
class B1<T extends { x: string } = { x:string } > extends React.Component<T, {}> {
|
||||
>B1 : Symbol(B1, Decl(file.tsx, 0, 32))
|
||||
>T : Symbol(T, Decl(file.tsx, 2, 9))
|
||||
>x : Symbol(x, Decl(file.tsx, 2, 20))
|
||||
>x : Symbol(x, Decl(file.tsx, 2, 36))
|
||||
>React.Component : Symbol(React.Component, Decl(react.d.ts, 158, 55))
|
||||
>React : Symbol(React, Decl(file.tsx, 0, 0))
|
||||
>Component : Symbol(React.Component, Decl(react.d.ts, 158, 55))
|
||||
>T : Symbol(T, Decl(file.tsx, 2, 9))
|
||||
|
||||
render() {
|
||||
>render : Symbol(B1.render, Decl(file.tsx, 2, 82))
|
||||
|
||||
return <div>hi</div>;
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45))
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45))
|
||||
}
|
||||
}
|
||||
class B<U> extends React.Component<U, {}> {
|
||||
>B : Symbol(B, Decl(file.tsx, 6, 1))
|
||||
>U : Symbol(U, Decl(file.tsx, 7, 8))
|
||||
>React.Component : Symbol(React.Component, Decl(react.d.ts, 158, 55))
|
||||
>React : Symbol(React, Decl(file.tsx, 0, 0))
|
||||
>Component : Symbol(React.Component, Decl(react.d.ts, 158, 55))
|
||||
>U : Symbol(U, Decl(file.tsx, 7, 8))
|
||||
|
||||
props: U;
|
||||
>props : Symbol(B.props, Decl(file.tsx, 7, 43))
|
||||
>U : Symbol(U, Decl(file.tsx, 7, 8))
|
||||
|
||||
render() {
|
||||
>render : Symbol(B.render, Decl(file.tsx, 8, 13))
|
||||
|
||||
return <B1 {...this.props} x="hi" />;
|
||||
>B1 : Symbol(B1, Decl(file.tsx, 0, 32))
|
||||
>this.props : Symbol(B.props, Decl(file.tsx, 7, 43))
|
||||
>this : Symbol(B, Decl(file.tsx, 6, 1))
|
||||
>props : Symbol(B.props, Decl(file.tsx, 7, 43))
|
||||
>x : Symbol(x, Decl(file.tsx, 10, 34))
|
||||
}
|
||||
}
|
47
tests/baselines/reference/tsxGenericAttributesType6.types
Normal file
47
tests/baselines/reference/tsxGenericAttributesType6.types
Normal file
|
@ -0,0 +1,47 @@
|
|||
=== tests/cases/conformance/jsx/file.tsx ===
|
||||
import React = require('react');
|
||||
>React : typeof React
|
||||
|
||||
class B1<T extends { x: string } = { x:string } > extends React.Component<T, {}> {
|
||||
>B1 : B1<T>
|
||||
>T : T
|
||||
>x : string
|
||||
>x : string
|
||||
>React.Component : React.Component<T, {}>
|
||||
>React : typeof React
|
||||
>Component : typeof React.Component
|
||||
>T : T
|
||||
|
||||
render() {
|
||||
>render : () => JSX.Element
|
||||
|
||||
return <div>hi</div>;
|
||||
><div>hi</div> : JSX.Element
|
||||
>div : any
|
||||
>div : any
|
||||
}
|
||||
}
|
||||
class B<U> extends React.Component<U, {}> {
|
||||
>B : B<U>
|
||||
>U : U
|
||||
>React.Component : React.Component<U, {}>
|
||||
>React : typeof React
|
||||
>Component : typeof React.Component
|
||||
>U : U
|
||||
|
||||
props: U;
|
||||
>props : U
|
||||
>U : U
|
||||
|
||||
render() {
|
||||
>render : () => JSX.Element
|
||||
|
||||
return <B1 {...this.props} x="hi" />;
|
||||
><B1 {...this.props} x="hi" /> : JSX.Element
|
||||
>B1 : typeof B1
|
||||
>this.props : U
|
||||
>this : this
|
||||
>props : U
|
||||
>x : string
|
||||
}
|
||||
}
|
22
tests/baselines/reference/tsxGenericAttributesType7.js
Normal file
22
tests/baselines/reference/tsxGenericAttributesType7.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
//// [file.tsx]
|
||||
import React = require('react');
|
||||
|
||||
declare function Component<T>(props: T) : JSX.Element;
|
||||
const decorator = function <U>(props: U) {
|
||||
return <Component {...props} />;
|
||||
}
|
||||
|
||||
const decorator1 = function <U extends {x: string}>(props: U) {
|
||||
return <Component {...props} x="hi"/>;
|
||||
}
|
||||
|
||||
//// [file.jsx]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var React = require("react");
|
||||
var decorator = function (props) {
|
||||
return <Component {...props}/>;
|
||||
};
|
||||
var decorator1 = function (props) {
|
||||
return <Component {...props} x="hi"/>;
|
||||
};
|
35
tests/baselines/reference/tsxGenericAttributesType7.symbols
Normal file
35
tests/baselines/reference/tsxGenericAttributesType7.symbols
Normal file
|
@ -0,0 +1,35 @@
|
|||
=== tests/cases/conformance/jsx/file.tsx ===
|
||||
import React = require('react');
|
||||
>React : Symbol(React, Decl(file.tsx, 0, 0))
|
||||
|
||||
declare function Component<T>(props: T) : JSX.Element;
|
||||
>Component : Symbol(Component, Decl(file.tsx, 0, 32))
|
||||
>T : Symbol(T, Decl(file.tsx, 2, 27))
|
||||
>props : Symbol(props, Decl(file.tsx, 2, 30))
|
||||
>T : Symbol(T, Decl(file.tsx, 2, 27))
|
||||
>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1))
|
||||
>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27))
|
||||
|
||||
const decorator = function <U>(props: U) {
|
||||
>decorator : Symbol(decorator, Decl(file.tsx, 3, 5))
|
||||
>U : Symbol(U, Decl(file.tsx, 3, 28))
|
||||
>props : Symbol(props, Decl(file.tsx, 3, 31))
|
||||
>U : Symbol(U, Decl(file.tsx, 3, 28))
|
||||
|
||||
return <Component {...props} />;
|
||||
>Component : Symbol(Component, Decl(file.tsx, 0, 32))
|
||||
>props : Symbol(props, Decl(file.tsx, 3, 31))
|
||||
}
|
||||
|
||||
const decorator1 = function <U extends {x: string}>(props: U) {
|
||||
>decorator1 : Symbol(decorator1, Decl(file.tsx, 7, 5))
|
||||
>U : Symbol(U, Decl(file.tsx, 7, 29))
|
||||
>x : Symbol(x, Decl(file.tsx, 7, 40))
|
||||
>props : Symbol(props, Decl(file.tsx, 7, 52))
|
||||
>U : Symbol(U, Decl(file.tsx, 7, 29))
|
||||
|
||||
return <Component {...props} x="hi"/>;
|
||||
>Component : Symbol(Component, Decl(file.tsx, 0, 32))
|
||||
>props : Symbol(props, Decl(file.tsx, 7, 52))
|
||||
>x : Symbol(x, Decl(file.tsx, 8, 32))
|
||||
}
|
39
tests/baselines/reference/tsxGenericAttributesType7.types
Normal file
39
tests/baselines/reference/tsxGenericAttributesType7.types
Normal file
|
@ -0,0 +1,39 @@
|
|||
=== tests/cases/conformance/jsx/file.tsx ===
|
||||
import React = require('react');
|
||||
>React : typeof React
|
||||
|
||||
declare function Component<T>(props: T) : JSX.Element;
|
||||
>Component : <T>(props: T) => JSX.Element
|
||||
>T : T
|
||||
>props : T
|
||||
>T : T
|
||||
>JSX : any
|
||||
>Element : JSX.Element
|
||||
|
||||
const decorator = function <U>(props: U) {
|
||||
>decorator : <U>(props: U) => JSX.Element
|
||||
>function <U>(props: U) { return <Component {...props} />;} : <U>(props: U) => JSX.Element
|
||||
>U : U
|
||||
>props : U
|
||||
>U : U
|
||||
|
||||
return <Component {...props} />;
|
||||
><Component {...props} /> : JSX.Element
|
||||
>Component : <T>(props: T) => JSX.Element
|
||||
>props : U
|
||||
}
|
||||
|
||||
const decorator1 = function <U extends {x: string}>(props: U) {
|
||||
>decorator1 : <U extends { x: string; }>(props: U) => JSX.Element
|
||||
>function <U extends {x: string}>(props: U) { return <Component {...props} x="hi"/>;} : <U extends { x: string; }>(props: U) => JSX.Element
|
||||
>U : U
|
||||
>x : string
|
||||
>props : U
|
||||
>U : U
|
||||
|
||||
return <Component {...props} x="hi"/>;
|
||||
><Component {...props} x="hi"/> : JSX.Element
|
||||
>Component : <T>(props: T) => JSX.Element
|
||||
>props : U
|
||||
>x : string
|
||||
}
|
22
tests/baselines/reference/tsxGenericAttributesType8.js
Normal file
22
tests/baselines/reference/tsxGenericAttributesType8.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
//// [file.tsx]
|
||||
import React = require('react');
|
||||
|
||||
declare function Component<T>(props: T) : JSX.Element;
|
||||
const decorator = function <U>(props: U) {
|
||||
return <Component {...props} />;
|
||||
}
|
||||
|
||||
const decorator1 = function <U extends {x: string}>(props: U) {
|
||||
return <Component {...props} />;
|
||||
}
|
||||
|
||||
//// [file.jsx]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var React = require("react");
|
||||
var decorator = function (props) {
|
||||
return <Component {...props}/>;
|
||||
};
|
||||
var decorator1 = function (props) {
|
||||
return <Component {...props}/>;
|
||||
};
|
34
tests/baselines/reference/tsxGenericAttributesType8.symbols
Normal file
34
tests/baselines/reference/tsxGenericAttributesType8.symbols
Normal file
|
@ -0,0 +1,34 @@
|
|||
=== tests/cases/conformance/jsx/file.tsx ===
|
||||
import React = require('react');
|
||||
>React : Symbol(React, Decl(file.tsx, 0, 0))
|
||||
|
||||
declare function Component<T>(props: T) : JSX.Element;
|
||||
>Component : Symbol(Component, Decl(file.tsx, 0, 32))
|
||||
>T : Symbol(T, Decl(file.tsx, 2, 27))
|
||||
>props : Symbol(props, Decl(file.tsx, 2, 30))
|
||||
>T : Symbol(T, Decl(file.tsx, 2, 27))
|
||||
>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1))
|
||||
>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27))
|
||||
|
||||
const decorator = function <U>(props: U) {
|
||||
>decorator : Symbol(decorator, Decl(file.tsx, 3, 5))
|
||||
>U : Symbol(U, Decl(file.tsx, 3, 28))
|
||||
>props : Symbol(props, Decl(file.tsx, 3, 31))
|
||||
>U : Symbol(U, Decl(file.tsx, 3, 28))
|
||||
|
||||
return <Component {...props} />;
|
||||
>Component : Symbol(Component, Decl(file.tsx, 0, 32))
|
||||
>props : Symbol(props, Decl(file.tsx, 3, 31))
|
||||
}
|
||||
|
||||
const decorator1 = function <U extends {x: string}>(props: U) {
|
||||
>decorator1 : Symbol(decorator1, Decl(file.tsx, 7, 5))
|
||||
>U : Symbol(U, Decl(file.tsx, 7, 29))
|
||||
>x : Symbol(x, Decl(file.tsx, 7, 40))
|
||||
>props : Symbol(props, Decl(file.tsx, 7, 52))
|
||||
>U : Symbol(U, Decl(file.tsx, 7, 29))
|
||||
|
||||
return <Component {...props} />;
|
||||
>Component : Symbol(Component, Decl(file.tsx, 0, 32))
|
||||
>props : Symbol(props, Decl(file.tsx, 7, 52))
|
||||
}
|
38
tests/baselines/reference/tsxGenericAttributesType8.types
Normal file
38
tests/baselines/reference/tsxGenericAttributesType8.types
Normal file
|
@ -0,0 +1,38 @@
|
|||
=== tests/cases/conformance/jsx/file.tsx ===
|
||||
import React = require('react');
|
||||
>React : typeof React
|
||||
|
||||
declare function Component<T>(props: T) : JSX.Element;
|
||||
>Component : <T>(props: T) => JSX.Element
|
||||
>T : T
|
||||
>props : T
|
||||
>T : T
|
||||
>JSX : any
|
||||
>Element : JSX.Element
|
||||
|
||||
const decorator = function <U>(props: U) {
|
||||
>decorator : <U>(props: U) => JSX.Element
|
||||
>function <U>(props: U) { return <Component {...props} />;} : <U>(props: U) => JSX.Element
|
||||
>U : U
|
||||
>props : U
|
||||
>U : U
|
||||
|
||||
return <Component {...props} />;
|
||||
><Component {...props} /> : JSX.Element
|
||||
>Component : <T>(props: T) => JSX.Element
|
||||
>props : U
|
||||
}
|
||||
|
||||
const decorator1 = function <U extends {x: string}>(props: U) {
|
||||
>decorator1 : <U extends { x: string; }>(props: U) => JSX.Element
|
||||
>function <U extends {x: string}>(props: U) { return <Component {...props} />;} : <U extends { x: string; }>(props: U) => JSX.Element
|
||||
>U : U
|
||||
>x : string
|
||||
>props : U
|
||||
>U : U
|
||||
|
||||
return <Component {...props} />;
|
||||
><Component {...props} /> : JSX.Element
|
||||
>Component : <T>(props: T) => JSX.Element
|
||||
>props : U
|
||||
}
|
40
tests/baselines/reference/tsxGenericAttributesType9.js
Normal file
40
tests/baselines/reference/tsxGenericAttributesType9.js
Normal file
|
@ -0,0 +1,40 @@
|
|||
//// [file.tsx]
|
||||
import React = require('react');
|
||||
|
||||
export function makeP<P>(Ctor: React.ComponentClass<P>): React.ComponentClass<P> {
|
||||
return class extends React.PureComponent<P, void> {
|
||||
public render(): JSX.Element {
|
||||
return (
|
||||
<Ctor {...this.props } />
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
//// [file.jsx]
|
||||
"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 React = require("react");
|
||||
function makeP(Ctor) {
|
||||
return (function (_super) {
|
||||
__extends(class_1, _super);
|
||||
function class_1() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
class_1.prototype.render = function () {
|
||||
return (<Ctor {...this.props}/>);
|
||||
};
|
||||
return class_1;
|
||||
}(React.PureComponent));
|
||||
}
|
||||
exports.makeP = makeP;
|
37
tests/baselines/reference/tsxGenericAttributesType9.symbols
Normal file
37
tests/baselines/reference/tsxGenericAttributesType9.symbols
Normal file
|
@ -0,0 +1,37 @@
|
|||
=== tests/cases/conformance/jsx/file.tsx ===
|
||||
import React = require('react');
|
||||
>React : Symbol(React, Decl(file.tsx, 0, 0))
|
||||
|
||||
export function makeP<P>(Ctor: React.ComponentClass<P>): React.ComponentClass<P> {
|
||||
>makeP : Symbol(makeP, Decl(file.tsx, 0, 32))
|
||||
>P : Symbol(P, Decl(file.tsx, 2, 22))
|
||||
>Ctor : Symbol(Ctor, Decl(file.tsx, 2, 25))
|
||||
>React : Symbol(React, Decl(file.tsx, 0, 0))
|
||||
>ComponentClass : Symbol(React.ComponentClass, Decl(react.d.ts, 204, 5))
|
||||
>P : Symbol(P, Decl(file.tsx, 2, 22))
|
||||
>React : Symbol(React, Decl(file.tsx, 0, 0))
|
||||
>ComponentClass : Symbol(React.ComponentClass, Decl(react.d.ts, 204, 5))
|
||||
>P : Symbol(P, Decl(file.tsx, 2, 22))
|
||||
|
||||
return class extends React.PureComponent<P, void> {
|
||||
>React.PureComponent : Symbol(React.PureComponent, Decl(react.d.ts, 179, 5))
|
||||
>React : Symbol(React, Decl(file.tsx, 0, 0))
|
||||
>PureComponent : Symbol(React.PureComponent, Decl(react.d.ts, 179, 5))
|
||||
>P : Symbol(P, Decl(file.tsx, 2, 22))
|
||||
|
||||
public render(): JSX.Element {
|
||||
>render : Symbol((Anonymous class).render, Decl(file.tsx, 3, 52))
|
||||
>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1))
|
||||
>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27))
|
||||
|
||||
return (
|
||||
<Ctor {...this.props } />
|
||||
>Ctor : Symbol(Ctor, Decl(file.tsx, 2, 25))
|
||||
>this.props : Symbol(React.Component.props, Decl(react.d.ts, 166, 37))
|
||||
>this : Symbol((Anonymous class), Decl(file.tsx, 3, 7))
|
||||
>props : Symbol(React.Component.props, Decl(react.d.ts, 166, 37))
|
||||
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
41
tests/baselines/reference/tsxGenericAttributesType9.types
Normal file
41
tests/baselines/reference/tsxGenericAttributesType9.types
Normal file
|
@ -0,0 +1,41 @@
|
|||
=== tests/cases/conformance/jsx/file.tsx ===
|
||||
import React = require('react');
|
||||
>React : typeof React
|
||||
|
||||
export function makeP<P>(Ctor: React.ComponentClass<P>): React.ComponentClass<P> {
|
||||
>makeP : <P>(Ctor: React.ComponentClass<P>) => React.ComponentClass<P>
|
||||
>P : P
|
||||
>Ctor : React.ComponentClass<P>
|
||||
>React : any
|
||||
>ComponentClass : React.ComponentClass<P>
|
||||
>P : P
|
||||
>React : any
|
||||
>ComponentClass : React.ComponentClass<P>
|
||||
>P : P
|
||||
|
||||
return class extends React.PureComponent<P, void> {
|
||||
>class extends React.PureComponent<P, void> { public render(): JSX.Element { return ( <Ctor {...this.props } /> ); } } : typeof (Anonymous class)
|
||||
>React.PureComponent : React.PureComponent<P, void>
|
||||
>React : typeof React
|
||||
>PureComponent : typeof React.PureComponent
|
||||
>P : P
|
||||
|
||||
public render(): JSX.Element {
|
||||
>render : () => JSX.Element
|
||||
>JSX : any
|
||||
>Element : JSX.Element
|
||||
|
||||
return (
|
||||
>( <Ctor {...this.props } /> ) : JSX.Element
|
||||
|
||||
<Ctor {...this.props } />
|
||||
><Ctor {...this.props } /> : JSX.Element
|
||||
>Ctor : React.ComponentClass<P>
|
||||
>this.props : P & { children?: React.ReactNode; }
|
||||
>this : this
|
||||
>props : P & { children?: React.ReactNode; }
|
||||
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
|
@ -21,8 +21,8 @@ var MainMenu: React.StatelessComponent<{}> = (props) => (<div>
|
|||
>MainMenu : React.StatelessComponent<{}>
|
||||
>React : any
|
||||
>StatelessComponent : React.StatelessComponent<P>
|
||||
>(props) => (<div> <h3>Main Menu</h3></div>) : (props: {}) => JSX.Element
|
||||
>props : {}
|
||||
>(props) => (<div> <h3>Main Menu</h3></div>) : (props: { children?: React.ReactNode; }) => JSX.Element
|
||||
>props : { children?: React.ReactNode; }
|
||||
>(<div> <h3>Main Menu</h3></div>) : JSX.Element
|
||||
><div> <h3>Main Menu</h3></div> : JSX.Element
|
||||
>div : any
|
||||
|
@ -40,7 +40,7 @@ var App: React.StatelessComponent<{ children }> = ({children}) => (
|
|||
>React : any
|
||||
>StatelessComponent : React.StatelessComponent<P>
|
||||
>children : any
|
||||
>({children}) => ( <div > <MainMenu/> </div>) : ({children}: { children: any; }) => JSX.Element
|
||||
>({children}) => ( <div > <MainMenu/> </div>) : ({children}: { children: any; } & { children?: React.ReactNode; }) => JSX.Element
|
||||
>children : any
|
||||
>( <div > <MainMenu/> </div>) : JSX.Element
|
||||
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
tests/cases/conformance/jsx/file.tsx(8,34): error TS2322: Type '{ ignore-prop: 10; prop: number; }' is not assignable to type 'IntrinsicAttributes & { prop: number; "ignore-prop": string; }'.
|
||||
Type '{ ignore-prop: 10; prop: number; }' is not assignable to type '{ prop: number; "ignore-prop": string; }'.
|
||||
tests/cases/conformance/jsx/file.tsx(8,34): error TS2322: Type 'T & { ignore-prop: 10; }' is not assignable to type 'IntrinsicAttributes & { prop: number; "ignore-prop": string; }'.
|
||||
Type 'T & { ignore-prop: 10; }' is not assignable to type '{ prop: number; "ignore-prop": string; }'.
|
||||
Types of property '"ignore-prop"' are incompatible.
|
||||
Type '10' is not assignable to type 'string'.
|
||||
tests/cases/conformance/jsx/file.tsx(13,34): error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & { prop: {}; "ignore-prop": string; }'.
|
||||
Type '{}' is not assignable to type '{ prop: {}; "ignore-prop": string; }'.
|
||||
Property 'prop' is missing in type '{}'.
|
||||
tests/cases/conformance/jsx/file.tsx(13,34): error TS2322: Type 'T' is not assignable to type 'IntrinsicAttributes & { prop: {}; "ignore-prop": string; }'.
|
||||
Type 'T' is not assignable to type '{ prop: {}; "ignore-prop": string; }'.
|
||||
tests/cases/conformance/jsx/file.tsx(20,19): error TS2322: Type '{ func: (a: number, b: string) => void; }' is not assignable to type 'IntrinsicAttributes & { func: (arg: number) => void; }'.
|
||||
Type '{ func: (a: number, b: string) => void; }' is not assignable to type '{ func: (arg: number) => void; }'.
|
||||
Types of property 'func' are incompatible.
|
||||
|
@ -25,8 +24,8 @@ tests/cases/conformance/jsx/file.tsx(31,10): error TS2453: The type argument for
|
|||
function Bar<T extends {prop: number}>(arg: T) {
|
||||
let a1 = <ComponentSpecific1 {...arg} ignore-prop={10} />;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ ignore-prop: 10; prop: number; }' is not assignable to type 'IntrinsicAttributes & { prop: number; "ignore-prop": string; }'.
|
||||
!!! error TS2322: Type '{ ignore-prop: 10; prop: number; }' is not assignable to type '{ prop: number; "ignore-prop": string; }'.
|
||||
!!! error TS2322: Type 'T & { ignore-prop: 10; }' is not assignable to type 'IntrinsicAttributes & { prop: number; "ignore-prop": string; }'.
|
||||
!!! error TS2322: Type 'T & { ignore-prop: 10; }' is not assignable to type '{ prop: number; "ignore-prop": string; }'.
|
||||
!!! error TS2322: Types of property '"ignore-prop"' are incompatible.
|
||||
!!! error TS2322: Type '10' is not assignable to type 'string'.
|
||||
}
|
||||
|
@ -35,9 +34,8 @@ tests/cases/conformance/jsx/file.tsx(31,10): error TS2453: The type argument for
|
|||
function Baz<T>(arg: T) {
|
||||
let a0 = <ComponentSpecific1 {...arg} />
|
||||
~~~~~~~~
|
||||
!!! error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & { prop: {}; "ignore-prop": string; }'.
|
||||
!!! error TS2322: Type '{}' is not assignable to type '{ prop: {}; "ignore-prop": string; }'.
|
||||
!!! error TS2322: Property 'prop' is missing in type '{}'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'IntrinsicAttributes & { prop: {}; "ignore-prop": string; }'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type '{ prop: {}; "ignore-prop": string; }'.
|
||||
}
|
||||
|
||||
declare function Link<U>(l: {func: (arg: U)=>void}): JSX.Element;
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
tests/cases/conformance/jsx/file.tsx(9,33): error TS2322: Type '{ a: number; }' is not assignable to type 'IntrinsicAttributes & { b: {}; a: number; }'.
|
||||
Type '{ a: number; }' is not assignable to type '{ b: {}; a: number; }'.
|
||||
Property 'b' is missing in type '{ a: number; }'.
|
||||
tests/cases/conformance/jsx/file.tsx(10,33): error TS2322: Type '{ b: number; }' is not assignable to type 'IntrinsicAttributes & { b: number; a: {}; }'.
|
||||
Type '{ b: number; }' is not assignable to type '{ b: number; a: {}; }'.
|
||||
Property 'a' is missing in type '{ b: number; }'.
|
||||
tests/cases/conformance/jsx/file.tsx(10,33): error TS2322: Type 'T' is not assignable to type 'IntrinsicAttributes & { b: number; a: {}; }'.
|
||||
Type '{ b: number; }' is not assignable to type 'IntrinsicAttributes & { b: number; a: {}; }'.
|
||||
Type '{ b: number; }' is not assignable to type '{ b: number; a: {}; }'.
|
||||
Type 'T' is not assignable to type '{ b: number; a: {}; }'.
|
||||
Type '{ b: number; }' is not assignable to type '{ b: number; a: {}; }'.
|
||||
Property 'a' is missing in type '{ b: number; }'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/jsx/file.tsx (2 errors) ====
|
||||
|
@ -22,7 +25,10 @@ tests/cases/conformance/jsx/file.tsx(10,33): error TS2322: Type '{ b: number; }'
|
|||
!!! error TS2322: Property 'b' is missing in type '{ a: number; }'.
|
||||
let a2 = <OverloadComponent {...arg1} ignore-prop /> // missing a
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ b: number; }' is not assignable to type 'IntrinsicAttributes & { b: number; a: {}; }'.
|
||||
!!! error TS2322: Type '{ b: number; }' is not assignable to type '{ b: number; a: {}; }'.
|
||||
!!! error TS2322: Property 'a' is missing in type '{ b: number; }'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'IntrinsicAttributes & { b: number; a: {}; }'.
|
||||
!!! error TS2322: Type '{ b: number; }' is not assignable to type 'IntrinsicAttributes & { b: number; a: {}; }'.
|
||||
!!! error TS2322: Type '{ b: number; }' is not assignable to type '{ b: number; a: {}; }'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type '{ b: number; a: {}; }'.
|
||||
!!! error TS2322: Type '{ b: number; }' is not assignable to type '{ b: number; a: {}; }'.
|
||||
!!! error TS2322: Property 'a' is missing in type '{ b: number; }'.
|
||||
}
|
|
@ -1,7 +1,11 @@
|
|||
tests/cases/conformance/jsx/file.tsx(15,14): error TS2605: JSX element type 'Element' is not a constructor function for JSX elements.
|
||||
Property 'render' is missing in type 'Element'.
|
||||
tests/cases/conformance/jsx/file.tsx(15,15): error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly.
|
||||
Type argument candidate 'number' is not a valid type argument because it is not a supertype of candidate '"hello"'.
|
||||
tests/cases/conformance/jsx/file.tsx(16,42): error TS2339: Property 'prop1' does not exist on type 'IntrinsicAttributes & { prop: number; }'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/jsx/file.tsx (1 errors) ====
|
||||
==== tests/cases/conformance/jsx/file.tsx (3 errors) ====
|
||||
import React = require('react')
|
||||
|
||||
declare function Component<U>(l: U): JSX.Element;
|
||||
|
@ -17,6 +21,12 @@ tests/cases/conformance/jsx/file.tsx(16,42): error TS2339: Property 'prop1' does
|
|||
let a1 = <ComponentSpecific {...arg} ignore-prop="hi" />; // U is number
|
||||
let a2 = <ComponentSpecific1 {...arg} ignore-prop={10} />; // U is number
|
||||
let a3 = <ComponentSpecific {...arg} prop="hello" />; // U is "hello"
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2605: JSX element type 'Element' is not a constructor function for JSX elements.
|
||||
!!! error TS2605: Property 'render' is missing in type 'Element'.
|
||||
~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly.
|
||||
!!! error TS2453: Type argument candidate 'number' is not a valid type argument because it is not a supertype of candidate '"hello"'.
|
||||
let a4 = <ComponentSpecific {...arg} prop1="hello" />; // U is "hello"
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2339: Property 'prop1' does not exist on type 'IntrinsicAttributes & { prop: number; }'.
|
||||
|
|
18
tests/cases/conformance/jsx/tsxGenericAttributesType1.tsx
Normal file
18
tests/cases/conformance/jsx/tsxGenericAttributesType1.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
// @filename: file.tsx
|
||||
// @jsx: preserve
|
||||
// @noLib: true
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
import React = require('react');
|
||||
|
||||
const decorator = function <T>(Component: React.StatelessComponent<T>): React.StatelessComponent<T> {
|
||||
return (props) => <Component {...props}></Component>
|
||||
};
|
||||
|
||||
const decorator2 = function <T extends { x: number }>(Component: React.StatelessComponent<T>): React.StatelessComponent<T> {
|
||||
return (props) => <Component {...props} x={2} ></Component>
|
||||
};
|
||||
|
||||
const decorator3 = function <T extends { x: number }, U extends { x: number } >(Component: React.StatelessComponent<T>): React.StatelessComponent<T> {
|
||||
return (props) => <Component x={2} {...props} ></Component>
|
||||
};
|
10
tests/cases/conformance/jsx/tsxGenericAttributesType2.tsx
Normal file
10
tests/cases/conformance/jsx/tsxGenericAttributesType2.tsx
Normal file
|
@ -0,0 +1,10 @@
|
|||
// @filename: file.tsx
|
||||
// @jsx: preserve
|
||||
// @noLib: true
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
import React = require('react');
|
||||
|
||||
const decorator4 = function <T extends { x: number }>(Component: React.StatelessComponent<T>): React.StatelessComponent<T> {
|
||||
return (props) => <Component {...props} y={"blah"} ></Component>
|
||||
};
|
17
tests/cases/conformance/jsx/tsxGenericAttributesType3.tsx
Normal file
17
tests/cases/conformance/jsx/tsxGenericAttributesType3.tsx
Normal file
|
@ -0,0 +1,17 @@
|
|||
// @filename: file.tsx
|
||||
// @jsx: preserve
|
||||
// @noLib: true
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
import React = require('react');
|
||||
|
||||
class B1<T extends { x: string } = { x:string } > extends React.Component<T, {}> {
|
||||
render() {
|
||||
return <div>hi</div>;
|
||||
}
|
||||
}
|
||||
class B<U> extends React.Component<U, {}> {
|
||||
render() {
|
||||
return <B1 {...this.props} x="hi" />;
|
||||
}
|
||||
}
|
18
tests/cases/conformance/jsx/tsxGenericAttributesType4.tsx
Normal file
18
tests/cases/conformance/jsx/tsxGenericAttributesType4.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
// @filename: file.tsx
|
||||
// @jsx: preserve
|
||||
// @noLib: true
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
import React = require('react');
|
||||
|
||||
class B1<T extends { x: string }> extends React.Component<T, {}> {
|
||||
render() {
|
||||
return <div>hi</div>;
|
||||
}
|
||||
}
|
||||
class B<U> extends React.Component<U, {}> {
|
||||
render() {
|
||||
// Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object
|
||||
return <B1 {...this.props} x="hi" />;
|
||||
}
|
||||
}
|
19
tests/cases/conformance/jsx/tsxGenericAttributesType5.tsx
Normal file
19
tests/cases/conformance/jsx/tsxGenericAttributesType5.tsx
Normal file
|
@ -0,0 +1,19 @@
|
|||
// @filename: file.tsx
|
||||
// @jsx: preserve
|
||||
// @noLib: true
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
import React = require('react');
|
||||
|
||||
class B1<T extends { x: string }> extends React.Component<T, {}> {
|
||||
render() {
|
||||
return <div>hi</div>;
|
||||
}
|
||||
}
|
||||
class B<U> extends React.Component<U, {}> {
|
||||
props: U;
|
||||
render() {
|
||||
// Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object
|
||||
return <B1 {...this.props} x="hi" />;
|
||||
}
|
||||
}
|
18
tests/cases/conformance/jsx/tsxGenericAttributesType6.tsx
Normal file
18
tests/cases/conformance/jsx/tsxGenericAttributesType6.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
// @filename: file.tsx
|
||||
// @jsx: preserve
|
||||
// @noLib: true
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
import React = require('react');
|
||||
|
||||
class B1<T extends { x: string } = { x:string } > extends React.Component<T, {}> {
|
||||
render() {
|
||||
return <div>hi</div>;
|
||||
}
|
||||
}
|
||||
class B<U> extends React.Component<U, {}> {
|
||||
props: U;
|
||||
render() {
|
||||
return <B1 {...this.props} x="hi" />;
|
||||
}
|
||||
}
|
15
tests/cases/conformance/jsx/tsxGenericAttributesType7.tsx
Normal file
15
tests/cases/conformance/jsx/tsxGenericAttributesType7.tsx
Normal file
|
@ -0,0 +1,15 @@
|
|||
// @filename: file.tsx
|
||||
// @jsx: preserve
|
||||
// @noLib: true
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
import React = require('react');
|
||||
|
||||
declare function Component<T>(props: T) : JSX.Element;
|
||||
const decorator = function <U>(props: U) {
|
||||
return <Component {...props} />;
|
||||
}
|
||||
|
||||
const decorator1 = function <U extends {x: string}>(props: U) {
|
||||
return <Component {...props} x="hi"/>;
|
||||
}
|
15
tests/cases/conformance/jsx/tsxGenericAttributesType8.tsx
Normal file
15
tests/cases/conformance/jsx/tsxGenericAttributesType8.tsx
Normal file
|
@ -0,0 +1,15 @@
|
|||
// @filename: file.tsx
|
||||
// @jsx: preserve
|
||||
// @noLib: true
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
import React = require('react');
|
||||
|
||||
declare function Component<T>(props: T) : JSX.Element;
|
||||
const decorator = function <U>(props: U) {
|
||||
return <Component {...props} />;
|
||||
}
|
||||
|
||||
const decorator1 = function <U extends {x: string}>(props: U) {
|
||||
return <Component {...props} />;
|
||||
}
|
16
tests/cases/conformance/jsx/tsxGenericAttributesType9.tsx
Normal file
16
tests/cases/conformance/jsx/tsxGenericAttributesType9.tsx
Normal file
|
@ -0,0 +1,16 @@
|
|||
// @filename: file.tsx
|
||||
// @jsx: preserve
|
||||
// @noLib: true
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
import React = require('react');
|
||||
|
||||
export function makeP<P>(Ctor: React.ComponentClass<P>): React.ComponentClass<P> {
|
||||
return class extends React.PureComponent<P, void> {
|
||||
public render(): JSX.Element {
|
||||
return (
|
||||
<Ctor {...this.props } />
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
256
tests/cases/fourslash/completionEntryForClassMembers.ts
Normal file
256
tests/cases/fourslash/completionEntryForClassMembers.ts
Normal file
|
@ -0,0 +1,256 @@
|
|||
///<reference path="fourslash.ts" />
|
||||
|
||||
////abstract class B {
|
||||
//// private privateMethod() { }
|
||||
//// protected protectedMethod() { };
|
||||
//// static staticMethod() { }
|
||||
//// abstract getValue(): number;
|
||||
//// /*abstractClass*/
|
||||
////}
|
||||
////class C extends B {
|
||||
//// /*classThatIsEmptyAndExtendingAnotherClass*/
|
||||
////}
|
||||
////class D extends B {
|
||||
//// /*classThatHasAlreadyImplementedAnotherClassMethod*/
|
||||
//// getValue() {
|
||||
//// return 10;
|
||||
//// }
|
||||
//// /*classThatHasAlreadyImplementedAnotherClassMethodAfterMethod*/
|
||||
////}
|
||||
////class D1 extends B {
|
||||
//// /*classThatHasDifferentMethodThanBase*/
|
||||
//// getValue1() {
|
||||
//// return 10;
|
||||
//// }
|
||||
//// /*classThatHasDifferentMethodThanBaseAfterMethod*/
|
||||
////}
|
||||
////class D2 extends B {
|
||||
//// /*classThatHasAlreadyImplementedAnotherClassProtectedMethod*/
|
||||
//// protectedMethod() {
|
||||
//// }
|
||||
//// /*classThatHasDifferentMethodThanBaseAfterProtectedMethod*/
|
||||
////}
|
||||
////class D3 extends D1 {
|
||||
//// /*classThatExtendsClassExtendingAnotherClass*/
|
||||
////}
|
||||
////class D4 extends D1 {
|
||||
//// static /*classThatExtendsClassExtendingAnotherClassAndTypesStatic*/
|
||||
////}
|
||||
////class D5 extends D2 {
|
||||
//// /*classThatExtendsClassExtendingAnotherClassWithOverridingMember*/
|
||||
////}
|
||||
////class D6 extends D2 {
|
||||
//// static /*classThatExtendsClassExtendingAnotherClassWithOverridingMemberAndTypesStatic*/
|
||||
////}
|
||||
////class E {
|
||||
//// /*classThatDoesNotExtendAnotherClass*/
|
||||
////}
|
||||
////class F extends B {
|
||||
//// public /*classThatHasWrittenPublicKeyword*/
|
||||
////}
|
||||
////class F2 extends B {
|
||||
//// private /*classThatHasWrittenPrivateKeyword*/
|
||||
////}
|
||||
////class G extends B {
|
||||
//// static /*classElementContainingStatic*/
|
||||
////}
|
||||
////class G2 extends B {
|
||||
//// private static /*classElementContainingPrivateStatic*/
|
||||
////}
|
||||
////class H extends B {
|
||||
//// prop/*classThatStartedWritingIdentifier*/
|
||||
////}
|
||||
//////Class for location verification
|
||||
////class I extends B {
|
||||
//// prop0: number
|
||||
//// /*propDeclarationWithoutSemicolon*/
|
||||
//// prop: number;
|
||||
//// /*propDeclarationWithSemicolon*/
|
||||
//// prop1 = 10;
|
||||
//// /*propAssignmentWithSemicolon*/
|
||||
//// prop2 = 10
|
||||
//// /*propAssignmentWithoutSemicolon*/
|
||||
//// method(): number
|
||||
//// /*methodSignatureWithoutSemicolon*/
|
||||
//// method2(): number;
|
||||
//// /*methodSignatureWithSemicolon*/
|
||||
//// method3() {
|
||||
//// /*InsideMethod*/
|
||||
//// }
|
||||
//// /*methodImplementation*/
|
||||
//// get c()
|
||||
//// /*accessorSignatureWithoutSemicolon*/
|
||||
//// set c()
|
||||
//// {
|
||||
//// }
|
||||
//// /*accessorSignatureImplementation*/
|
||||
////}
|
||||
////class J extends B {
|
||||
//// get /*classThatHasWrittenGetKeyword*/
|
||||
////}
|
||||
////class K extends B {
|
||||
//// set /*classThatHasWrittenSetKeyword*/
|
||||
////}
|
||||
////class J extends B {
|
||||
//// get identi/*classThatStartedWritingIdentifierOfGetAccessor*/
|
||||
////}
|
||||
////class K extends B {
|
||||
//// set identi/*classThatStartedWritingIdentifierOfSetAccessor*/
|
||||
////}
|
||||
////class L extends B {
|
||||
//// public identi/*classThatStartedWritingIdentifierAfterModifier*/
|
||||
////}
|
||||
////class L2 extends B {
|
||||
//// private identi/*classThatStartedWritingIdentifierAfterPrivateModifier*/
|
||||
////}
|
||||
////class M extends B {
|
||||
//// static identi/*classThatStartedWritingIdentifierAfterStaticModifier*/
|
||||
////}
|
||||
////class M extends B {
|
||||
//// private static identi/*classThatStartedWritingIdentifierAfterPrivateStaticModifier*/
|
||||
////}
|
||||
////class N extends B {
|
||||
//// async /*classThatHasWrittenAsyncKeyword*/
|
||||
////}
|
||||
|
||||
const allowedKeywordCount = verify.allowedClassElementKeywords.length;
|
||||
type CompletionInfo = [string, string];
|
||||
type CompletionInfoVerifier = { validMembers: CompletionInfo[], invalidMembers: CompletionInfo[] };
|
||||
|
||||
function verifyClassElementLocations({ validMembers, invalidMembers }: CompletionInfoVerifier, classElementCompletionLocations: string[]) {
|
||||
for (const marker of classElementCompletionLocations) {
|
||||
goTo.marker(marker);
|
||||
verifyCompletionInfo(validMembers, verify);
|
||||
verifyCompletionInfo(invalidMembers, verify.not);
|
||||
verify.completionListContainsClassElementKeywords();
|
||||
verify.completionListCount(allowedKeywordCount + validMembers.length);
|
||||
}
|
||||
}
|
||||
|
||||
function verifyCompletionInfo(memberInfo: CompletionInfo[], verify: FourSlashInterface.verifyNegatable) {
|
||||
for (const [symbol, text] of memberInfo) {
|
||||
verify.completionListContains(symbol, text, /*documentation*/ undefined, "method");
|
||||
}
|
||||
}
|
||||
|
||||
const allMembersOfBase: CompletionInfo[] = [
|
||||
["getValue", "(method) B.getValue(): number"],
|
||||
["protectedMethod", "(method) B.protectedMethod(): void"],
|
||||
["privateMethod", "(method) B.privateMethod(): void"],
|
||||
["staticMethod", "(method) B.staticMethod(): void"]
|
||||
];
|
||||
const publicCompletionInfoOfD1: CompletionInfo[] = [
|
||||
["getValue1", "(method) D1.getValue1(): number"]
|
||||
];
|
||||
const publicCompletionInfoOfD2: CompletionInfo[] = [
|
||||
["protectedMethod", "(method) D2.protectedMethod(): void"]
|
||||
];
|
||||
function filterCompletionInfo(fn: (a: CompletionInfo) => boolean): CompletionInfoVerifier {
|
||||
const validMembers: CompletionInfo[] = [];
|
||||
const invalidMembers: CompletionInfo[] = [];
|
||||
for (const member of allMembersOfBase) {
|
||||
if (fn(member)) {
|
||||
validMembers.push(member);
|
||||
}
|
||||
else {
|
||||
invalidMembers.push(member);
|
||||
}
|
||||
}
|
||||
return { validMembers, invalidMembers };
|
||||
}
|
||||
|
||||
|
||||
const instanceMemberInfo = filterCompletionInfo(([a]: CompletionInfo) => a === "getValue" || a === "protectedMethod");
|
||||
const staticMemberInfo = filterCompletionInfo(([a]: CompletionInfo) => a === "staticMethod");
|
||||
const instanceWithoutProtectedMemberInfo = filterCompletionInfo(([a]: CompletionInfo) => a === "getValue");
|
||||
const instanceWithoutPublicMemberInfo = filterCompletionInfo(([a]: CompletionInfo) => a === "protectedMethod");
|
||||
|
||||
const instanceMemberInfoD1: CompletionInfoVerifier = {
|
||||
validMembers: instanceMemberInfo.validMembers.concat(publicCompletionInfoOfD1),
|
||||
invalidMembers: instanceMemberInfo.invalidMembers
|
||||
};
|
||||
const instanceMemberInfoD2: CompletionInfoVerifier = {
|
||||
validMembers: instanceWithoutProtectedMemberInfo.validMembers.concat(publicCompletionInfoOfD2),
|
||||
invalidMembers: instanceWithoutProtectedMemberInfo.invalidMembers
|
||||
};
|
||||
const staticMemberInfoDn: CompletionInfoVerifier = {
|
||||
validMembers: staticMemberInfo.validMembers,
|
||||
invalidMembers: staticMemberInfo.invalidMembers.concat(publicCompletionInfoOfD1, publicCompletionInfoOfD2)
|
||||
};
|
||||
|
||||
// Not a class element declaration location
|
||||
const nonClassElementMarkers = [
|
||||
"InsideMethod"
|
||||
];
|
||||
for (const marker of nonClassElementMarkers) {
|
||||
goTo.marker(marker);
|
||||
verifyCompletionInfo(allMembersOfBase, verify.not);
|
||||
verify.not.completionListIsEmpty();
|
||||
}
|
||||
|
||||
// Only keywords allowed at this position since they dont extend the class or are private
|
||||
const onlyClassElementKeywordLocations = [
|
||||
"abstractClass",
|
||||
"classThatDoesNotExtendAnotherClass",
|
||||
"classThatHasWrittenPrivateKeyword",
|
||||
"classElementContainingPrivateStatic",
|
||||
"classThatStartedWritingIdentifierAfterPrivateModifier",
|
||||
"classThatStartedWritingIdentifierAfterPrivateStaticModifier"
|
||||
];
|
||||
verifyClassElementLocations({ validMembers: [], invalidMembers: allMembersOfBase }, onlyClassElementKeywordLocations);
|
||||
|
||||
// Instance base members and class member keywords allowed
|
||||
const classInstanceElementLocations = [
|
||||
"classThatIsEmptyAndExtendingAnotherClass",
|
||||
"classThatHasDifferentMethodThanBase",
|
||||
"classThatHasDifferentMethodThanBaseAfterMethod",
|
||||
"classThatHasWrittenPublicKeyword",
|
||||
"classThatStartedWritingIdentifier",
|
||||
"propDeclarationWithoutSemicolon",
|
||||
"propDeclarationWithSemicolon",
|
||||
"propAssignmentWithSemicolon",
|
||||
"propAssignmentWithoutSemicolon",
|
||||
"methodSignatureWithoutSemicolon",
|
||||
"methodSignatureWithSemicolon",
|
||||
"methodImplementation",
|
||||
"accessorSignatureWithoutSemicolon",
|
||||
"accessorSignatureImplementation",
|
||||
"classThatHasWrittenGetKeyword",
|
||||
"classThatHasWrittenSetKeyword",
|
||||
"classThatStartedWritingIdentifierOfGetAccessor",
|
||||
"classThatStartedWritingIdentifierOfSetAccessor",
|
||||
"classThatStartedWritingIdentifierAfterModifier",
|
||||
"classThatHasWrittenAsyncKeyword"
|
||||
];
|
||||
verifyClassElementLocations(instanceMemberInfo, classInstanceElementLocations);
|
||||
|
||||
// Static Base members and class member keywords allowed
|
||||
const staticClassLocations = [
|
||||
"classElementContainingStatic",
|
||||
"classThatStartedWritingIdentifierAfterStaticModifier"
|
||||
];
|
||||
verifyClassElementLocations(staticMemberInfo, staticClassLocations);
|
||||
|
||||
const classInstanceElementWithoutPublicMethodLocations = [
|
||||
"classThatHasAlreadyImplementedAnotherClassMethod",
|
||||
"classThatHasAlreadyImplementedAnotherClassMethodAfterMethod",
|
||||
];
|
||||
verifyClassElementLocations(instanceWithoutPublicMemberInfo, classInstanceElementWithoutPublicMethodLocations);
|
||||
|
||||
const classInstanceElementWithoutProtectedMethodLocations = [
|
||||
"classThatHasAlreadyImplementedAnotherClassProtectedMethod",
|
||||
"classThatHasDifferentMethodThanBaseAfterProtectedMethod",
|
||||
];
|
||||
verifyClassElementLocations(instanceWithoutProtectedMemberInfo, classInstanceElementWithoutProtectedMethodLocations);
|
||||
|
||||
// instance memebers in D1 and base class are shown
|
||||
verifyClassElementLocations(instanceMemberInfoD1, ["classThatExtendsClassExtendingAnotherClass"]);
|
||||
|
||||
// instance memebers in D2 and base class are shown
|
||||
verifyClassElementLocations(instanceMemberInfoD2, ["classThatExtendsClassExtendingAnotherClassWithOverridingMember"]);
|
||||
|
||||
// static base members and class member keywords allowed
|
||||
verifyClassElementLocations(staticMemberInfoDn, [
|
||||
"classThatExtendsClassExtendingAnotherClassAndTypesStatic",
|
||||
"classThatExtendsClassExtendingAnotherClassWithOverridingMemberAndTypesStatic"
|
||||
]);
|
456
tests/cases/fourslash/completionEntryForClassMembers2.ts
Normal file
456
tests/cases/fourslash/completionEntryForClassMembers2.ts
Normal file
|
@ -0,0 +1,456 @@
|
|||
///<reference path="fourslash.ts" />
|
||||
|
||||
////interface I {
|
||||
//// methodOfInterface(): number;
|
||||
////}
|
||||
////interface I2 {
|
||||
//// methodOfInterface2(): number;
|
||||
////}
|
||||
////interface I3 {
|
||||
//// getValue(): string;
|
||||
//// method(): string;
|
||||
////}
|
||||
////interface I4 {
|
||||
//// staticMethod(): void;
|
||||
//// method(): string;
|
||||
////}
|
||||
////class B0 {
|
||||
//// private privateMethod() { }
|
||||
//// protected protectedMethod() { }
|
||||
//// static staticMethod() { }
|
||||
//// getValue(): string | boolean { return "hello"; }
|
||||
//// private privateMethod1() { }
|
||||
//// protected protectedMethod1() { }
|
||||
//// static staticMethod1() { }
|
||||
//// getValue1(): string | boolean { return "hello"; }
|
||||
////}
|
||||
////interface I5 extends B0 {
|
||||
//// methodOfInterface5(): number;
|
||||
////}
|
||||
////interface I6 extends B0 {
|
||||
//// methodOfInterface6(): number;
|
||||
//// staticMethod(): void;
|
||||
////}
|
||||
////interface I7 extends I {
|
||||
//// methodOfInterface7(): number;
|
||||
////}
|
||||
////class B {
|
||||
//// private privateMethod() { }
|
||||
//// protected protectedMethod() { }
|
||||
//// static staticMethod() { }
|
||||
//// getValue(): string | boolean { return "hello"; }
|
||||
////}
|
||||
////class C0 implements I, I2 {
|
||||
//// /*implementsIAndI2*/
|
||||
////}
|
||||
////class C00 implements I, I2 {
|
||||
//// static /*implementsIAndI2AndWritingStatic*/
|
||||
////}
|
||||
////class C001 implements I, I2 {
|
||||
//// methodOfInterface/*implementsIAndI2AndWritingMethodNameOfI*/
|
||||
////}
|
||||
////class C extends B implements I, I2 {
|
||||
//// /*extendsBAndImplementsIAndI2*/
|
||||
////}
|
||||
////class C1 extends B implements I, I2 {
|
||||
//// static /*extendsBAndImplementsIAndI2AndWritingStatic*/
|
||||
////}
|
||||
////class D extends B implements I, I2 {
|
||||
//// /*extendsBAndImplementsIAndI2WithMethodFromB*/
|
||||
//// protected protectedMethod() {
|
||||
//// return "protected";
|
||||
//// }
|
||||
////}
|
||||
////class E extends B implements I, I2 {
|
||||
//// /*extendsBAndImplementsIAndI2WithMethodFromI*/
|
||||
//// methodOfInterface() {
|
||||
//// return 1;
|
||||
//// }
|
||||
////}
|
||||
////class F extends B implements I, I2 {
|
||||
//// /*extendsBAndImplementsIAndI2WithMethodFromBAndI*/
|
||||
//// protected protectedMethod() {
|
||||
//// return "protected"
|
||||
//// }
|
||||
//// methodOfInterface() {
|
||||
//// return 1;
|
||||
//// }
|
||||
////}
|
||||
////class F2 extends B implements I, I2 {
|
||||
//// protected protectedMethod() {
|
||||
//// return "protected"
|
||||
//// }
|
||||
//// methodOfInterface() {
|
||||
//// return 1;
|
||||
//// }
|
||||
//// static /*extendsBAndImplementsIAndI2WithMethodFromBAndIAndTypesStatic*/
|
||||
////}
|
||||
////class G extends B implements I3 {
|
||||
//// /*extendsBAndImplementsI3WithSameNameMembers*/
|
||||
////}
|
||||
////class H extends B implements I3 {
|
||||
//// /*extendsBAndImplementsI3WithSameNameMembersAndHasImplementedTheMember*/
|
||||
//// getValue() {
|
||||
//// return "hello";
|
||||
//// }
|
||||
////}
|
||||
////class J extends B0 implements I4 {
|
||||
//// /*extendsB0ThatExtendsAndImplementsI4WithStaticMethod*/
|
||||
////}
|
||||
////class L extends B0 implements I4 {
|
||||
//// /*extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedAnotherMethod*/
|
||||
//// staticMethod2() {
|
||||
//// return "hello";
|
||||
//// }
|
||||
////}
|
||||
////class K extends B0 implements I4 {
|
||||
//// /*extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedThatMethod*/
|
||||
//// staticMethod() {
|
||||
//// return "hello";
|
||||
//// }
|
||||
////}
|
||||
////class M extends B0 implements I4 {
|
||||
//// /*extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedThatMethodAsStatic*/
|
||||
//// static staticMethod() {
|
||||
//// return "hello";
|
||||
//// }
|
||||
////}
|
||||
////class N extends B0 implements I4 {
|
||||
//// /*extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedThatMethodAsBoth*/
|
||||
//// staticMethod() {
|
||||
//// return "hello";
|
||||
//// }
|
||||
//// static staticMethod() {
|
||||
//// return "hello";
|
||||
//// }
|
||||
////}
|
||||
////class J1 extends B0 implements I4 {
|
||||
//// static /*extendsB0ThatExtendsAndImplementsI4WithStaticMethodWritingStatic*/
|
||||
////}
|
||||
////class L1 extends B0 implements I4 {
|
||||
//// staticMethod2() {
|
||||
//// return "hello";
|
||||
//// }
|
||||
//// static /*extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedAnotherMethodWritingStatic*/
|
||||
////}
|
||||
////class K1 extends B0 implements I4 {
|
||||
//// staticMethod() {
|
||||
//// return "hello";
|
||||
//// }
|
||||
//// static /*extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedThatMethodWritingStatic*/
|
||||
////}
|
||||
////class M1 extends B0 implements I4 {
|
||||
//// static staticMethod() {
|
||||
//// return "hello";
|
||||
//// }
|
||||
//// static /*extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedThatMethodAsStaticWritingStatic*/
|
||||
////}
|
||||
////class N1 extends B0 implements I4 {
|
||||
//// staticMethod() {
|
||||
//// return "hello";
|
||||
//// }
|
||||
//// static staticMethod() {
|
||||
//// return "hello";
|
||||
//// }
|
||||
//// static /*extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedThatMethodAsBothWritingStatic*/
|
||||
////}
|
||||
////class O implements I7 {
|
||||
//// /*implementsI7whichExtendsI*/
|
||||
////}
|
||||
////class P implements I7, I {
|
||||
//// /*implementsI7whichExtendsIAndAlsoImplementsI*/
|
||||
////}
|
||||
////class Q implements I, I7 {
|
||||
//// /*implementsIAndAlsoImplementsI7whichExtendsI*/
|
||||
////}
|
||||
////class R implements I5 {
|
||||
//// /*implementsI5ThatExtendsB0*/
|
||||
////}
|
||||
////class S implements I6 {
|
||||
//// /*implementsI6ThatExtendsB0AndHasStaticMethodOfB0*/
|
||||
////}
|
||||
////class T extends B0 implements I5 {
|
||||
//// /*extendsB0AndImplementsI5ThatExtendsB0*/
|
||||
////}
|
||||
////class U extends B0 implements I6 {
|
||||
//// /*extendsB0AndImplementsI6ThatExtendsB0AndHasStaticMethodOfB0*/
|
||||
////}
|
||||
////class R1 implements I5 {
|
||||
//// static /*implementsI5ThatExtendsB0TypesStatic*/
|
||||
////}
|
||||
////class S1 implements I6 {
|
||||
//// static /*implementsI6ThatExtendsB0AndHasStaticMethodOfB0TypesStatic*/
|
||||
////}
|
||||
////class T1 extends B0 implements I5 {
|
||||
//// static /*extendsB0AndImplementsI5ThatExtendsB0TypesStatic*/
|
||||
////}
|
||||
////class U1 extends B0 implements I6 {
|
||||
//// static /*extendsB0AndImplementsI6ThatExtendsB0AndHasStaticMethodOfB0TypesStatic*/
|
||||
////}
|
||||
|
||||
const allowedKeywordCount = verify.allowedClassElementKeywords.length;
|
||||
type CompletionInfo = [string, string];
|
||||
type CompletionInfoVerifier = { validMembers: CompletionInfo[], invalidMembers: CompletionInfo[] };
|
||||
|
||||
function verifyClassElementLocations({ validMembers, invalidMembers }: CompletionInfoVerifier, classElementCompletionLocations: string[]) {
|
||||
for (const marker of classElementCompletionLocations) {
|
||||
goTo.marker(marker);
|
||||
verifyCompletionInfo(validMembers, verify);
|
||||
verifyCompletionInfo(invalidMembers, verify.not);
|
||||
verify.completionListContainsClassElementKeywords();
|
||||
verify.completionListCount(allowedKeywordCount + validMembers.length);
|
||||
}
|
||||
}
|
||||
|
||||
function verifyCompletionInfo(memberInfo: CompletionInfo[], verify: FourSlashInterface.verifyNegatable) {
|
||||
for (const [symbol, text] of memberInfo) {
|
||||
verify.completionListContains(symbol, text, /*documentation*/ undefined, "method");
|
||||
}
|
||||
}
|
||||
|
||||
const validInstanceMembersOfBaseClassB: CompletionInfo[] = [
|
||||
["getValue", "(method) B.getValue(): string | boolean"],
|
||||
["protectedMethod", "(method) B.protectedMethod(): void"],
|
||||
];
|
||||
const validStaticMembersOfBaseClassB: CompletionInfo[] = [
|
||||
["staticMethod", "(method) B.staticMethod(): void"]
|
||||
];
|
||||
const privateMembersOfBaseClassB: CompletionInfo[] = [
|
||||
["privateMethod", "(method) B.privateMethod(): void"],
|
||||
];
|
||||
const protectedPropertiesOfBaseClassB0: CompletionInfo[] = [
|
||||
["protectedMethod", "(method) B0.protectedMethod(): void"],
|
||||
["protectedMethod1", "(method) B0.protectedMethod1(): void"],
|
||||
];
|
||||
const publicPropertiesOfBaseClassB0: CompletionInfo[] = [
|
||||
["getValue", "(method) B0.getValue(): string | boolean"],
|
||||
["getValue1", "(method) B0.getValue1(): string | boolean"],
|
||||
];
|
||||
const validInstanceMembersOfBaseClassB0: CompletionInfo[] = protectedPropertiesOfBaseClassB0.concat(publicPropertiesOfBaseClassB0);
|
||||
const validStaticMembersOfBaseClassB0: CompletionInfo[] = [
|
||||
["staticMethod", "(method) B0.staticMethod(): void"],
|
||||
["staticMethod1", "(method) B0.staticMethod1(): void"]
|
||||
];
|
||||
const privateMembersOfBaseClassB0: CompletionInfo[] = [
|
||||
["privateMethod", "(method) B0.privateMethod(): void"],
|
||||
["privateMethod1", "(method) B0.privateMethod1(): void"],
|
||||
];
|
||||
const membersOfI: CompletionInfo[] = [
|
||||
["methodOfInterface", "(method) I.methodOfInterface(): number"],
|
||||
];
|
||||
const membersOfI2: CompletionInfo[] = [
|
||||
["methodOfInterface2", "(method) I2.methodOfInterface2(): number"],
|
||||
];
|
||||
const membersOfI3: CompletionInfo[] = [
|
||||
["getValue", "(method) I3.getValue(): string"],
|
||||
["method", "(method) I3.method(): string"],
|
||||
];
|
||||
const membersOfI4: CompletionInfo[] = [
|
||||
["staticMethod", "(method) I4.staticMethod(): void"],
|
||||
["method", "(method) I4.method(): string"],
|
||||
];
|
||||
const membersOfI5: CompletionInfo[] = publicPropertiesOfBaseClassB0.concat([
|
||||
["methodOfInterface5", "(method) I5.methodOfInterface5(): number"]
|
||||
]);
|
||||
const membersOfI6: CompletionInfo[] = publicPropertiesOfBaseClassB0.concat([
|
||||
["staticMethod", "(method) I6.staticMethod(): void"],
|
||||
["methodOfInterface6", "(method) I6.methodOfInterface6(): number"]
|
||||
]);
|
||||
const membersOfI7: CompletionInfo[] = membersOfI.concat([
|
||||
["methodOfInterface7", "(method) I7.methodOfInterface7(): number"]
|
||||
]);
|
||||
|
||||
function getCompletionInfoVerifier(
|
||||
validMembers: CompletionInfo[],
|
||||
invalidMembers: CompletionInfo[],
|
||||
arrayToDistribute: CompletionInfo[],
|
||||
isValidDistributionCriteria: (v: CompletionInfo) => boolean): CompletionInfoVerifier {
|
||||
if (arrayToDistribute) {
|
||||
validMembers = validMembers.concat(arrayToDistribute.filter(isValidDistributionCriteria));
|
||||
invalidMembers = invalidMembers.concat(arrayToDistribute.filter(v => !isValidDistributionCriteria(v)));
|
||||
}
|
||||
return {
|
||||
validMembers,
|
||||
invalidMembers
|
||||
}
|
||||
}
|
||||
|
||||
const noMembers: CompletionInfo[] = [];
|
||||
const membersOfIAndI2 = membersOfI.concat(membersOfI2);
|
||||
const invalidMembersOfBAtInstanceLocation = privateMembersOfBaseClassB.concat(validStaticMembersOfBaseClassB);
|
||||
|
||||
// members of I and I2
|
||||
verifyClassElementLocations({ validMembers: membersOfIAndI2, invalidMembers: noMembers }, [
|
||||
"implementsIAndI2",
|
||||
"implementsIAndI2AndWritingMethodNameOfI"
|
||||
]);
|
||||
|
||||
// Static location so no members of I and I2
|
||||
verifyClassElementLocations({ validMembers: noMembers, invalidMembers: membersOfIAndI2 },
|
||||
["implementsIAndI2AndWritingStatic"]);
|
||||
|
||||
const allInstanceBAndIAndI2 = membersOfIAndI2.concat(validInstanceMembersOfBaseClassB);
|
||||
// members of instance B, I and I2
|
||||
verifyClassElementLocations({
|
||||
validMembers: allInstanceBAndIAndI2,
|
||||
invalidMembers: invalidMembersOfBAtInstanceLocation
|
||||
}, ["extendsBAndImplementsIAndI2"]);
|
||||
|
||||
// static location so only static members of B and no members of instance B, I and I2
|
||||
verifyClassElementLocations({
|
||||
validMembers: validStaticMembersOfBaseClassB,
|
||||
invalidMembers: privateMembersOfBaseClassB.concat(allInstanceBAndIAndI2)
|
||||
}, [
|
||||
"extendsBAndImplementsIAndI2AndWritingStatic",
|
||||
"extendsBAndImplementsIAndI2WithMethodFromBAndIAndTypesStatic"
|
||||
]);
|
||||
|
||||
// instance members of B without protectedMethod, I and I2
|
||||
verifyClassElementLocations(
|
||||
getCompletionInfoVerifier(
|
||||
/*validMembers*/ membersOfIAndI2,
|
||||
/*invalidMembers*/ invalidMembersOfBAtInstanceLocation,
|
||||
/*arrayToDistribute*/ validInstanceMembersOfBaseClassB,
|
||||
value => value[0] !== "protectedMethod"),
|
||||
["extendsBAndImplementsIAndI2WithMethodFromB"]);
|
||||
|
||||
// instance members of B, members of T without methodOfInterface and I2
|
||||
verifyClassElementLocations(
|
||||
getCompletionInfoVerifier(
|
||||
/*validMembers*/ membersOfI2.concat(validInstanceMembersOfBaseClassB),
|
||||
/*invalidMembers*/ invalidMembersOfBAtInstanceLocation,
|
||||
/*arrayToDistribute*/ membersOfI,
|
||||
value => value[0] !== "methodOfInterface"),
|
||||
["extendsBAndImplementsIAndI2WithMethodFromI"]);
|
||||
|
||||
// instance members of B without protectedMethod, members of T without methodOfInterface and I2
|
||||
verifyClassElementLocations(
|
||||
getCompletionInfoVerifier(
|
||||
/*validMembers*/ membersOfI2,
|
||||
/*invalidMembers*/ invalidMembersOfBAtInstanceLocation,
|
||||
/*arrayToDistribute*/ membersOfI.concat(validInstanceMembersOfBaseClassB),
|
||||
value => value[0] !== "methodOfInterface" && value[0] !== "protectedMethod"),
|
||||
["extendsBAndImplementsIAndI2WithMethodFromBAndI"]);
|
||||
|
||||
// members of B and members of I3 that are not same as name of method in B
|
||||
verifyClassElementLocations(
|
||||
getCompletionInfoVerifier(
|
||||
/*validMembers*/ validInstanceMembersOfBaseClassB,
|
||||
/*invalidMembers*/ invalidMembersOfBAtInstanceLocation,
|
||||
/*arrayToDistribute*/ membersOfI3,
|
||||
value => value[0] !== "getValue"),
|
||||
["extendsBAndImplementsI3WithSameNameMembers"]);
|
||||
|
||||
// members of B (without getValue since its implemented) and members of I3 that are not same as name of method in B
|
||||
verifyClassElementLocations(
|
||||
getCompletionInfoVerifier(
|
||||
/*validMembers*/ noMembers,
|
||||
/*invalidMembers*/ invalidMembersOfBAtInstanceLocation,
|
||||
/*arrayToDistribute*/ membersOfI3.concat(validInstanceMembersOfBaseClassB),
|
||||
value => value[0] !== "getValue"),
|
||||
["extendsBAndImplementsI3WithSameNameMembersAndHasImplementedTheMember"]);
|
||||
|
||||
const invalidMembersOfB0AtInstanceSide = privateMembersOfBaseClassB0.concat(validStaticMembersOfBaseClassB0);
|
||||
const invalidMembersOfB0AtStaticSide = privateMembersOfBaseClassB0.concat(validInstanceMembersOfBaseClassB0);
|
||||
// members of B0 and members of I4
|
||||
verifyClassElementLocations({
|
||||
validMembers: validInstanceMembersOfBaseClassB0.concat(membersOfI4),
|
||||
invalidMembers: invalidMembersOfB0AtInstanceSide
|
||||
}, [
|
||||
"extendsB0ThatExtendsAndImplementsI4WithStaticMethod",
|
||||
"extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedAnotherMethod",
|
||||
"extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedThatMethodAsStatic"
|
||||
]);
|
||||
|
||||
// members of B0 and members of I4 that are not staticMethod
|
||||
verifyClassElementLocations(
|
||||
getCompletionInfoVerifier(
|
||||
/*validMembers*/ validInstanceMembersOfBaseClassB0,
|
||||
/*invalidMembers*/ invalidMembersOfB0AtInstanceSide,
|
||||
/*arrayToDistribute*/ membersOfI4,
|
||||
value => value[0] !== "staticMethod"
|
||||
), [
|
||||
"extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedThatMethod",
|
||||
"extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedThatMethodAsBoth"
|
||||
]);
|
||||
|
||||
// static members of B0
|
||||
verifyClassElementLocations({
|
||||
validMembers: validStaticMembersOfBaseClassB0,
|
||||
invalidMembers: invalidMembersOfB0AtStaticSide.concat(membersOfI4)
|
||||
}, [
|
||||
"extendsB0ThatExtendsAndImplementsI4WithStaticMethodWritingStatic",
|
||||
"extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedAnotherMethodWritingStatic",
|
||||
"extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedThatMethodWritingStatic"
|
||||
]);
|
||||
|
||||
// static members of B0 without staticMethod
|
||||
verifyClassElementLocations(
|
||||
getCompletionInfoVerifier(
|
||||
/*validMembers*/ noMembers,
|
||||
/*invalidMembers*/ invalidMembersOfB0AtStaticSide.concat(membersOfI4),
|
||||
/*arrayToDistribute*/ validStaticMembersOfBaseClassB0,
|
||||
value => value[0] !== "staticMethod"
|
||||
), [
|
||||
"extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedThatMethodAsStaticWritingStatic",
|
||||
"extendsB0ThatExtendsAndImplementsI4WithStaticMethodAndImplementedThatMethodAsBothWritingStatic"
|
||||
]);
|
||||
|
||||
// members of I7 extends I
|
||||
verifyClassElementLocations({ validMembers: membersOfI7, invalidMembers: noMembers }, [
|
||||
"implementsI7whichExtendsI",
|
||||
"implementsI7whichExtendsIAndAlsoImplementsI",
|
||||
"implementsIAndAlsoImplementsI7whichExtendsI"
|
||||
]);
|
||||
|
||||
const invalidMembersOfB0AtInstanceSideFromInterfaceExtendingB0 = invalidMembersOfB0AtInstanceSide
|
||||
.concat(protectedPropertiesOfBaseClassB0);
|
||||
// members of I5 extends B0
|
||||
verifyClassElementLocations({
|
||||
validMembers: membersOfI5,
|
||||
invalidMembers: invalidMembersOfB0AtInstanceSideFromInterfaceExtendingB0
|
||||
}, [
|
||||
"implementsI5ThatExtendsB0",
|
||||
]);
|
||||
|
||||
// members of I6 extends B0
|
||||
verifyClassElementLocations({
|
||||
validMembers: membersOfI6,
|
||||
invalidMembers: invalidMembersOfB0AtInstanceSideFromInterfaceExtendingB0
|
||||
}, [
|
||||
"implementsI6ThatExtendsB0AndHasStaticMethodOfB0",
|
||||
]);
|
||||
|
||||
// members of B0 and I5 that extends B0
|
||||
verifyClassElementLocations({
|
||||
validMembers: membersOfI5.concat(protectedPropertiesOfBaseClassB0),
|
||||
invalidMembers: invalidMembersOfB0AtInstanceSide
|
||||
}, [
|
||||
"extendsB0AndImplementsI5ThatExtendsB0"
|
||||
]);
|
||||
|
||||
// members of B0 and I6 that extends B0
|
||||
verifyClassElementLocations({
|
||||
validMembers: membersOfI6.concat(protectedPropertiesOfBaseClassB0),
|
||||
invalidMembers: invalidMembersOfB0AtInstanceSide
|
||||
}, [
|
||||
"extendsB0AndImplementsI6ThatExtendsB0AndHasStaticMethodOfB0"
|
||||
]);
|
||||
|
||||
// nothing on static side as these do not extend any other class
|
||||
verifyClassElementLocations({
|
||||
validMembers: [],
|
||||
invalidMembers: membersOfI5.concat(membersOfI6, invalidMembersOfB0AtStaticSide)
|
||||
}, [
|
||||
"implementsI5ThatExtendsB0TypesStatic",
|
||||
"implementsI6ThatExtendsB0AndHasStaticMethodOfB0TypesStatic"
|
||||
]);
|
||||
|
||||
// statics of base B but nothing from instance side
|
||||
verifyClassElementLocations({
|
||||
validMembers: validStaticMembersOfBaseClassB0,
|
||||
invalidMembers: membersOfI5.concat(membersOfI6, invalidMembersOfB0AtStaticSide)
|
||||
}, [
|
||||
"extendsB0AndImplementsI5ThatExtendsB0TypesStatic",
|
||||
"extendsB0AndImplementsI6ThatExtendsB0AndHasStaticMethodOfB0TypesStatic"
|
||||
]);
|
|
@ -10,4 +10,4 @@
|
|||
//// public static a/*property2*/
|
||||
////}
|
||||
|
||||
goTo.eachMarker(() => verify.completionListIsEmpty());
|
||||
goTo.eachMarker(() => verify.completionListContainsClassElementKeywords());
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
///<reference path="fourslash.ts" />
|
||||
///<reference path="fourslash.ts" />
|
||||
|
||||
//// var x = class myClass {
|
||||
//// getClassName (){
|
||||
|
@ -11,4 +11,4 @@ goTo.marker("0");
|
|||
verify.completionListContains("myClass", "(local class) myClass", /*documentation*/ undefined, "local class");
|
||||
|
||||
goTo.marker("1");
|
||||
verify.completionListContains("myClass", "(local class) myClass", /*documentation*/ undefined, "local class");
|
||||
verify.not.completionListContains("myClass", "(local class) myClass", /*documentation*/ undefined, "local class");
|
|
@ -1,4 +1,4 @@
|
|||
///<reference path="fourslash.ts" />
|
||||
///<reference path="fourslash.ts" />
|
||||
|
||||
//// class myClass { /*0*/ }
|
||||
//// /*1*/
|
||||
|
@ -16,7 +16,7 @@
|
|||
//// }
|
||||
|
||||
goTo.marker("0");
|
||||
verify.completionListContains("myClass", "class myClass", /*documentation*/ undefined, "class");
|
||||
verify.not.completionListContains("myClass", "class myClass", /*documentation*/ undefined, "class");
|
||||
verify.not.completionListContains("myClass", "(local class) myClass", /*documentation*/ undefined, "local class");
|
||||
|
||||
goTo.marker("1");
|
||||
|
@ -28,7 +28,7 @@ verify.completionListContains("myClass", "(local class) myClass", /*documentatio
|
|||
verify.not.completionListContains("myClass", "class myClass", /*documentation*/ undefined, "class");
|
||||
|
||||
goTo.marker("3");
|
||||
verify.completionListContains("myClass", "(local class) myClass", /*documentation*/ undefined, "local class");
|
||||
verify.not.completionListContains("myClass", "(local class) myClass", /*documentation*/ undefined, "local class");
|
||||
verify.not.completionListContains("myClass", "class myClass", /*documentation*/ undefined, "class");
|
||||
|
||||
goTo.marker("4");
|
||||
|
@ -36,5 +36,5 @@ verify.completionListContains("myClass", "class myClass", /*documentation*/ unde
|
|||
verify.not.completionListContains("myClass", "(local class) myClass", /*documentation*/ undefined, "local class");
|
||||
|
||||
goTo.marker("5");
|
||||
verify.completionListContains("myClass", "class myClass", /*documentation*/ undefined, "class");
|
||||
verify.not.completionListContains("myClass", "class myClass", /*documentation*/ undefined, "class");
|
||||
verify.not.completionListContains("myClass", "(local class) myClass", /*documentation*/ undefined, "local class");
|
||||
|
|
|
@ -53,7 +53,7 @@ verify.completionListIsGlobal(false);
|
|||
goTo.marker("9");
|
||||
verify.completionListIsGlobal(false);
|
||||
goTo.marker("10");
|
||||
verify.completionListIsGlobal(true);
|
||||
verify.completionListIsGlobal(false);
|
||||
goTo.marker("11");
|
||||
verify.completionListIsGlobal(true);
|
||||
goTo.marker("12");
|
||||
|
|
|
@ -225,27 +225,28 @@
|
|||
////
|
||||
////var shwvar = 1;
|
||||
|
||||
function goToMarkAndGeneralVerify(marker: string)
|
||||
function goToMarkAndGeneralVerify(marker: string, isClassScope?: boolean)
|
||||
{
|
||||
goTo.marker(marker);
|
||||
|
||||
verify.completionListContains('mod1var', 'var mod1var: number');
|
||||
verify.completionListContains('mod1fn', 'function mod1fn(): void');
|
||||
verify.completionListContains('mod1cls', 'class mod1cls');
|
||||
verify.completionListContains('mod1int', 'interface mod1int');
|
||||
verify.completionListContains('mod1mod', 'namespace mod1mod');
|
||||
verify.completionListContains('mod1evar', 'var mod1.mod1evar: number');
|
||||
verify.completionListContains('mod1efn', 'function mod1.mod1efn(): void');
|
||||
verify.completionListContains('mod1ecls', 'class mod1.mod1ecls');
|
||||
verify.completionListContains('mod1eint', 'interface mod1.mod1eint');
|
||||
verify.completionListContains('mod1emod', 'namespace mod1.mod1emod');
|
||||
verify.completionListContains('mod1eexvar', 'var mod1.mod1eexvar: number');
|
||||
verify.completionListContains('mod2', 'namespace mod2');
|
||||
verify.completionListContains('mod3', 'namespace mod3');
|
||||
verify.completionListContains('shwvar', 'var shwvar: number');
|
||||
verify.completionListContains('shwfn', 'function shwfn(): void');
|
||||
verify.completionListContains('shwcls', 'class shwcls');
|
||||
verify.completionListContains('shwint', 'interface shwint');
|
||||
const verifyModule = isClassScope ? verify.not : verify;
|
||||
verifyModule.completionListContains('mod1var', 'var mod1var: number');
|
||||
verifyModule.completionListContains('mod1fn', 'function mod1fn(): void');
|
||||
verifyModule.completionListContains('mod1cls', 'class mod1cls');
|
||||
verifyModule.completionListContains('mod1int', 'interface mod1int');
|
||||
verifyModule.completionListContains('mod1mod', 'namespace mod1mod');
|
||||
verifyModule.completionListContains('mod1evar', 'var mod1.mod1evar: number');
|
||||
verifyModule.completionListContains('mod1efn', 'function mod1.mod1efn(): void');
|
||||
verifyModule.completionListContains('mod1ecls', 'class mod1.mod1ecls');
|
||||
verifyModule.completionListContains('mod1eint', 'interface mod1.mod1eint');
|
||||
verifyModule.completionListContains('mod1emod', 'namespace mod1.mod1emod');
|
||||
verifyModule.completionListContains('mod1eexvar', 'var mod1.mod1eexvar: number');
|
||||
verifyModule.completionListContains('mod2', 'namespace mod2');
|
||||
verifyModule.completionListContains('mod3', 'namespace mod3');
|
||||
verifyModule.completionListContains('shwvar', 'var shwvar: number');
|
||||
verifyModule.completionListContains('shwfn', 'function shwfn(): void');
|
||||
verifyModule.completionListContains('shwcls', 'class shwcls');
|
||||
verifyModule.completionListContains('shwint', 'interface shwint');
|
||||
|
||||
verify.not.completionListContains('mod2var');
|
||||
verify.not.completionListContains('mod2fn');
|
||||
|
@ -280,7 +281,7 @@ verify.completionListContains('bar', '(local var) bar: number');
|
|||
verify.completionListContains('foob', '(local function) foob(): void');
|
||||
|
||||
// from class in mod1
|
||||
goToMarkAndGeneralVerify('class');
|
||||
goToMarkAndGeneralVerify('class', /*isClassScope*/ true);
|
||||
//verify.not.completionListContains('ceFunc');
|
||||
//verify.not.completionListContains('ceVar');
|
||||
|
||||
|
@ -306,7 +307,7 @@ verify.completionListContains('bar', '(local var) bar: number');
|
|||
verify.completionListContains('foob', '(local function) foob(): void');
|
||||
|
||||
// from exported class in mod1
|
||||
goToMarkAndGeneralVerify('exportedClass');
|
||||
goToMarkAndGeneralVerify('exportedClass', /*isClassScope*/ true);
|
||||
//verify.not.completionListContains('ceFunc');
|
||||
//verify.not.completionListContains('ceVar');
|
||||
|
||||
|
|
|
@ -231,6 +231,39 @@
|
|||
//// x: /*objectLiteral*/
|
||||
////}
|
||||
|
||||
goTo.marker('extendedClass');
|
||||
|
||||
verify.not.completionListContains('mod1');
|
||||
verify.not.completionListContains('mod2');
|
||||
verify.not.completionListContains('mod3');
|
||||
verify.not.completionListContains('shwvar', 'var shwvar: number');
|
||||
verify.not.completionListContains('shwfn', 'function shwfn(): void');
|
||||
verify.not.completionListContains('shwcls', 'class shwcls');
|
||||
verify.not.completionListContains('shwint', 'interface shwint');
|
||||
|
||||
verify.not.completionListContains('mod2var');
|
||||
verify.not.completionListContains('mod2fn');
|
||||
verify.not.completionListContains('mod2cls');
|
||||
verify.not.completionListContains('mod2int');
|
||||
verify.not.completionListContains('mod2mod');
|
||||
verify.not.completionListContains('mod2evar');
|
||||
verify.not.completionListContains('mod2efn');
|
||||
verify.not.completionListContains('mod2ecls');
|
||||
verify.not.completionListContains('mod2eint');
|
||||
verify.not.completionListContains('mod2emod');
|
||||
verify.not.completionListContains('sfvar');
|
||||
verify.not.completionListContains('sffn');
|
||||
verify.not.completionListContains('scvar');
|
||||
verify.not.completionListContains('scfn');
|
||||
verify.completionListContains('scpfn');
|
||||
verify.completionListContains('scpvar');
|
||||
verify.not.completionListContains('scsvar');
|
||||
verify.not.completionListContains('scsfn');
|
||||
verify.not.completionListContains('sivar');
|
||||
verify.not.completionListContains('sifn');
|
||||
verify.not.completionListContains('mod1exvar');
|
||||
verify.not.completionListContains('mod2eexvar');
|
||||
|
||||
function goToMarkerAndVerify(marker: string)
|
||||
{
|
||||
goTo.marker(marker);
|
||||
|
@ -267,8 +300,6 @@ function goToMarkerAndVerify(marker: string)
|
|||
verify.not.completionListContains('mod2eexvar');
|
||||
}
|
||||
|
||||
goToMarkerAndVerify('extendedClass');
|
||||
|
||||
goToMarkerAndVerify('objectLiteral');
|
||||
|
||||
goTo.marker('localVar');
|
||||
|
|
16
tests/cases/fourslash/findAllRefsForDefaultExport04.ts
Normal file
16
tests/cases/fourslash/findAllRefsForDefaultExport04.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @Filename: /a.ts
|
||||
////const [|{| "isWriteAccess": true, "isDefinition": true |}a|] = 0;
|
||||
////export default [|a|];
|
||||
|
||||
// @Filename: /b.ts
|
||||
////import [|{| "isWriteAccess": true, "isDefinition": true |}a|] from "./a";
|
||||
////[|a|];
|
||||
|
||||
const [r0, r1, r2, r3] = test.ranges();
|
||||
verify.referenceGroups([r0, r1], [
|
||||
{ definition: "const a: 0", ranges: [r0, r1] },
|
||||
{ definition: "import a", ranges: [r2, r3] }
|
||||
]);
|
||||
verify.singleReferenceGroup("import a", [r2, r3]);
|
|
@ -133,11 +133,13 @@ declare namespace FourSlashInterface {
|
|||
class verifyNegatable {
|
||||
private negative;
|
||||
not: verifyNegatable;
|
||||
allowedClassElementKeywords: string[];
|
||||
constructor(negative?: boolean);
|
||||
completionListCount(expectedCount: number): void;
|
||||
completionListContains(symbol: string, text?: string, documentation?: string, kind?: string, spanIndex?: number): void;
|
||||
completionListItemsCountIsGreaterThan(count: number): void;
|
||||
completionListIsEmpty(): void;
|
||||
completionListContainsClassElementKeywords(): void;
|
||||
completionListAllowsNewIdentifier(): void;
|
||||
signatureHelpPresent(): void;
|
||||
errorExistsBetweenMarkers(startMarker: string, endMarker: string): void;
|
||||
|
|
|
@ -26,7 +26,7 @@ const methods = ranges.get("method");
|
|||
const [m0, m1, m2] = methods;
|
||||
verify.referenceGroups(m0, [{ definition: "(method) Base<T>.method<U>(a?: T, b?: U): this", ranges: methods }]);
|
||||
verify.referenceGroups(m1, [
|
||||
{ definition: "(method) Base<T>.method(): void", ranges: [m0] },
|
||||
{ definition: "(method) Base<T>.method<U>(a?: T, b?: U): this", ranges: [m0] },
|
||||
{ definition: "(method) MyClass.method(): void", ranges: [m1, m2] }
|
||||
]);
|
||||
verify.referenceGroups(m2, [
|
||||
|
|
|
@ -15,5 +15,5 @@
|
|||
|
||||
verify.quickInfos({
|
||||
1: "function ComponentSpecific<number>(l: {\n prop: number;\n}): any",
|
||||
2: "function ComponentSpecific<\"hello\">(l: {\n prop: \"hello\";\n}): any"
|
||||
2: "function ComponentSpecific<U>(l: {\n prop: U;\n}): any"
|
||||
});
|
||||
|
|
|
@ -24,6 +24,6 @@ verify.quickInfos({
|
|||
3: "function OverloadComponent<boolean, string>(attr: {\n b: string;\n a: boolean;\n}): any (+2 overloads)",
|
||||
4: "function OverloadComponent<number>(attr: {\n b: number;\n a?: string;\n \"ignore-prop\": boolean;\n}): any (+2 overloads)",
|
||||
5: "function OverloadComponent(): any (+2 overloads)",
|
||||
6: "function OverloadComponent<boolean, number>(attr: {\n b: number;\n a: boolean;\n}): any (+2 overloads)",
|
||||
7: "function OverloadComponent<boolean, string>(attr: {\n b: string;\n a: boolean;\n}): any (+2 overloads)"
|
||||
6: "function OverloadComponent(): any (+2 overloads)",
|
||||
7: "function OverloadComponent(): any (+2 overloads)",
|
||||
});
|
||||
|
|
2
tests/lib/react.d.ts
vendored
2
tests/lib/react.d.ts
vendored
|
@ -197,7 +197,7 @@ declare namespace __React {
|
|||
|
||||
type SFC<P> = StatelessComponent<P>;
|
||||
interface StatelessComponent<P> {
|
||||
(props: P, context?: any): ReactElement<any>;
|
||||
(props: P & { children?: ReactNode }, context?: any): ReactElement<any>;
|
||||
propTypes?: ValidationMap<P>;
|
||||
contextTypes?: ValidationMap<any>;
|
||||
defaultProps?: P;
|
||||
|
|
Loading…
Reference in a new issue