mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into ownJsonParsing
This commit is contained in:
+56
-37
@@ -211,6 +211,7 @@ namespace ts {
|
||||
return tryFindAmbientModule(moduleName, /*withAugmentations*/ false);
|
||||
},
|
||||
getApparentType,
|
||||
getAllPossiblePropertiesOfType,
|
||||
getSuggestionForNonexistentProperty,
|
||||
getSuggestionForNonexistentSymbol,
|
||||
getBaseConstraintOfType,
|
||||
@@ -690,10 +691,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);
|
||||
}
|
||||
@@ -743,7 +740,8 @@ namespace ts {
|
||||
const useFile = getSourceFileOfNode(usage);
|
||||
if (declarationFile !== useFile) {
|
||||
if ((modulekind && (declarationFile.externalModuleIndicator || useFile.externalModuleIndicator)) ||
|
||||
(!compilerOptions.outFile && !compilerOptions.out)) {
|
||||
(!compilerOptions.outFile && !compilerOptions.out) ||
|
||||
isInAmbientContext(declaration)) {
|
||||
// nodes are in different files and order cannot be determined
|
||||
return true;
|
||||
}
|
||||
@@ -1288,7 +1286,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)));
|
||||
}
|
||||
}
|
||||
@@ -4163,6 +4161,7 @@ namespace ts {
|
||||
const types: Type[] = [];
|
||||
let definedInConstructor = false;
|
||||
let definedInMethod = false;
|
||||
let jsDocType: Type;
|
||||
for (const declaration of symbol.declarations) {
|
||||
const expression = declaration.kind === SyntaxKind.BinaryExpression ? <BinaryExpression>declaration :
|
||||
declaration.kind === SyntaxKind.PropertyAccessExpression ? <BinaryExpression>getAncestor(declaration, SyntaxKind.BinaryExpression) :
|
||||
@@ -4181,19 +4180,26 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
if (expression.flags & NodeFlags.JavaScriptFile) {
|
||||
// If there is a JSDoc type, use it
|
||||
const type = getTypeForDeclarationFromJSDocComment(expression.parent);
|
||||
if (type && type !== unknownType) {
|
||||
types.push(getWidenedType(type));
|
||||
continue;
|
||||
// If there is a JSDoc type, use it
|
||||
const type = getTypeForDeclarationFromJSDocComment(expression.parent);
|
||||
if (type) {
|
||||
const declarationType = getWidenedType(type);
|
||||
if (!jsDocType) {
|
||||
jsDocType = declarationType;
|
||||
}
|
||||
else if (jsDocType !== unknownType && declarationType !== unknownType && !isTypeIdenticalTo(jsDocType, declarationType)) {
|
||||
const name = getNameOfDeclaration(declaration);
|
||||
error(name, Diagnostics.Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2, declarationNameToString(name), typeToString(jsDocType), typeToString(declarationType));
|
||||
}
|
||||
}
|
||||
|
||||
types.push(getWidenedLiteralType(checkExpressionCached(expression.right)));
|
||||
else if (!jsDocType) {
|
||||
// If we don't have an explicit JSDoc type, get the type from the expression.
|
||||
types.push(getWidenedLiteralType(checkExpressionCached(expression.right)));
|
||||
}
|
||||
}
|
||||
|
||||
return getWidenedType(addOptionality(getUnionType(types, /*subtypeReduction*/ true), definedInMethod && !definedInConstructor));
|
||||
const type = jsDocType || getUnionType(types, /*subtypeReduction*/ true);
|
||||
return getWidenedType(addOptionality(type, definedInMethod && !definedInConstructor));
|
||||
}
|
||||
|
||||
// Return the type implied by a binding pattern element. This is the type of the initializer of the element if
|
||||
@@ -5692,6 +5698,22 @@ namespace ts {
|
||||
getPropertiesOfObjectType(type);
|
||||
}
|
||||
|
||||
function getAllPossiblePropertiesOfType(type: Type): Symbol[] {
|
||||
if (type.flags & TypeFlags.Union) {
|
||||
const props = createMap<Symbol>();
|
||||
for (const memberType of (type as UnionType).types) {
|
||||
for (const { name } of getPropertiesOfType(memberType)) {
|
||||
if (!props.has(name)) {
|
||||
props.set(name, createUnionOrIntersectionProperty(type as UnionType, name));
|
||||
}
|
||||
}
|
||||
}
|
||||
return arrayFrom(props.values());
|
||||
} else {
|
||||
return getPropertiesOfType(type);
|
||||
}
|
||||
}
|
||||
|
||||
function getConstraintOfType(type: TypeVariable | UnionOrIntersectionType): Type {
|
||||
return type.flags & TypeFlags.TypeParameter ? getConstraintOfTypeParameter(<TypeParameter>type) :
|
||||
type.flags & TypeFlags.IndexedAccess ? getConstraintOfIndexedAccess(<IndexedAccessType>type) :
|
||||
@@ -12760,7 +12782,7 @@ namespace ts {
|
||||
* @param node the expression whose contextual type will be returned.
|
||||
* @returns the contextual type of an expression.
|
||||
*/
|
||||
function getContextualType(node: Expression): Type {
|
||||
function getContextualType(node: Expression): Type | undefined {
|
||||
if (isInsideWithStatementBody(node)) {
|
||||
// We cannot answer semantic questions within a with block, do not proceed any further
|
||||
return undefined;
|
||||
@@ -13234,7 +13256,7 @@ namespace ts {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isValidSpreadType(type: Type): boolean {
|
||||
return !!(type.flags & (TypeFlags.Any | TypeFlags.Null | TypeFlags.Undefined | TypeFlags.NonPrimitive) ||
|
||||
@@ -13554,6 +13576,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.
|
||||
@@ -13574,6 +13610,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);
|
||||
@@ -13611,7 +13648,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) {
|
||||
@@ -14011,25 +14049,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;
|
||||
}
|
||||
|
||||
@@ -490,6 +490,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.
|
||||
|
||||
@@ -733,6 +733,9 @@ namespace ts {
|
||||
// Transformation nodes
|
||||
case SyntaxKind.PartiallyEmittedExpression:
|
||||
return emitPartiallyEmittedExpression(<PartiallyEmittedExpression>node);
|
||||
|
||||
case SyntaxKind.CommaListExpression:
|
||||
return emitCommaList(<CommaListExpression>node);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2101,6 +2104,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.
|
||||
@@ -2951,6 +2958,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,
|
||||
|
||||
+29
-1
@@ -2077,6 +2077,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;
|
||||
}
|
||||
|
||||
// Compound nodes
|
||||
|
||||
export function createComma(left: Expression, right: Expression) {
|
||||
@@ -2852,7 +2876,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 {
|
||||
@@ -442,6 +440,8 @@ namespace ts {
|
||||
case ModuleResolutionKind.Classic:
|
||||
result = classicNameResolver(moduleName, containingFile, compilerOptions, host, cache);
|
||||
break;
|
||||
default:
|
||||
Debug.fail(`Unexpected moduleResolution: ${moduleResolution}`);
|
||||
}
|
||||
|
||||
if (perFolderCache) {
|
||||
|
||||
@@ -361,6 +361,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;
|
||||
|
||||
+1
-86
@@ -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) {
|
||||
|
||||
+21
-2
@@ -389,6 +389,7 @@ namespace ts {
|
||||
// Transformation nodes
|
||||
NotEmittedStatement,
|
||||
PartiallyEmittedExpression,
|
||||
CommaListExpression,
|
||||
MergeDeclarationMarker,
|
||||
EndOfDeclarationMarker,
|
||||
|
||||
@@ -571,7 +572,11 @@ namespace ts {
|
||||
|
||||
export interface Identifier extends PrimaryExpression {
|
||||
kind: SyntaxKind.Identifier;
|
||||
text: string; // Text of identifier (with escapes converted to characters)
|
||||
/**
|
||||
* Text of identifier (with escapes converted to characters).
|
||||
* If the identifier begins with two underscores, this will begin with three.
|
||||
*/
|
||||
text: string;
|
||||
originalKeywordKind?: SyntaxKind; // Original syntaxKind which get set so that we can report an error later
|
||||
/*@internal*/ autoGenerateKind?: GeneratedIdentifierKind; // Specifies whether to auto-generate the text for an identifier.
|
||||
/*@internal*/ autoGenerateId?: number; // Ensures unique generated identifiers get unique names, but clones get the same name.
|
||||
@@ -1599,6 +1604,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.
|
||||
*/
|
||||
@@ -2532,7 +2545,7 @@ namespace ts {
|
||||
getFullyQualifiedName(symbol: Symbol): string;
|
||||
getAugmentedPropertiesOfType(type: Type): Symbol[];
|
||||
getRootSymbols(symbol: Symbol): Symbol[];
|
||||
getContextualType(node: Expression): Type;
|
||||
getContextualType(node: Expression): Type | undefined;
|
||||
getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[]): Signature;
|
||||
getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature;
|
||||
isImplementationOfOverload(node: FunctionLikeDeclaration): boolean;
|
||||
@@ -2573,6 +2586,12 @@ namespace ts {
|
||||
/* @internal */ getIdentifierCount(): number;
|
||||
/* @internal */ getSymbolCount(): number;
|
||||
/* @internal */ getTypeCount(): number;
|
||||
|
||||
/**
|
||||
* For a union, will include a property if it's defined in *any* of the member types.
|
||||
* So for `{ a } | { b }`, this will include both `a` and `b`.
|
||||
*/
|
||||
/* @internal */ getAllPossiblePropertiesOfType(type: Type): Symbol[];
|
||||
}
|
||||
|
||||
export enum NodeBuilderFlags {
|
||||
|
||||
+54
-23
@@ -2338,6 +2338,9 @@ namespace ts {
|
||||
case SyntaxKind.SpreadElement:
|
||||
return 1;
|
||||
|
||||
case SyntaxKind.CommaListExpression:
|
||||
return 0;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
@@ -3936,6 +3939,7 @@ namespace ts {
|
||||
|| kind === SyntaxKind.SpreadElement
|
||||
|| kind === SyntaxKind.AsExpression
|
||||
|| kind === SyntaxKind.OmittedExpression
|
||||
|| kind === SyntaxKind.CommaListExpression
|
||||
|| isUnaryExpressionKind(kind);
|
||||
}
|
||||
|
||||
@@ -4049,6 +4053,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;
|
||||
}
|
||||
@@ -4255,6 +4263,52 @@ namespace ts {
|
||||
// Firefox has Object.prototype.watch
|
||||
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);
|
||||
for (let i = 0; i < s2.length + 1; i++) {
|
||||
previous[i] = i;
|
||||
current[i] = -1;
|
||||
}
|
||||
for (let i = 1; i < s1.length + 1; i++) {
|
||||
current[0] = i;
|
||||
for (let j = 1; j < s2.length + 1; j++) {
|
||||
current[j] = Math.min(
|
||||
previous[j] + 1,
|
||||
current[j - 1] + 1,
|
||||
previous[j - 1] + (s1[i - 1] === s2[j - 1] ? 0 : 2));
|
||||
}
|
||||
// shift current back to previous, and then reuse previous' array
|
||||
const tmp = previous;
|
||||
previous = current;
|
||||
current = tmp;
|
||||
}
|
||||
return previous[previous.length - 1];
|
||||
}
|
||||
}
|
||||
|
||||
namespace ts {
|
||||
@@ -4685,27 +4739,4 @@ namespace ts {
|
||||
export function unescapeIdentifier(identifier: string): string {
|
||||
return identifier.length >= 3 && identifier.charCodeAt(0) === CharacterCodes._ && identifier.charCodeAt(1) === CharacterCodes._ && identifier.charCodeAt(2) === CharacterCodes._ ? identifier.substr(1) : identifier;
|
||||
}
|
||||
|
||||
export function levenshtein(s1: string, s2: string): number {
|
||||
let previous: number[] = new Array(s2.length + 1);
|
||||
let current: number[] = new Array(s2.length + 1);
|
||||
for (let i = 0; i < s2.length + 1; i++) {
|
||||
previous[i] = i;
|
||||
current[i] = -1;
|
||||
}
|
||||
for (let i = 1; i < s1.length + 1; i++) {
|
||||
current[0] = i;
|
||||
for (let j = 1; j < s2.length + 1; j++) {
|
||||
current[j] = Math.min(
|
||||
previous[j] + 1,
|
||||
current[j - 1] + 1,
|
||||
previous[j - 1] + (s1[i - 1] === s2[j - 1] ? 0 : 2));
|
||||
}
|
||||
// shift current back to previous, and then reuse previous' array
|
||||
const tmp = previous;
|
||||
previous = current;
|
||||
current = tmp;
|
||||
}
|
||||
return previous[previous.length - 1];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -876,6 +876,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;
|
||||
@@ -1389,6 +1393,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);
|
||||
}
|
||||
|
||||
Vendored
+92
-1
@@ -23,5 +23,96 @@ interface SharedArrayBufferConstructor {
|
||||
readonly prototype: SharedArrayBuffer;
|
||||
new (byteLength: number): SharedArrayBuffer;
|
||||
}
|
||||
declare var SharedArrayBuffer: SharedArrayBufferConstructor;
|
||||
|
||||
declare var SharedArrayBuffer: SharedArrayBufferConstructor;
|
||||
interface ArrayBufferTypes {
|
||||
SharedArrayBuffer: SharedArrayBuffer;
|
||||
}
|
||||
|
||||
interface Atomics {
|
||||
/**
|
||||
* Adds a value to the value at the given position in the array, returning the original value.
|
||||
* Until this atomic operation completes, any other read or write operation against the array
|
||||
* will block.
|
||||
*/
|
||||
add(typedArray: Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array, index: number, value: number): number;
|
||||
|
||||
/**
|
||||
* Stores the bitwise AND of a value with the value at the given position in the array,
|
||||
* returning the original value. Until this atomic operation completes, any other read or
|
||||
* write operation against the array will block.
|
||||
*/
|
||||
and(typedArray: Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array, index: number, value: number): number;
|
||||
|
||||
/**
|
||||
* Replaces the value at the given position in the array if the original value equals the given
|
||||
* expected value, returning the original value. Until this atomic operation completes, any
|
||||
* other read or write operation against the array will block.
|
||||
*/
|
||||
compareExchange(typedArray: Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array, index: number, expectedValue: number, replacementValue: number): number;
|
||||
|
||||
/**
|
||||
* Replaces the value at the given position in the array, returning the original value. Until
|
||||
* this atomic operation completes, any other read or write operation against the array will
|
||||
* block.
|
||||
*/
|
||||
exchange(typedArray: Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array, index: number, value: number): number;
|
||||
|
||||
/**
|
||||
* Returns a value indicating whether high-performance algorithms can use atomic operations
|
||||
* (`true`) or must use locks (`false`) for the given number of bytes-per-element of a typed
|
||||
* array.
|
||||
*/
|
||||
isLockFree(size: number): boolean;
|
||||
|
||||
/**
|
||||
* Returns the value at the given position in the array. Until this atomic operation completes,
|
||||
* any other read or write operation against the array will block.
|
||||
*/
|
||||
load(typedArray: Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array, index: number): number;
|
||||
|
||||
/**
|
||||
* Stores the bitwise OR of a value with the value at the given position in the array,
|
||||
* returning the original value. Until this atomic operation completes, any other read or write
|
||||
* operation against the array will block.
|
||||
*/
|
||||
or(typedArray: Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array, index: number, value: number): number;
|
||||
|
||||
/**
|
||||
* Stores a value at the given position in the array, returning the new value. Until this
|
||||
* atomic operation completes, any other read or write operation against the array will block.
|
||||
*/
|
||||
store(typedArray: Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array, index: number, value: number): number;
|
||||
|
||||
/**
|
||||
* Subtracts a value from the value at the given position in the array, returning the original
|
||||
* value. Until this atomic operation completes, any other read or write operation against the
|
||||
* array will block.
|
||||
*/
|
||||
sub(typedArray: Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array, index: number, value: number): number;
|
||||
|
||||
/**
|
||||
* If the value at the given position in the array is equal to the provided value, the current
|
||||
* agent is put to sleep causing execution to suspend until the timeout expires (returning
|
||||
* `"timed-out"`) or until the agent is awoken (returning `"ok"`); otherwise, returns
|
||||
* `"not-equal"`.
|
||||
*/
|
||||
wait(typedArray: Int32Array, index: number, value: number, timeout?: number): "ok" | "not-equal" | "timed-out";
|
||||
|
||||
/**
|
||||
* Wakes up sleeping agents that are waiting on the given index of the array, returning the
|
||||
* number of agents that were awoken.
|
||||
*/
|
||||
wake(typedArray: Int32Array, index: number, count: number): number;
|
||||
|
||||
/**
|
||||
* Stores the bitwise XOR of a value with the value at the given position in the array,
|
||||
* returning the original value. Until this atomic operation completes, any other read or write
|
||||
* operation against the array will block.
|
||||
*/
|
||||
xor(typedArray: Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array, index: number, value: number): number;
|
||||
|
||||
readonly [Symbol.toStringTag]: "Atomics";
|
||||
}
|
||||
|
||||
declare var Atomics: Atomics;
|
||||
Vendored
+28
-20
@@ -1386,6 +1386,14 @@ interface ArrayBuffer {
|
||||
slice(begin: number, end?: number): ArrayBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allowed ArrayBuffer types for the buffer of an ArrayBufferView and related Typed Arrays.
|
||||
*/
|
||||
interface ArrayBufferTypes {
|
||||
ArrayBuffer: ArrayBuffer;
|
||||
}
|
||||
type ArrayBufferLike = ArrayBufferTypes[keyof ArrayBufferTypes];
|
||||
|
||||
interface ArrayBufferConstructor {
|
||||
readonly prototype: ArrayBuffer;
|
||||
new (byteLength: number): ArrayBuffer;
|
||||
@@ -1397,7 +1405,7 @@ interface ArrayBufferView {
|
||||
/**
|
||||
* The ArrayBuffer instance referenced by the array.
|
||||
*/
|
||||
buffer: ArrayBuffer;
|
||||
buffer: ArrayBufferLike;
|
||||
|
||||
/**
|
||||
* The length in bytes of the array.
|
||||
@@ -1539,7 +1547,7 @@ interface DataView {
|
||||
}
|
||||
|
||||
interface DataViewConstructor {
|
||||
new (buffer: ArrayBuffer, byteOffset?: number, byteLength?: number): DataView;
|
||||
new (buffer: ArrayBufferLike, byteOffset?: number, byteLength?: number): DataView;
|
||||
}
|
||||
declare const DataView: DataViewConstructor;
|
||||
|
||||
@@ -1556,7 +1564,7 @@ interface Int8Array {
|
||||
/**
|
||||
* The ArrayBuffer instance referenced by the array.
|
||||
*/
|
||||
readonly buffer: ArrayBuffer;
|
||||
readonly buffer: ArrayBufferLike;
|
||||
|
||||
/**
|
||||
* The length in bytes of the array.
|
||||
@@ -1799,7 +1807,7 @@ interface Int8ArrayConstructor {
|
||||
readonly prototype: Int8Array;
|
||||
new (length: number): Int8Array;
|
||||
new (array: ArrayLike<number>): Int8Array;
|
||||
new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Int8Array;
|
||||
new (buffer: ArrayBufferLike, byteOffset?: number, length?: number): Int8Array;
|
||||
|
||||
/**
|
||||
* The size in bytes of each element in the array.
|
||||
@@ -1840,7 +1848,7 @@ interface Uint8Array {
|
||||
/**
|
||||
* The ArrayBuffer instance referenced by the array.
|
||||
*/
|
||||
readonly buffer: ArrayBuffer;
|
||||
readonly buffer: ArrayBufferLike;
|
||||
|
||||
/**
|
||||
* The length in bytes of the array.
|
||||
@@ -2084,7 +2092,7 @@ interface Uint8ArrayConstructor {
|
||||
readonly prototype: Uint8Array;
|
||||
new (length: number): Uint8Array;
|
||||
new (array: ArrayLike<number>): Uint8Array;
|
||||
new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Uint8Array;
|
||||
new (buffer: ArrayBufferLike, byteOffset?: number, length?: number): Uint8Array;
|
||||
|
||||
/**
|
||||
* The size in bytes of each element in the array.
|
||||
@@ -2125,7 +2133,7 @@ interface Uint8ClampedArray {
|
||||
/**
|
||||
* The ArrayBuffer instance referenced by the array.
|
||||
*/
|
||||
readonly buffer: ArrayBuffer;
|
||||
readonly buffer: ArrayBufferLike;
|
||||
|
||||
/**
|
||||
* The length in bytes of the array.
|
||||
@@ -2369,7 +2377,7 @@ interface Uint8ClampedArrayConstructor {
|
||||
readonly prototype: Uint8ClampedArray;
|
||||
new (length: number): Uint8ClampedArray;
|
||||
new (array: ArrayLike<number>): Uint8ClampedArray;
|
||||
new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Uint8ClampedArray;
|
||||
new (buffer: ArrayBufferLike, byteOffset?: number, length?: number): Uint8ClampedArray;
|
||||
|
||||
/**
|
||||
* The size in bytes of each element in the array.
|
||||
@@ -2409,7 +2417,7 @@ interface Int16Array {
|
||||
/**
|
||||
* The ArrayBuffer instance referenced by the array.
|
||||
*/
|
||||
readonly buffer: ArrayBuffer;
|
||||
readonly buffer: ArrayBufferLike;
|
||||
|
||||
/**
|
||||
* The length in bytes of the array.
|
||||
@@ -2653,7 +2661,7 @@ interface Int16ArrayConstructor {
|
||||
readonly prototype: Int16Array;
|
||||
new (length: number): Int16Array;
|
||||
new (array: ArrayLike<number>): Int16Array;
|
||||
new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Int16Array;
|
||||
new (buffer: ArrayBufferLike, byteOffset?: number, length?: number): Int16Array;
|
||||
|
||||
/**
|
||||
* The size in bytes of each element in the array.
|
||||
@@ -2694,7 +2702,7 @@ interface Uint16Array {
|
||||
/**
|
||||
* The ArrayBuffer instance referenced by the array.
|
||||
*/
|
||||
readonly buffer: ArrayBuffer;
|
||||
readonly buffer: ArrayBufferLike;
|
||||
|
||||
/**
|
||||
* The length in bytes of the array.
|
||||
@@ -2938,7 +2946,7 @@ interface Uint16ArrayConstructor {
|
||||
readonly prototype: Uint16Array;
|
||||
new (length: number): Uint16Array;
|
||||
new (array: ArrayLike<number>): Uint16Array;
|
||||
new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Uint16Array;
|
||||
new (buffer: ArrayBufferLike, byteOffset?: number, length?: number): Uint16Array;
|
||||
|
||||
/**
|
||||
* The size in bytes of each element in the array.
|
||||
@@ -2978,7 +2986,7 @@ interface Int32Array {
|
||||
/**
|
||||
* The ArrayBuffer instance referenced by the array.
|
||||
*/
|
||||
readonly buffer: ArrayBuffer;
|
||||
readonly buffer: ArrayBufferLike;
|
||||
|
||||
/**
|
||||
* The length in bytes of the array.
|
||||
@@ -3222,7 +3230,7 @@ interface Int32ArrayConstructor {
|
||||
readonly prototype: Int32Array;
|
||||
new (length: number): Int32Array;
|
||||
new (array: ArrayLike<number>): Int32Array;
|
||||
new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Int32Array;
|
||||
new (buffer: ArrayBufferLike, byteOffset?: number, length?: number): Int32Array;
|
||||
|
||||
/**
|
||||
* The size in bytes of each element in the array.
|
||||
@@ -3262,7 +3270,7 @@ interface Uint32Array {
|
||||
/**
|
||||
* The ArrayBuffer instance referenced by the array.
|
||||
*/
|
||||
readonly buffer: ArrayBuffer;
|
||||
readonly buffer: ArrayBufferLike;
|
||||
|
||||
/**
|
||||
* The length in bytes of the array.
|
||||
@@ -3506,7 +3514,7 @@ interface Uint32ArrayConstructor {
|
||||
readonly prototype: Uint32Array;
|
||||
new (length: number): Uint32Array;
|
||||
new (array: ArrayLike<number>): Uint32Array;
|
||||
new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Uint32Array;
|
||||
new (buffer: ArrayBufferLike, byteOffset?: number, length?: number): Uint32Array;
|
||||
|
||||
/**
|
||||
* The size in bytes of each element in the array.
|
||||
@@ -3546,7 +3554,7 @@ interface Float32Array {
|
||||
/**
|
||||
* The ArrayBuffer instance referenced by the array.
|
||||
*/
|
||||
readonly buffer: ArrayBuffer;
|
||||
readonly buffer: ArrayBufferLike;
|
||||
|
||||
/**
|
||||
* The length in bytes of the array.
|
||||
@@ -3790,7 +3798,7 @@ interface Float32ArrayConstructor {
|
||||
readonly prototype: Float32Array;
|
||||
new (length: number): Float32Array;
|
||||
new (array: ArrayLike<number>): Float32Array;
|
||||
new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Float32Array;
|
||||
new (buffer: ArrayBufferLike, byteOffset?: number, length?: number): Float32Array;
|
||||
|
||||
/**
|
||||
* The size in bytes of each element in the array.
|
||||
@@ -3831,7 +3839,7 @@ interface Float64Array {
|
||||
/**
|
||||
* The ArrayBuffer instance referenced by the array.
|
||||
*/
|
||||
readonly buffer: ArrayBuffer;
|
||||
readonly buffer: ArrayBufferLike;
|
||||
|
||||
/**
|
||||
* The length in bytes of the array.
|
||||
@@ -4075,7 +4083,7 @@ interface Float64ArrayConstructor {
|
||||
readonly prototype: Float64Array;
|
||||
new (length: number): Float64Array;
|
||||
new (array: ArrayLike<number>): Float64Array;
|
||||
new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Float64Array;
|
||||
new (buffer: ArrayBufferLike, byteOffset?: number, length?: number): Float64Array;
|
||||
|
||||
/**
|
||||
* The size in bytes of each element in the array.
|
||||
|
||||
@@ -2278,6 +2278,7 @@ namespace ts.server.protocol {
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean;
|
||||
insertSpaceAfterTypeAssertion?: boolean;
|
||||
insertSpaceBeforeFunctionParenthesis?: boolean;
|
||||
placeOpenBraceOnNewLineForFunctions?: boolean;
|
||||
placeOpenBraceOnNewLineForControlBlocks?: boolean;
|
||||
|
||||
+233
-33
@@ -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);
|
||||
}
|
||||
|
||||
@@ -221,11 +224,12 @@ namespace ts.Completions {
|
||||
function getStringLiteralCompletionEntriesFromCallExpression(argumentInfo: SignatureHelp.ArgumentListInfo, typeChecker: TypeChecker): CompletionInfo | undefined {
|
||||
const candidates: Signature[] = [];
|
||||
const entries: CompletionEntry[] = [];
|
||||
const uniques = createMap<true>();
|
||||
|
||||
typeChecker.getResolvedSignature(argumentInfo.invocation, candidates);
|
||||
|
||||
for (const candidate of candidates) {
|
||||
addStringLiteralCompletionsFromType(typeChecker.getParameterType(candidate, argumentInfo.argumentIndex), entries, typeChecker);
|
||||
addStringLiteralCompletionsFromType(typeChecker.getParameterType(candidate, argumentInfo.argumentIndex), entries, typeChecker, uniques);
|
||||
}
|
||||
|
||||
if (entries.length) {
|
||||
@@ -258,7 +262,7 @@ namespace ts.Completions {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function addStringLiteralCompletionsFromType(type: Type, result: Push<CompletionEntry>, typeChecker: TypeChecker): void {
|
||||
function addStringLiteralCompletionsFromType(type: Type, result: Push<CompletionEntry>, typeChecker: TypeChecker, uniques = createMap<true>()): void {
|
||||
if (type && type.flags & TypeFlags.TypeParameter) {
|
||||
type = typeChecker.getBaseConstraintOfType(type);
|
||||
}
|
||||
@@ -267,16 +271,20 @@ namespace ts.Completions {
|
||||
}
|
||||
if (type.flags & TypeFlags.Union) {
|
||||
for (const t of (<UnionType>type).types) {
|
||||
addStringLiteralCompletionsFromType(t, result, typeChecker);
|
||||
addStringLiteralCompletionsFromType(t, result, typeChecker, uniques);
|
||||
}
|
||||
}
|
||||
else if (type.flags & TypeFlags.StringLiteral) {
|
||||
result.push({
|
||||
name: (<LiteralType>type).text,
|
||||
kindModifiers: ScriptElementKindModifier.none,
|
||||
kind: ScriptElementKind.variableElement,
|
||||
sortText: "0"
|
||||
});
|
||||
const name = (<LiteralType>type).text;
|
||||
if (!uniques.has(name)) {
|
||||
uniques.set(name, true);
|
||||
result.push({
|
||||
name,
|
||||
kindModifiers: ScriptElementKindModifier.none,
|
||||
kind: ScriptElementKind.variableElement,
|
||||
sortText: "0"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -406,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) {
|
||||
@@ -505,6 +513,7 @@ namespace ts.Completions {
|
||||
let isGlobalCompletion = false;
|
||||
let isMemberCompletion: boolean;
|
||||
let isNewIdentifierLocation: boolean;
|
||||
let hasFilteredClassMemberKeywords = false;
|
||||
let symbols: Symbol[] = [];
|
||||
|
||||
if (isRightOfDot) {
|
||||
@@ -542,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
|
||||
@@ -599,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)) {
|
||||
@@ -611,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)) {
|
||||
@@ -813,19 +829,16 @@ namespace ts.Completions {
|
||||
// We're looking up possible property names from contextual/inferred/declared type.
|
||||
isMemberCompletion = true;
|
||||
|
||||
let typeForObject: Type;
|
||||
let typeMembers: Symbol[];
|
||||
let existingMembers: Declaration[];
|
||||
|
||||
if (objectLikeContainer.kind === SyntaxKind.ObjectLiteralExpression) {
|
||||
// We are completing on contextual types, but may also include properties
|
||||
// other than those within the declared type.
|
||||
isNewIdentifierLocation = true;
|
||||
|
||||
// If the object literal is being assigned to something of type 'null | { hello: string }',
|
||||
// it clearly isn't trying to satisfy the 'null' type. So we grab the non-nullable type if possible.
|
||||
typeForObject = typeChecker.getContextualType(<ObjectLiteralExpression>objectLikeContainer);
|
||||
typeForObject = typeForObject && typeForObject.getNonNullableType();
|
||||
|
||||
const typeForObject = typeChecker.getContextualType(<ObjectLiteralExpression>objectLikeContainer);
|
||||
if (!typeForObject) return false;
|
||||
typeMembers = typeChecker.getAllPossiblePropertiesOfType(typeForObject);
|
||||
existingMembers = (<ObjectLiteralExpression>objectLikeContainer).properties;
|
||||
}
|
||||
else if (objectLikeContainer.kind === SyntaxKind.ObjectBindingPattern) {
|
||||
@@ -849,7 +862,10 @@ namespace ts.Completions {
|
||||
}
|
||||
}
|
||||
if (canGetType) {
|
||||
typeForObject = typeChecker.getTypeAtLocation(objectLikeContainer);
|
||||
const typeForObject = typeChecker.getTypeAtLocation(objectLikeContainer);
|
||||
if (!typeForObject) return false;
|
||||
// In a binding pattern, get only known properties. Everywhere else we will get all possible properties.
|
||||
typeMembers = typeChecker.getPropertiesOfType(typeForObject);
|
||||
existingMembers = (<ObjectBindingPattern>objectLikeContainer).elements;
|
||||
}
|
||||
}
|
||||
@@ -861,11 +877,6 @@ namespace ts.Completions {
|
||||
Debug.fail("Expected object literal or binding pattern, got " + objectLikeContainer.kind);
|
||||
}
|
||||
|
||||
if (!typeForObject) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const typeMembers = typeChecker.getPropertiesOfType(typeForObject);
|
||||
if (typeMembers && typeMembers.length > 0) {
|
||||
// Add filtered items to the completion list
|
||||
symbols = filterObjectMembersList(typeMembers, existingMembers);
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -637,7 +637,9 @@ namespace ts.FindAllReferences.Core {
|
||||
return parent ? scope.getSourceFile() : scope;
|
||||
}
|
||||
|
||||
function getPossibleSymbolReferencePositions(sourceFile: SourceFile, symbolName: string, start: number, end: number): number[] {
|
||||
function getPossibleSymbolReferencePositions(sourceFile: SourceFile, symbolName: string, container: Node = sourceFile, fullStart = false): number[] {
|
||||
const start = fullStart ? container.getFullStart() : container.getStart(sourceFile);
|
||||
const end = container.getEnd();
|
||||
const positions: number[] = [];
|
||||
|
||||
/// TODO: Cache symbol existence for files to save text search
|
||||
@@ -676,16 +678,11 @@ namespace ts.FindAllReferences.Core {
|
||||
const references: Entry[] = [];
|
||||
const sourceFile = container.getSourceFile();
|
||||
const labelName = targetLabel.text;
|
||||
const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, labelName, container.getStart(), container.getEnd());
|
||||
const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, labelName, container);
|
||||
for (const position of possiblePositions) {
|
||||
const node = getTouchingWord(sourceFile, position);
|
||||
if (!node || node.getWidth() !== labelName.length) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Only pick labels that are either the target label, or have a target that is the target label
|
||||
if (node === targetLabel ||
|
||||
(isJumpStatementTarget(node) && getTargetLabel(node, labelName) === targetLabel)) {
|
||||
if (node && (node === targetLabel || (isJumpStatementTarget(node) && getTargetLabel(node, labelName) === targetLabel))) {
|
||||
references.push(nodeEntry(node));
|
||||
}
|
||||
}
|
||||
@@ -697,15 +694,14 @@ namespace ts.FindAllReferences.Core {
|
||||
// Compare the length so we filter out strict superstrings of the symbol we are looking for
|
||||
switch (node && node.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
return node.getWidth() === searchSymbolName.length;
|
||||
return unescapeIdentifier((node as Identifier).text).length === searchSymbolName.length;
|
||||
|
||||
case SyntaxKind.StringLiteral:
|
||||
return (isLiteralNameOfPropertyDeclarationOrIndexAccess(node) || isNameOfExternalModuleImportOrDeclaration(node)) &&
|
||||
// For string literals we have two additional chars for the quotes
|
||||
node.getWidth() === searchSymbolName.length + 2;
|
||||
(node as StringLiteral).text.length === searchSymbolName.length;
|
||||
|
||||
case SyntaxKind.NumericLiteral:
|
||||
return isLiteralNameOfPropertyDeclarationOrIndexAccess(node) && node.getWidth() === searchSymbolName.length;
|
||||
return isLiteralNameOfPropertyDeclarationOrIndexAccess(node) && (node as NumericLiteral).text.length === searchSymbolName.length;
|
||||
|
||||
default:
|
||||
return false;
|
||||
@@ -722,7 +718,7 @@ namespace ts.FindAllReferences.Core {
|
||||
}
|
||||
|
||||
function addReferencesForKeywordInFile(sourceFile: SourceFile, kind: SyntaxKind, searchText: string, references: Push<NodeEntry>): void {
|
||||
const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, searchText, sourceFile.getStart(), sourceFile.getEnd());
|
||||
const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, searchText);
|
||||
for (const position of possiblePositions) {
|
||||
const referenceLocation = getTouchingPropertyName(sourceFile, position);
|
||||
if (referenceLocation.kind === kind) {
|
||||
@@ -746,9 +742,7 @@ namespace ts.FindAllReferences.Core {
|
||||
return;
|
||||
}
|
||||
|
||||
const start = state.findInComments ? container.getFullStart() : container.getStart();
|
||||
const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, search.text, start, container.getEnd());
|
||||
for (const position of possiblePositions) {
|
||||
for (const position of getPossibleSymbolReferencePositions(sourceFile, search.text, container, /*fullStart*/ state.findInComments)) {
|
||||
getReferencesAtLocation(sourceFile, position, search, state);
|
||||
}
|
||||
}
|
||||
@@ -1192,7 +1186,7 @@ namespace ts.FindAllReferences.Core {
|
||||
const references: Entry[] = [];
|
||||
|
||||
const sourceFile = searchSpaceNode.getSourceFile();
|
||||
const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "super", searchSpaceNode.getStart(), searchSpaceNode.getEnd());
|
||||
const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "super", searchSpaceNode);
|
||||
for (const position of possiblePositions) {
|
||||
const node = getTouchingWord(sourceFile, position);
|
||||
|
||||
@@ -1254,13 +1248,13 @@ namespace ts.FindAllReferences.Core {
|
||||
if (searchSpaceNode.kind === SyntaxKind.SourceFile) {
|
||||
forEach(sourceFiles, sourceFile => {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "this", sourceFile.getStart(), sourceFile.getEnd());
|
||||
possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "this");
|
||||
getThisReferencesInFile(sourceFile, sourceFile, possiblePositions, references);
|
||||
});
|
||||
}
|
||||
else {
|
||||
const sourceFile = searchSpaceNode.getSourceFile();
|
||||
possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "this", searchSpaceNode.getStart(), searchSpaceNode.getEnd());
|
||||
possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "this", searchSpaceNode);
|
||||
getThisReferencesInFile(sourceFile, searchSpaceNode, possiblePositions, references);
|
||||
}
|
||||
|
||||
@@ -1314,7 +1308,7 @@ namespace ts.FindAllReferences.Core {
|
||||
|
||||
for (const sourceFile of sourceFiles) {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, node.text, sourceFile.getStart(), sourceFile.getEnd());
|
||||
const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, node.text);
|
||||
getReferencesForStringLiteralInFile(sourceFile, node.text, possiblePositions, references);
|
||||
}
|
||||
|
||||
|
||||
@@ -50,19 +50,10 @@ namespace ts.GoToDefinition {
|
||||
// get the aliased symbol instead. This allows for goto def on an import e.g.
|
||||
// import {A, B} from "mod";
|
||||
// to jump to the implementation directly.
|
||||
if (symbol.flags & SymbolFlags.Alias) {
|
||||
const declaration = symbol.declarations[0];
|
||||
|
||||
// Go to the original declaration for cases:
|
||||
//
|
||||
// (1) when the aliased symbol was declared in the location(parent).
|
||||
// (2) when the aliased symbol is originating from a named import.
|
||||
//
|
||||
if (node.kind === SyntaxKind.Identifier &&
|
||||
(node.parent === declaration ||
|
||||
(declaration.kind === SyntaxKind.ImportSpecifier && declaration.parent && declaration.parent.kind === SyntaxKind.NamedImports))) {
|
||||
|
||||
symbol = typeChecker.getAliasedSymbol(symbol);
|
||||
if (symbol.flags & SymbolFlags.Alias && shouldSkipAlias(node, symbol.declarations[0])) {
|
||||
const aliased = typeChecker.getAliasedSymbol(symbol);
|
||||
if (aliased.declarations) {
|
||||
symbol = aliased;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,17 +76,6 @@ namespace ts.GoToDefinition {
|
||||
declaration => createDefinitionInfo(declaration, shorthandSymbolKind, shorthandSymbolName, shorthandContainerName));
|
||||
}
|
||||
|
||||
if (isJsxOpeningLikeElement(node.parent)) {
|
||||
// If there are errors when trying to figure out stateless component function, just return the first declaration
|
||||
// For example:
|
||||
// declare function /*firstSource*/MainButton(buttonProps: ButtonProps): JSX.Element;
|
||||
// declare function /*secondSource*/MainButton(linkProps: LinkProps): JSX.Element;
|
||||
// declare function /*thirdSource*/MainButton(props: ButtonProps | LinkProps): JSX.Element;
|
||||
// let opt = <Main/*firstTarget*/Button />; // Error - We get undefined for resolved signature indicating an error, then just return the first declaration
|
||||
const {symbolName, symbolKind, containerName} = getSymbolInfo(typeChecker, symbol, node);
|
||||
return [createDefinitionInfo(symbol.valueDeclaration, symbolKind, symbolName, containerName)];
|
||||
}
|
||||
|
||||
// If the current location we want to find its definition is in an object literal, try to get the contextual type for the
|
||||
// object literal, lookup the property symbol in the contextual type, and use this for goto-definition.
|
||||
// For example
|
||||
@@ -106,15 +86,9 @@ namespace ts.GoToDefinition {
|
||||
// function Foo(arg: Props) {}
|
||||
// Foo( { pr/*1*/op1: 10, prop2: true })
|
||||
const element = getContainingObjectLiteralElement(node);
|
||||
if (element) {
|
||||
if (typeChecker.getContextualType(element.parent as Expression)) {
|
||||
const result: DefinitionInfo[] = [];
|
||||
const propertySymbols = getPropertySymbolsFromContextualType(typeChecker, element);
|
||||
for (const propertySymbol of propertySymbols) {
|
||||
result.push(...getDefinitionFromSymbol(typeChecker, propertySymbol, node));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
if (element && typeChecker.getContextualType(element.parent as Expression)) {
|
||||
return flatMap(getPropertySymbolsFromContextualType(typeChecker, element), propertySymbol =>
|
||||
getDefinitionFromSymbol(typeChecker, propertySymbol, node));
|
||||
}
|
||||
return getDefinitionFromSymbol(typeChecker, symbol, node);
|
||||
}
|
||||
@@ -153,6 +127,29 @@ namespace ts.GoToDefinition {
|
||||
return getDefinitionFromSymbol(typeChecker, type.symbol, node);
|
||||
}
|
||||
|
||||
// Go to the original declaration for cases:
|
||||
//
|
||||
// (1) when the aliased symbol was declared in the location(parent).
|
||||
// (2) when the aliased symbol is originating from an import.
|
||||
//
|
||||
function shouldSkipAlias(node: Node, declaration: Node): boolean {
|
||||
if (node.kind !== SyntaxKind.Identifier) {
|
||||
return false;
|
||||
}
|
||||
if (node.parent === declaration) {
|
||||
return true;
|
||||
}
|
||||
switch (declaration.kind) {
|
||||
case SyntaxKind.ImportClause:
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
return true;
|
||||
case SyntaxKind.ImportSpecifier:
|
||||
return declaration.parent.kind === SyntaxKind.NamedImports;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function getDefinitionFromSymbol(typeChecker: TypeChecker, symbol: Symbol, node: Node): DefinitionInfo[] {
|
||||
const result: DefinitionInfo[] = [];
|
||||
const declarations = symbol.getDeclarations();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
//// [tests/cases/compiler/blockScopedNamespaceDifferentFile.ts] ////
|
||||
|
||||
//// [test.ts]
|
||||
// #15734 failed when test.ts comes before typings.d.ts
|
||||
namespace C {
|
||||
export class Name {
|
||||
static funcData = A.AA.func();
|
||||
static someConst = A.AA.foo;
|
||||
|
||||
constructor(parameters) {}
|
||||
}
|
||||
}
|
||||
|
||||
//// [typings.d.ts]
|
||||
declare namespace A {
|
||||
namespace AA {
|
||||
function func(): number;
|
||||
const foo = "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [out.js]
|
||||
// #15734 failed when test.ts comes before typings.d.ts
|
||||
var C;
|
||||
(function (C) {
|
||||
var Name = (function () {
|
||||
function Name(parameters) {
|
||||
}
|
||||
return Name;
|
||||
}());
|
||||
Name.funcData = A.AA.func();
|
||||
Name.someConst = A.AA.foo;
|
||||
C.Name = Name;
|
||||
})(C || (C = {}));
|
||||
@@ -0,0 +1,44 @@
|
||||
=== tests/cases/compiler/test.ts ===
|
||||
// #15734 failed when test.ts comes before typings.d.ts
|
||||
namespace C {
|
||||
>C : Symbol(C, Decl(test.ts, 0, 0))
|
||||
|
||||
export class Name {
|
||||
>Name : Symbol(Name, Decl(test.ts, 1, 13))
|
||||
|
||||
static funcData = A.AA.func();
|
||||
>funcData : Symbol(Name.funcData, Decl(test.ts, 2, 23))
|
||||
>A.AA.func : Symbol(A.AA.func, Decl(typings.d.ts, 1, 18))
|
||||
>A.AA : Symbol(A.AA, Decl(typings.d.ts, 0, 21))
|
||||
>A : Symbol(A, Decl(typings.d.ts, 0, 0))
|
||||
>AA : Symbol(A.AA, Decl(typings.d.ts, 0, 21))
|
||||
>func : Symbol(A.AA.func, Decl(typings.d.ts, 1, 18))
|
||||
|
||||
static someConst = A.AA.foo;
|
||||
>someConst : Symbol(Name.someConst, Decl(test.ts, 3, 38))
|
||||
>A.AA.foo : Symbol(A.AA.foo, Decl(typings.d.ts, 3, 13))
|
||||
>A.AA : Symbol(A.AA, Decl(typings.d.ts, 0, 21))
|
||||
>A : Symbol(A, Decl(typings.d.ts, 0, 0))
|
||||
>AA : Symbol(A.AA, Decl(typings.d.ts, 0, 21))
|
||||
>foo : Symbol(A.AA.foo, Decl(typings.d.ts, 3, 13))
|
||||
|
||||
constructor(parameters) {}
|
||||
>parameters : Symbol(parameters, Decl(test.ts, 6, 20))
|
||||
}
|
||||
}
|
||||
|
||||
=== tests/cases/compiler/typings.d.ts ===
|
||||
declare namespace A {
|
||||
>A : Symbol(A, Decl(typings.d.ts, 0, 0))
|
||||
|
||||
namespace AA {
|
||||
>AA : Symbol(AA, Decl(typings.d.ts, 0, 21))
|
||||
|
||||
function func(): number;
|
||||
>func : Symbol(func, Decl(typings.d.ts, 1, 18))
|
||||
|
||||
const foo = "";
|
||||
>foo : Symbol(foo, Decl(typings.d.ts, 3, 13))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
=== tests/cases/compiler/test.ts ===
|
||||
// #15734 failed when test.ts comes before typings.d.ts
|
||||
namespace C {
|
||||
>C : typeof C
|
||||
|
||||
export class Name {
|
||||
>Name : Name
|
||||
|
||||
static funcData = A.AA.func();
|
||||
>funcData : number
|
||||
>A.AA.func() : number
|
||||
>A.AA.func : () => number
|
||||
>A.AA : typeof A.AA
|
||||
>A : typeof A
|
||||
>AA : typeof A.AA
|
||||
>func : () => number
|
||||
|
||||
static someConst = A.AA.foo;
|
||||
>someConst : string
|
||||
>A.AA.foo : ""
|
||||
>A.AA : typeof A.AA
|
||||
>A : typeof A
|
||||
>AA : typeof A.AA
|
||||
>foo : ""
|
||||
|
||||
constructor(parameters) {}
|
||||
>parameters : any
|
||||
}
|
||||
}
|
||||
|
||||
=== tests/cases/compiler/typings.d.ts ===
|
||||
declare namespace A {
|
||||
>A : typeof A
|
||||
|
||||
namespace AA {
|
||||
>AA : typeof AA
|
||||
|
||||
function func(): number;
|
||||
>func : () => number
|
||||
|
||||
const foo = "";
|
||||
>foo : ""
|
||||
>"" : ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
=== tests/cases/compiler/a.js ===
|
||||
class C {
|
||||
>C : Symbol(C, Decl(a.js, 0, 0))
|
||||
|
||||
constructor() {
|
||||
/** @type {boolean} */
|
||||
this.a = true;
|
||||
>this.a : Symbol(C.a, Decl(a.js, 1, 16), Decl(a.js, 3, 16))
|
||||
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||
>a : Symbol(C.a, Decl(a.js, 1, 16), Decl(a.js, 3, 16))
|
||||
|
||||
this.a = !!this.a;
|
||||
>this.a : Symbol(C.a, Decl(a.js, 1, 16), Decl(a.js, 3, 16))
|
||||
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||
>a : Symbol(C.a, Decl(a.js, 1, 16), Decl(a.js, 3, 16))
|
||||
>this.a : Symbol(C.a, Decl(a.js, 1, 16), Decl(a.js, 3, 16))
|
||||
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||
>a : Symbol(C.a, Decl(a.js, 1, 16), Decl(a.js, 3, 16))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
=== tests/cases/compiler/a.js ===
|
||||
class C {
|
||||
>C : C
|
||||
|
||||
constructor() {
|
||||
/** @type {boolean} */
|
||||
this.a = true;
|
||||
>this.a = true : true
|
||||
>this.a : boolean
|
||||
>this : this
|
||||
>a : boolean
|
||||
>true : true
|
||||
|
||||
this.a = !!this.a;
|
||||
>this.a = !!this.a : boolean
|
||||
>this.a : boolean
|
||||
>this : this
|
||||
>a : boolean
|
||||
>!!this.a : boolean
|
||||
>!this.a : boolean
|
||||
>this.a : true
|
||||
>this : this
|
||||
>a : true
|
||||
}
|
||||
}
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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>; };
|
||||
};
|
||||
@@ -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))
|
||||
|
||||
};
|
||||
@@ -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; }'.
|
||||
};
|
||||
@@ -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>; };
|
||||
};
|
||||
@@ -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));
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
@@ -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; }'.
|
||||
}
|
||||
}
|
||||
@@ -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; }'.
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
@@ -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));
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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"/>;
|
||||
};
|
||||
@@ -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))
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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}/>;
|
||||
};
|
||||
@@ -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))
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
// @target: es5
|
||||
// @outFile: out.js
|
||||
// @module: amd
|
||||
|
||||
// #15734 failed when test.ts comes before typings.d.ts
|
||||
// @Filename: test.ts
|
||||
namespace C {
|
||||
export class Name {
|
||||
static funcData = A.AA.func();
|
||||
static someConst = A.AA.foo;
|
||||
|
||||
constructor(parameters) {}
|
||||
}
|
||||
}
|
||||
|
||||
// @Filename: typings.d.ts
|
||||
declare namespace A {
|
||||
namespace AA {
|
||||
function func(): number;
|
||||
const foo = "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @noEmit: true
|
||||
// @noImplicitAny: true
|
||||
// @fileName: a.js
|
||||
class C {
|
||||
constructor() {
|
||||
/** @type {boolean} */
|
||||
this.a = true;
|
||||
this.a = !!this.a;
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
};
|
||||
@@ -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>
|
||||
};
|
||||
@@ -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" />;
|
||||
}
|
||||
}
|
||||
@@ -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" />;
|
||||
}
|
||||
}
|
||||
@@ -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" />;
|
||||
}
|
||||
}
|
||||
@@ -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" />;
|
||||
}
|
||||
}
|
||||
@@ -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"/>;
|
||||
}
|
||||
@@ -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} />;
|
||||
}
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
verify.quickInfoAt("useFoo", "import foo");
|
||||
verify.goToDefinition({
|
||||
useFoo: "importFoo",
|
||||
useFoo: "module",
|
||||
importFoo: "module"
|
||||
});
|
||||
|
||||
@@ -27,6 +27,6 @@ verify.goToDefinition({
|
||||
|
||||
verify.quickInfoAt("useBang", "import bang = require(\"jquery\")");
|
||||
verify.goToDefinition({
|
||||
useBang: "importBang",
|
||||
useBang: "module",
|
||||
importBang: "module"
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
]);
|
||||
@@ -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"
|
||||
]);
|
||||
@@ -0,0 +1,10 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////function foo(x: "bla"): void;
|
||||
////function foo(x: "bla"): void;
|
||||
////function foo(x: string) {}
|
||||
////foo("/**/")
|
||||
|
||||
goTo.marker();
|
||||
verify.completionListContains("bla");
|
||||
verify.completionListCount(1);
|
||||
@@ -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");
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @strictNullChecks: true
|
||||
|
||||
// Non-objects should be skipped, so `| number | null` should have no effect on completions.
|
||||
////const x: { a: number, b: number } | { a: string, c: string } | { b: boolean } | number | null = { /*x*/ };
|
||||
|
||||
////interface I { a: number; }
|
||||
////function f(...args: Array<I | I[]>) {}
|
||||
////f({ /*f*/ });
|
||||
|
||||
goTo.marker("x");
|
||||
verify.completionListContains("a", "(property) a: string | number");
|
||||
verify.completionListContains("b", "(property) b: number | boolean");
|
||||
verify.completionListContains("c", "(property) c: string");
|
||||
|
||||
goTo.marker("f");
|
||||
verify.completionListContains("a", "(property) a: number");
|
||||
@@ -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');
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
// @Filename: /a.ts
|
||||
////export default function /*fDef*/f() {}
|
||||
////export const /*xDef*/x = 0;
|
||||
|
||||
// @Filename: /b.ts
|
||||
/////*bDef*/declare const b: number;
|
||||
////export = b;
|
||||
|
||||
// @Filename: /b.ts
|
||||
////import f, { x } from "./a";
|
||||
////import * as /*aDef*/a from "./a";
|
||||
////import b = require("./b");
|
||||
/////*fUse*/f;
|
||||
/////*xUse*/x;
|
||||
/////*aUse*/a;
|
||||
/////*bUse*/b;
|
||||
|
||||
verify.goToDefinition({
|
||||
aUse: "aDef", // Namespace import isn't "skipped"
|
||||
fUse: "fDef",
|
||||
xUse: "xDef",
|
||||
bUse: "bDef",
|
||||
});
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
////not read
|
||||
|
||||
// @Filename: /a.ts
|
||||
////import { f } from "foo";
|
||||
/////**/f();
|
||||
////import { /*def*/f } from "foo";
|
||||
/////*use*/f();
|
||||
|
||||
verify.goToDefinition("", []);
|
||||
verify.goToDefinition("use", "def");
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
// @Filename: foo.d.ts
|
||||
////declare const /*foo_value_declaration*/foo: number;
|
||||
////declare module "foo_module" {
|
||||
//// interface I { x: number; y: number }
|
||||
//// interface /*foo_type_declaration*/I { x: number; y: number }
|
||||
//// export = I;
|
||||
////}
|
||||
|
||||
// @Filename: foo_user.ts
|
||||
///////<reference path="foo.d.ts" />
|
||||
////import /*foo_type_declaration*/foo = require("foo_module");
|
||||
////import foo = require("foo_module");
|
||||
////const x = foo/*foo_value*/;
|
||||
////const i: foo/*foo_type*/ = { x: 1, y: 2 };
|
||||
|
||||
@@ -39,13 +39,13 @@ verify.goToDefinitionIs("foo_type_declaration");
|
||||
// @Filename: bar.d.ts
|
||||
////declare interface /*bar_type_declaration*/bar { x: number; y: number }
|
||||
////declare module "bar_module" {
|
||||
//// const x: number;
|
||||
//// const /*bar_value_declaration*/x: number;
|
||||
//// export = x;
|
||||
////}
|
||||
|
||||
// @Filename: bar_user.ts
|
||||
///////<reference path="bar.d.ts" />
|
||||
////import /*bar_value_declaration*/bar = require("bar_module");
|
||||
////import bar = require("bar_module");
|
||||
////const x = bar/*bar_value*/;
|
||||
////const i: bar/*bar_type*/ = { x: 1, y: 2 };
|
||||
|
||||
|
||||
@@ -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, [
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @jsx: preserve
|
||||
|
||||
// @Filename: C.tsx
|
||||
////export default class /*def*/C {}
|
||||
|
||||
// @Filename: a.tsx
|
||||
////import C from "./C";
|
||||
////const foo = </*use*/C />;
|
||||
|
||||
verify.noErrors();
|
||||
|
||||
goTo.marker("use");
|
||||
verify.goToDefinitionIs("def");
|
||||
@@ -17,6 +17,6 @@ const [r0, r1, r2] = test.ranges();
|
||||
verify.singleReferenceGroup('"foo"', [r1]);
|
||||
|
||||
goTo.marker("foo");
|
||||
verify.goToDefinitionIs([]);
|
||||
verify.goToDefinitionIs("foo");
|
||||
verify.quickInfoIs("import foo");
|
||||
verify.singleReferenceGroup("import foo", [r0, r2]);
|
||||
|
||||
Vendored
+1
-1
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user