Merge branch 'master' into jsdoc

This commit is contained in:
Andy Hanson
2017-05-17 07:17:32 -07:00
104 changed files with 3234 additions and 757 deletions
+8 -2
View File
@@ -935,7 +935,7 @@ gulp.task(loggedIOJsPath, /*help*/ false, [], (done) => {
const temp = path.join(builtLocalDirectory, "temp");
mkdirP(temp, (err) => {
if (err) { console.error(err); done(err); process.exit(1); }
exec(host, [LKGCompiler, "--types --outdir", temp, loggedIOpath], () => {
exec(host, [LKGCompiler, "--types", "--target es5", "--lib es5", "--outdir", temp, loggedIOpath], () => {
fs.renameSync(path.join(temp, "/harness/loggedIO.js"), loggedIOJsPath);
del(temp).then(() => done(), done);
}, done);
@@ -946,7 +946,13 @@ const instrumenterPath = path.join(harnessDirectory, "instrumenter.ts");
const instrumenterJsPath = path.join(builtLocalDirectory, "instrumenter.js");
gulp.task(instrumenterJsPath, /*help*/ false, [servicesFile], () => {
const settings: tsc.Settings = getCompilerSettings({
outFile: instrumenterJsPath
outFile: instrumenterJsPath,
target: "es5",
lib: [
"es6",
"dom",
"scripthost"
]
}, /*useBuiltCompiler*/ true);
return gulp.src(instrumenterPath)
.pipe(newer(instrumenterJsPath))
+361 -258
View File
File diff suppressed because it is too large Load Diff
+31
View File
@@ -230,6 +230,8 @@ namespace ts {
* If no such value is found, it applies the callback until the parent pointer is undefined or the callback returns "quit"
* At that point findAncestor returns undefined.
*/
export function findAncestor<T extends Node>(node: Node, callback: (element: Node) => element is T): T | undefined;
export function findAncestor(node: Node, callback: (element: Node) => boolean | "quit"): Node | undefined;
export function findAncestor(node: Node, callback: (element: Node) => boolean | "quit"): Node {
while (node) {
const result = callback(node);
@@ -490,6 +492,35 @@ namespace ts {
return result;
}
/**
* Maps an array. If the mapped value is an array, it is spread into the result.
* Avoids allocation if all elements map to themselves.
*
* @param array The array to map.
* @param mapfn The callback used to map the result into one or more values.
*/
export function sameFlatMap<T>(array: T[], mapfn: (x: T, i: number) => T | T[]): T[] {
let result: T[];
if (array) {
for (let i = 0; i < array.length; i++) {
const item = array[i];
const mapped = mapfn(item, i);
if (result || item !== mapped || isArray(mapped)) {
if (!result) {
result = array.slice(0, i);
}
if (isArray(mapped)) {
addRange(result, mapped);
}
else {
result.push(mapped);
}
}
}
}
return result || array;
}
/**
* Computes the first matching span of elements and returns a tuple of the first span
* and the remaining elements.
+50 -14
View File
@@ -153,7 +153,7 @@ namespace ts {
for (let i = 0; i < numNodes; i++) {
const currentNode = bundle ? bundle.sourceFiles[i] : node;
const sourceFile = isSourceFile(currentNode) ? currentNode : currentSourceFile;
const shouldSkip = compilerOptions.noEmitHelpers || (sourceFile && getExternalHelpersModuleName(sourceFile) !== undefined);
const shouldSkip = compilerOptions.noEmitHelpers || getExternalHelpersModuleName(sourceFile) !== undefined;
const shouldBundle = isSourceFile(currentNode) && !isOwnFileEmit;
const helpers = getEmitHelpers(currentNode);
if (helpers) {
@@ -212,7 +212,7 @@ namespace ts {
emitLeadingCommentsOfPosition,
} = comments;
let currentSourceFile: SourceFile;
let currentSourceFile: SourceFile | undefined;
let nodeIdToGeneratedName: string[]; // Map of generated names for specific nodes.
let autoGeneratedIdToGeneratedName: string[]; // Map of generated names for temp and loop variables.
let generatedNames: Map<string>; // Set of names generated by the NameGenerator.
@@ -264,7 +264,12 @@ namespace ts {
return endPrint();
}
function writeNode(hint: EmitHint, node: Node, sourceFile: SourceFile, output: EmitTextWriter) {
/**
* If `sourceFile` is `undefined`, `node` must be a synthesized `TypeNode`.
*/
function writeNode(hint: EmitHint, node: TypeNode, sourceFile: undefined, output: EmitTextWriter): void;
function writeNode(hint: EmitHint, node: Node, sourceFile: SourceFile, output: EmitTextWriter): void;
function writeNode(hint: EmitHint, node: Node, sourceFile: SourceFile | undefined, output: EmitTextWriter) {
const previousWriter = writer;
setWriter(output);
print(hint, node, sourceFile);
@@ -305,8 +310,10 @@ namespace ts {
return text;
}
function print(hint: EmitHint, node: Node, sourceFile: SourceFile) {
setSourceFile(sourceFile);
function print(hint: EmitHint, node: Node, sourceFile: SourceFile | undefined) {
if (sourceFile) {
setSourceFile(sourceFile);
}
pipelineEmitWithNotification(hint, node);
}
@@ -733,6 +740,9 @@ namespace ts {
// Transformation nodes
case SyntaxKind.PartiallyEmittedExpression:
return emitPartiallyEmittedExpression(<PartiallyEmittedExpression>node);
case SyntaxKind.CommaListExpression:
return emitCommaList(<CommaListExpression>node);
}
}
@@ -778,6 +788,7 @@ namespace ts {
function emitIdentifier(node: Identifier) {
write(getTextOfNode(node, /*includeTrivia*/ false));
emitTypeArguments(node, node.typeArguments);
}
//
@@ -812,6 +823,7 @@ namespace ts {
function emitTypeParameter(node: TypeParameterDeclaration) {
emit(node.name);
emitWithPrefix(" extends ", node.constraint);
emitWithPrefix(" = ", node.default);
}
function emitParameter(node: ParameterDeclaration) {
@@ -952,7 +964,10 @@ namespace ts {
function emitTypeLiteral(node: TypeLiteralNode) {
write("{");
emitList(node, node.members, ListFormat.TypeLiteralMembers);
// If the literal is empty, do not add spaces between braces.
if (node.members.length > 0) {
emitList(node, node.members, getEmitFlags(node) & EmitFlags.SingleLine ? ListFormat.SingleLineTypeLiteralMembers : ListFormat.MultiLineTypeLiteralMembers);
}
write("}");
}
@@ -999,9 +1014,15 @@ namespace ts {
}
function emitMappedType(node: MappedTypeNode) {
const emitFlags = getEmitFlags(node);
write("{");
writeLine();
increaseIndent();
if (emitFlags & EmitFlags.SingleLine) {
write(" ");
}
else {
writeLine();
increaseIndent();
}
writeIfPresent(node.readonlyToken, "readonly ");
write("[");
emit(node.typeParameter.name);
@@ -1012,8 +1033,13 @@ namespace ts {
write(": ");
emit(node.type);
write(";");
writeLine();
decreaseIndent();
if (emitFlags & EmitFlags.SingleLine) {
write(" ");
}
else {
writeLine();
decreaseIndent();
}
write("}");
}
@@ -1032,7 +1058,7 @@ namespace ts {
}
else {
write("{");
emitList(node, elements, ListFormat.ObjectBindingPatternElements);
emitList(node, elements, getEmitFlags(node) & EmitFlags.SingleLine ? ListFormat.ObjectBindingPatternElements : ListFormat.ObjectBindingPatternElementsWithSpaceBetweenBraces);
write("}");
}
}
@@ -2101,6 +2127,10 @@ namespace ts {
emitExpression(node.expression);
}
function emitCommaList(node: CommaListExpression) {
emitExpressionList(node, node.elements, ListFormat.CommaListElements);
}
/**
* Emits any prologue directives at the start of a Statement list, returning the
* number of prologue directives written to the output.
@@ -2630,7 +2660,9 @@ namespace ts {
if (node.kind === SyntaxKind.StringLiteral && (<StringLiteral>node).textSourceNode) {
const textSourceNode = (<StringLiteral>node).textSourceNode;
if (isIdentifier(textSourceNode)) {
return "\"" + escapeNonAsciiCharacters(escapeString(getTextOfNode(textSourceNode))) + "\"";
return getEmitFlags(node) & EmitFlags.NoAsciiEscaping ?
`"${escapeString(getTextOfNode(textSourceNode))}"` :
`"${escapeNonAsciiString(getTextOfNode(textSourceNode))}"`;
}
else {
return getLiteralTextOfNode(textSourceNode);
@@ -2943,14 +2975,18 @@ namespace ts {
// Precomputed Formats
Modifiers = SingleLine | SpaceBetweenSiblings,
HeritageClauses = SingleLine | SpaceBetweenSiblings,
TypeLiteralMembers = MultiLine | Indented,
SingleLineTypeLiteralMembers = SingleLine | SpaceBetweenBraces | SpaceBetweenSiblings | Indented,
MultiLineTypeLiteralMembers = MultiLine | Indented,
TupleTypeElements = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented,
UnionTypeConstituents = BarDelimited | SpaceBetweenSiblings | SingleLine,
IntersectionTypeConstituents = AmpersandDelimited | SpaceBetweenSiblings | SingleLine,
ObjectBindingPatternElements = SingleLine | AllowTrailingComma | SpaceBetweenBraces | CommaDelimited | SpaceBetweenSiblings,
ObjectBindingPatternElements = SingleLine | CommaDelimited | SpaceBetweenSiblings,
ObjectBindingPatternElementsWithSpaceBetweenBraces = SingleLine | AllowTrailingComma | SpaceBetweenBraces | CommaDelimited | SpaceBetweenSiblings,
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,
+101 -21
View File
@@ -107,15 +107,27 @@ namespace ts {
// Identifiers
export function createIdentifier(text: string): Identifier {
export function createIdentifier(text: string): Identifier;
/* @internal */
export function createIdentifier(text: string, typeArguments: TypeNode[]): Identifier;
export function createIdentifier(text: string, typeArguments?: TypeNode[]): Identifier {
const node = <Identifier>createSynthesizedNode(SyntaxKind.Identifier);
node.text = escapeIdentifier(text);
node.originalKeywordKind = text ? stringToToken(text) : SyntaxKind.Unknown;
node.autoGenerateKind = GeneratedIdentifierKind.None;
node.autoGenerateId = 0;
if (typeArguments) {
node.typeArguments = createNodeArray(typeArguments);
}
return node;
}
export function updateIdentifier(node: Identifier, typeArguments: NodeArray<TypeNode> | undefined): Identifier {
return node.typeArguments !== typeArguments
? updateNode(createIdentifier(node.text, typeArguments), node)
: node;
}
let nextAutoGenerateId = 0;
/** Create a unique temporary variable. */
@@ -271,8 +283,9 @@ namespace ts {
// Type Elements
export function createPropertySignature(name: PropertyName | string, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertySignature {
export function createPropertySignature(modifiers: Modifier[] | undefined, name: PropertyName | string, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertySignature {
const node = createSynthesizedNode(SyntaxKind.PropertySignature) as PropertySignature;
node.modifiers = asNodeArray(modifiers);
node.name = asName(name);
node.questionToken = questionToken;
node.type = type;
@@ -280,12 +293,13 @@ namespace ts {
return node;
}
export function updatePropertySignature(node: PropertySignature, name: PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) {
return node.name !== name
export function updatePropertySignature(node: PropertySignature, modifiers: Modifier[] | undefined, name: PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) {
return node.modifiers !== modifiers
|| node.name !== name
|| node.questionToken !== questionToken
|| node.type !== type
|| node.initializer !== initializer
? updateNode(createPropertySignature(name, questionToken, type, initializer), node)
? updateNode(createPropertySignature(modifiers, name, questionToken, type, initializer), node)
: node;
}
@@ -492,7 +506,7 @@ namespace ts {
export function createTypeReferenceNode(typeName: string | EntityName, typeArguments: TypeNode[] | undefined) {
const node = createSynthesizedNode(SyntaxKind.TypeReference) as TypeReferenceNode;
node.typeName = asName(typeName);
node.typeArguments = asNodeArray(typeArguments);
node.typeArguments = typeArguments && parenthesizeTypeParameters(typeArguments);
return node;
}
@@ -545,7 +559,7 @@ namespace ts {
export function createArrayTypeNode(elementType: TypeNode) {
const node = createSynthesizedNode(SyntaxKind.ArrayType) as ArrayTypeNode;
node.elementType = elementType;
node.elementType = parenthesizeElementTypeMember(elementType);
return node;
}
@@ -585,7 +599,7 @@ namespace ts {
export function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, types: TypeNode[]) {
const node = createSynthesizedNode(kind) as UnionTypeNode | IntersectionTypeNode;
node.types = createNodeArray(types);
node.types = parenthesizeElementTypeMembers(types);
return node;
}
@@ -614,7 +628,7 @@ namespace ts {
export function createTypeOperatorNode(type: TypeNode) {
const node = createSynthesizedNode(SyntaxKind.TypeOperator) as TypeOperatorNode;
node.operator = SyntaxKind.KeyOfKeyword;
node.type = type;
node.type = parenthesizeElementTypeMember(type);
return node;
}
@@ -624,7 +638,7 @@ namespace ts {
export function createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode) {
const node = createSynthesizedNode(SyntaxKind.IndexedAccessType) as IndexedAccessTypeNode;
node.objectType = objectType;
node.objectType = parenthesizeElementTypeMember(objectType);
node.indexType = indexType;
return node;
}
@@ -2077,6 +2091,30 @@ namespace ts {
return node;
}
function flattenCommaElements(node: Expression): Expression | Expression[] {
if (nodeIsSynthesized(node) && !isParseTreeNode(node) && !node.original && !node.emitNode && !node.id) {
if (node.kind === SyntaxKind.CommaListExpression) {
return (<CommaListExpression>node).elements;
}
if (isBinaryExpression(node) && node.operatorToken.kind === SyntaxKind.CommaToken) {
return [node.left, node.right];
}
}
return node;
}
export function createCommaList(elements: Expression[]) {
const node = <CommaListExpression>createSynthesizedNode(SyntaxKind.CommaListExpression);
node.elements = createNodeArray(sameFlatMap(elements, flattenCommaElements));
return node;
}
export function updateCommaList(node: CommaListExpression, elements: Expression[]) {
return node.elements !== elements
? updateNode(createCommaList(elements), node)
: node;
}
export function createBundle(sourceFiles: SourceFile[]) {
const node = <Bundle>createNode(SyntaxKind.Bundle);
node.sourceFiles = sourceFiles;
@@ -2465,6 +2503,25 @@ namespace ts {
/* @internal */
namespace ts {
export const nullTransformationContext: TransformationContext = {
enableEmitNotification: noop,
enableSubstitution: noop,
endLexicalEnvironment: () => undefined,
getCompilerOptions: notImplemented,
getEmitHost: notImplemented,
getEmitResolver: notImplemented,
hoistFunctionDeclaration: noop,
hoistVariableDeclaration: noop,
isEmitNotificationEnabled: notImplemented,
isSubstitutionEnabled: notImplemented,
onEmitNode: noop,
onSubstituteNode: notImplemented,
readEmitHelpers: notImplemented,
requestEmitHelper: noop,
resumeLexicalEnvironment: noop,
startLexicalEnvironment: noop,
suspendLexicalEnvironment: noop
};
// Compound nodes
@@ -2865,7 +2922,11 @@ namespace ts {
}
export function inlineExpressions(expressions: Expression[]) {
return reduceLeft(expressions, createComma);
// Avoid deeply nested comma expressions as traversing them during emit can result in "Maximum call
// stack size exceeded" errors.
return expressions.length > 10
? createCommaList(expressions)
: reduceLeft(expressions, createComma);
}
export function createExpressionFromEntityName(node: EntityName | Expression): Expression {
@@ -3261,16 +3322,6 @@ namespace ts {
return statements;
}
export function parenthesizeConditionalHead(condition: Expression) {
const conditionalPrecedence = getOperatorPrecedence(SyntaxKind.ConditionalExpression, SyntaxKind.QuestionToken);
const emittedCondition = skipPartiallyEmittedExpressions(condition);
const conditionPrecedence = getExpressionPrecedence(emittedCondition);
if (compareValues(conditionPrecedence, conditionalPrecedence) === Comparison.LessThan) {
return createParen(condition);
}
return condition;
}
/**
* Wraps the operand to a BinaryExpression in parentheses if they are needed to preserve the intended
* order of operations.
@@ -3572,6 +3623,35 @@ namespace ts {
return expression;
}
export function parenthesizeElementTypeMember(member: TypeNode) {
switch (member.kind) {
case SyntaxKind.UnionType:
case SyntaxKind.IntersectionType:
case SyntaxKind.FunctionType:
case SyntaxKind.ConstructorType:
return createParenthesizedType(member);
}
return member;
}
export function parenthesizeElementTypeMembers(members: TypeNode[]) {
return createNodeArray(sameMap(members, parenthesizeElementTypeMember));
}
export function parenthesizeTypeParameters(typeParameters: TypeNode[]) {
if (some(typeParameters)) {
const nodeArray = createNodeArray() as NodeArray<TypeNode>;
for (let i = 0; i < typeParameters.length; ++i) {
const entry = typeParameters[i];
nodeArray.push(i === 0 && isFunctionOrConstructorTypeNode(entry) && entry.typeParameters ?
createParenthesizedType(entry) :
entry);
}
return nodeArray;
}
}
/**
* Clones a series of not-emitted expressions with a new inner expression.
*
+4 -6
View File
@@ -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 {
+6 -4
View File
@@ -23,19 +23,19 @@ namespace ts {
}
}
function visitNode<T>(cbNode: (node: Node) => T, node: Node): T {
function visitNode<T>(cbNode: (node: Node) => T, node: Node): T | undefined {
if (node) {
return cbNode(node);
}
}
function visitNodeArray<T>(cbNodes: (nodes: Node[]) => T, nodes: Node[]) {
function visitNodeArray<T>(cbNodes: (nodes: Node[]) => T, nodes: Node[]): T | undefined {
if (nodes) {
return cbNodes(nodes);
}
}
function visitEachNode<T>(cbNode: (node: Node) => T, nodes: Node[]) {
function visitEachNode<T>(cbNode: (node: Node) => T, nodes: Node[]): T | undefined {
if (nodes) {
for (const node of nodes) {
const result = cbNode(node);
@@ -50,7 +50,7 @@ namespace ts {
// stored in properties. If a 'cbNodes' callback is specified, it is invoked for embedded arrays; otherwise,
// embedded arrays are flattened and the 'cbNode' callback is invoked for each element. If a callback returns
// a truthy value, iteration stops and that value is returned. Otherwise, undefined is returned.
export function forEachChild<T>(node: Node, cbNode: (node: Node) => T, cbNodeArray?: (nodes: NodeArray<Node>) => T): T {
export function forEachChild<T>(node: Node, cbNode: (node: Node) => T | undefined, cbNodeArray?: (nodes: NodeArray<Node>) => T | undefined): T | undefined {
if (!node) {
return;
}
@@ -362,6 +362,8 @@ namespace ts {
return visitNode(cbNode, (<ExternalModuleReference>node).expression);
case SyntaxKind.MissingDeclaration:
return visitNodes(cbNodes, node.decorators);
case SyntaxKind.CommaListExpression:
return visitNodes(cbNodes, (<CommaListExpression>node).elements);
case SyntaxKind.JsxElement:
return visitNode(cbNode, (<JsxElement>node).openingElement) ||
+95
View File
@@ -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;
+7 -6
View File
@@ -712,11 +712,11 @@ namespace ts {
return accumulator;
}
export function forEachLeadingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T) {
export function forEachLeadingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined {
return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ false, cb, state);
}
export function forEachTrailingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T) {
export function forEachTrailingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined {
return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ true, cb, state);
}
@@ -746,10 +746,11 @@ namespace ts {
}
/** Optionally, get the shebang */
export function getShebang(text: string): string {
return shebangTriviaRegex.test(text)
? shebangTriviaRegex.exec(text)[0]
: undefined;
export function getShebang(text: string): string | undefined {
const match = shebangTriviaRegex.exec(text);
if (match) {
return match[0];
}
}
export function isIdentifierStart(ch: number, languageVersion: ScriptTarget): boolean {
+2 -2
View File
@@ -929,8 +929,8 @@ namespace ts {
text: `
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
var i, p;
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
};
`
};
+1 -86
View File
@@ -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) {
+58 -27
View File
@@ -389,6 +389,7 @@ namespace ts {
// Transformation nodes
NotEmittedStatement,
PartiallyEmittedExpression,
CommaListExpression,
MergeDeclarationMarker,
EndOfDeclarationMarker,
@@ -576,10 +577,11 @@ namespace ts {
* 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
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.
isInJSDocNamespace?: boolean; // if the node is a member in a JSDoc namespace
/*@internal*/ autoGenerateId?: number; // Ensures unique generated identifiers get unique names, but clones get the same name.
isInJSDocNamespace?: boolean; // if the node is a member in a JSDoc namespace
/*@internal*/ typeArguments?: NodeArray<TypeNode>; // Only defined on synthesized nodes. Though not syntactically valid, used in emitting diagnostics.
}
// Transient identifier node (marked by id === -1)
@@ -1603,6 +1605,14 @@ namespace ts {
kind: SyntaxKind.EndOfDeclarationMarker;
}
/**
* A list of comma-seperated expressions. This node is only created by transformations.
*/
export interface CommaListExpression extends Expression {
kind: SyntaxKind.CommaListExpression;
elements: NodeArray<Expression>;
}
/**
* Marks the beginning of a merged transformed declaration.
*/
@@ -2518,11 +2528,11 @@ namespace ts {
indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): IndexSignatureDeclaration;
getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[];
getSymbolAtLocation(node: Node): Symbol;
getSymbolAtLocation(node: Node): Symbol | undefined;
getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: string): Symbol[];
getShorthandAssignmentValueSymbol(location: Node): Symbol;
getExportSpecifierLocalTargetSymbol(location: ExportSpecifier): Symbol;
getPropertySymbolOfDestructuringAssignment(location: Identifier): Symbol;
getShorthandAssignmentValueSymbol(location: Node): Symbol | undefined;
getExportSpecifierLocalTargetSymbol(location: ExportSpecifier): Symbol | undefined;
getPropertySymbolOfDestructuringAssignment(location: Identifier): Symbol | undefined;
getTypeAtLocation(node: Node): Type;
getTypeFromTypeNode(node: TypeNode): Type;
signatureToString(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): string;
@@ -2533,15 +2543,15 @@ namespace ts {
getAugmentedPropertiesOfType(type: Type): Symbol[];
getRootSymbols(symbol: Symbol): Symbol[];
getContextualType(node: Expression): Type | undefined;
getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[]): Signature;
getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature;
isImplementationOfOverload(node: FunctionLikeDeclaration): boolean;
getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[]): Signature | undefined;
getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature | undefined;
isImplementationOfOverload(node: FunctionLikeDeclaration): boolean | undefined;
isUndefinedSymbol(symbol: Symbol): boolean;
isArgumentsSymbol(symbol: Symbol): boolean;
isUnknownSymbol(symbol: Symbol): boolean;
/* @internal */ getMergedSymbol(symbol: Symbol): Symbol;
getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number;
getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number | undefined;
isValidPropertyAccess(node: PropertyAccessExpression | QualifiedName, propertyName: string): boolean;
/** Follow all aliases to get the original symbol. */
getAliasedSymbol(symbol: Symbol): Symbol;
@@ -2551,7 +2561,7 @@ namespace ts {
/** Unlike `getExportsOfModule`, this includes properties of an `export =` value. */
/* @internal */ getExportsAndPropertiesOfModule(moduleSymbol: Symbol): Symbol[];
getAllAttributesTypeFromJsxOpeningLikeElement(elementNode: JsxOpeningLikeElement): Type;
getAllAttributesTypeFromJsxOpeningLikeElement(elementNode: JsxOpeningLikeElement): Type | undefined;
getJsxIntrinsicTagNames(): Symbol[];
isOptionalParameter(node: ParameterDeclaration): boolean;
getAmbientModules(): Symbol[];
@@ -2559,10 +2569,10 @@ namespace ts {
tryGetMemberInModuleExports(memberName: string, moduleSymbol: Symbol): Symbol | undefined;
getApparentType(type: Type): Type;
getSuggestionForNonexistentProperty(node: Identifier, containingType: Type): string | undefined;
getSuggestionForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): string;
/* @internal */ getBaseConstraintOfType(type: Type): Type;
getSuggestionForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): string | undefined;
/* @internal */ getBaseConstraintOfType(type: Type): Type | undefined;
/* @internal */ tryFindAmbientModuleWithoutAugmentations(moduleName: string): Symbol;
/* @internal */ tryFindAmbientModuleWithoutAugmentations(moduleName: string): Symbol | undefined;
// Should not be called directly. Should only be accessed through the Program instance.
/* @internal */ getDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[];
@@ -2573,22 +2583,42 @@ 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 {
None = 0,
allowThisInObjectLiteral = 1 << 0,
allowQualifedNameInPlaceOfIdentifier = 1 << 1,
allowTypeParameterInQualifiedName = 1 << 2,
allowAnonymousIdentifier = 1 << 3,
allowEmptyUnionOrIntersection = 1 << 4,
allowEmptyTuple = 1 << 5
// Options
NoTruncation = 1 << 0, // Don't truncate result
WriteArrayAsGenericType = 1 << 1, // Write Array<T> instead T[]
WriteTypeArgumentsOfSignature = 1 << 5, // Write the type arguments instead of type parameters of the signature
UseFullyQualifiedType = 1 << 6, // Write out the fully qualified type name (eg. Module.Type, instead of Type)
SuppressAnyReturnType = 1 << 8, // If the return type is any-like, don't offer a return type.
WriteTypeParametersInQualifiedName = 1 << 9,
// Error handling
AllowThisInObjectLiteral = 1 << 10,
AllowQualifedNameInPlaceOfIdentifier = 1 << 11,
AllowAnonymousIdentifier = 1 << 13,
AllowEmptyUnionOrIntersection = 1 << 14,
AllowEmptyTuple = 1 << 15,
IgnoreErrors = AllowThisInObjectLiteral | AllowQualifedNameInPlaceOfIdentifier | AllowAnonymousIdentifier | AllowEmptyUnionOrIntersection | AllowEmptyTuple,
// State
InObjectTypeLiteral = 1 << 20,
InTypeAlias = 1 << 23, // Writing type in type alias declaration
}
export interface SymbolDisplayBuilder {
buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
buildSymbolDisplay(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): void;
buildSignatureDisplay(signatures: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): void;
buildSignatureDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): void;
buildIndexSignatureDisplay(info: IndexInfo, writer: SymbolWriter, kind: IndexKind, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, symbolStack?: Symbol[]): void;
buildParameterDisplay(parameter: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
buildTypeParameterDisplay(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
@@ -2738,7 +2768,7 @@ namespace ts {
getNodeCheckFlags(node: Node): NodeCheckFlags;
isDeclarationVisible(node: Declaration): boolean;
collectLinkedAliases(node: Identifier): Node[];
isImplementationOfOverload(node: FunctionLikeDeclaration): boolean;
isImplementationOfOverload(node: FunctionLikeDeclaration): boolean | undefined;
isRequiredInitializedParameter(node: ParameterDeclaration): boolean;
writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
writeReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
@@ -3120,7 +3150,7 @@ namespace ts {
*/
export interface TypeReference extends ObjectType {
target: GenericType; // Type reference target
typeArguments: Type[]; // Type reference type arguments (undefined if none)
typeArguments?: Type[]; // Type reference type arguments (undefined if none)
}
// Generic class and interface types
@@ -3250,7 +3280,7 @@ namespace ts {
export interface Signature {
declaration: SignatureDeclaration; // Originating declaration
typeParameters: TypeParameter[]; // Type parameters (undefined if non-generic)
typeParameters?: TypeParameter[]; // Type parameters (undefined if non-generic)
parameters: Symbol[]; // Parameters
/* @internal */
thisParameter?: Symbol; // symbol of this-type parameter
@@ -3512,7 +3542,7 @@ namespace ts {
export const enum NewLineKind {
CarriageReturnLineFeed = 0,
LineFeed = 1,
LineFeed = 1
}
export interface LineAndCharacter {
@@ -3964,6 +3994,7 @@ namespace ts {
NoHoisting = 1 << 21, // Do not hoist this declaration in --module system
HasEndOfDeclarationMarker = 1 << 22, // Declaration has an associated NotEmittedStatement to mark the end of the declaration
Iterator = 1 << 23, // The expression to a `yield*` should be treated as an Iterator when down-leveling, not an Iterable.
NoAsciiEscaping = 1 << 24, // When synthesizing nodes that lack an original node or textSourceNode, we want to write the text on the node with ASCII escaping substitutions.
}
export interface EmitHelper {
@@ -4176,7 +4207,7 @@ namespace ts {
* Prints a bundle of source files as-is, without any emit transformations.
*/
printBundle(bundle: Bundle): string;
/*@internal*/ writeNode(hint: EmitHint, node: Node, sourceFile: SourceFile, writer: EmitTextWriter): void;
/*@internal*/ writeNode(hint: EmitHint, node: Node, sourceFile: SourceFile | undefined, writer: EmitTextWriter): void;
/*@internal*/ writeFile(sourceFile: SourceFile, writer: EmitTextWriter): void;
/*@internal*/ writeBundle(bundle: Bundle, writer: EmitTextWriter): void;
}
+64 -20
View File
@@ -11,12 +11,12 @@ namespace ts {
isTypeReferenceDirective?: boolean;
}
export function getDeclarationOfKind(symbol: Symbol, kind: SyntaxKind): Declaration {
export function getDeclarationOfKind<T extends Declaration>(symbol: Symbol, kind: T["kind"]): T {
const declarations = symbol.declarations;
if (declarations) {
for (const declaration of declarations) {
if (declaration.kind === kind) {
return declaration;
return declaration as T;
}
}
}
@@ -328,19 +328,21 @@ namespace ts {
return getSourceTextOfNodeFromSourceFile(sourceFile, node);
}
const escapeText = getEmitFlags(node) & EmitFlags.NoAsciiEscaping ? escapeString : escapeNonAsciiString;
// If we can't reach the original source text, use the canonical form if it's a number,
// or an escaped quoted form of the original text if it's string-like.
// or a (possibly escaped) quoted form of the original text if it's string-like.
switch (node.kind) {
case SyntaxKind.StringLiteral:
return getQuotedEscapedLiteralText('"', node.text, '"');
return '"' + escapeText(node.text) + '"';
case SyntaxKind.NoSubstitutionTemplateLiteral:
return getQuotedEscapedLiteralText("`", node.text, "`");
return "`" + escapeText(node.text) + "`";
case SyntaxKind.TemplateHead:
return getQuotedEscapedLiteralText("`", node.text, "${");
return "`" + escapeText(node.text) + "${";
case SyntaxKind.TemplateMiddle:
return getQuotedEscapedLiteralText("}", node.text, "${");
return "}" + escapeText(node.text) + "${";
case SyntaxKind.TemplateTail:
return getQuotedEscapedLiteralText("}", node.text, "`");
return "}" + escapeText(node.text) + "`";
case SyntaxKind.NumericLiteral:
return node.text;
}
@@ -348,10 +350,6 @@ namespace ts {
Debug.fail(`Literal kind '${node.kind}' not accounted for.`);
}
function getQuotedEscapedLiteralText(leftQuote: string, text: string, rightQuote: string) {
return leftQuote + escapeNonAsciiCharacters(escapeString(text)) + rightQuote;
}
// Add an extra underscore to identifiers that start with two underscores to avoid issues with magic names like '__proto__'
export function escapeIdentifier(identifier: string): string {
return identifier.length >= 2 && identifier.charCodeAt(0) === CharacterCodes._ && identifier.charCodeAt(1) === CharacterCodes._ ? "_" + identifier : identifier;
@@ -465,7 +463,7 @@ namespace ts {
return getFullWidth(name) === 0 ? "(Missing)" : getTextOfNode(name);
}
export function getNameFromIndexInfo(info: IndexInfo) {
export function getNameFromIndexInfo(info: IndexInfo): string | undefined {
return info.declaration ? declarationNameToString(info.declaration.parameters[0].name) : undefined;
}
@@ -881,6 +879,16 @@ namespace ts {
return false;
}
export function isFunctionOrConstructorTypeNode(node: Node): node is FunctionTypeNode | ConstructorTypeNode {
switch (node.kind) {
case SyntaxKind.FunctionType:
case SyntaxKind.ConstructorType:
return true;
}
return false;
}
export function introducesArgumentsExoticObject(node: Node) {
switch (node.kind) {
case SyntaxKind.MethodDeclaration:
@@ -2336,6 +2344,9 @@ namespace ts {
case SyntaxKind.SpreadElement:
return 1;
case SyntaxKind.CommaListExpression:
return 0;
default:
return -1;
}
@@ -2468,7 +2479,8 @@ namespace ts {
}
const nonAsciiCharacters = /[^\u0000-\u007F]/g;
export function escapeNonAsciiCharacters(s: string): string {
export function escapeNonAsciiString(s: string): string {
s = escapeString(s);
// Replace non-ASCII characters with '\uNNNN' escapes if any exist.
// Otherwise just return the original string.
return nonAsciiCharacters.test(s) ?
@@ -3261,13 +3273,13 @@ namespace ts {
const carriageReturnLineFeed = "\r\n";
const lineFeed = "\n";
export function getNewLineCharacter(options: CompilerOptions | PrinterOptions): string {
if (options.newLine === NewLineKind.CarriageReturnLineFeed) {
return carriageReturnLineFeed;
switch (options.newLine) {
case NewLineKind.CarriageReturnLineFeed:
return carriageReturnLineFeed;
case NewLineKind.LineFeed:
return lineFeed;
}
else if (options.newLine === NewLineKind.LineFeed) {
return lineFeed;
}
else if (sys) {
if (sys) {
return sys.newLine;
}
return carriageReturnLineFeed;
@@ -3924,6 +3936,7 @@ namespace ts {
|| kind === SyntaxKind.SpreadElement
|| kind === SyntaxKind.AsExpression
|| kind === SyntaxKind.OmittedExpression
|| kind === SyntaxKind.CommaListExpression
|| isUnaryExpressionKind(kind);
}
@@ -4015,6 +4028,10 @@ namespace ts {
return node.kind === SyntaxKind.ImportEqualsDeclaration;
}
export function isImportDeclaration(node: Node): node is ImportDeclaration {
return node.kind === SyntaxKind.ImportDeclaration;
}
export function isImportClause(node: Node): node is ImportClause {
return node.kind === SyntaxKind.ImportClause;
}
@@ -4037,6 +4054,10 @@ namespace ts {
return node.kind === SyntaxKind.ExportSpecifier;
}
export function isExportAssignment(node: Node): node is ExportAssignment {
return node.kind === SyntaxKind.ExportAssignment;
}
export function isModuleOrEnumDeclaration(node: Node): node is ModuleDeclaration | EnumDeclaration {
return node.kind === SyntaxKind.ModuleDeclaration || node.kind === SyntaxKind.EnumDeclaration;
}
@@ -4244,6 +4265,29 @@ namespace ts {
return options.watch && options.hasOwnProperty("watch");
}
export function getCheckFlags(symbol: Symbol): CheckFlags {
return symbol.flags & SymbolFlags.Transient ? (<TransientSymbol>symbol).checkFlags : 0;
}
export function getDeclarationModifierFlagsFromSymbol(s: Symbol): ModifierFlags {
if (s.valueDeclaration) {
const flags = getCombinedModifierFlags(s.valueDeclaration);
return s.parent && s.parent.flags & SymbolFlags.Class ? flags : flags & ~ModifierFlags.AccessibilityModifier;
}
if (getCheckFlags(s) & CheckFlags.Synthetic) {
const checkFlags = (<TransientSymbol>s).checkFlags;
const accessModifier = checkFlags & CheckFlags.ContainsPrivate ? ModifierFlags.Private :
checkFlags & CheckFlags.ContainsPublic ? ModifierFlags.Public :
ModifierFlags.Protected;
const staticModifier = checkFlags & CheckFlags.ContainsStatic ? ModifierFlags.Static : 0;
return accessModifier | staticModifier;
}
if (s.flags & SymbolFlags.Prototype) {
return ModifierFlags.Public | ModifierFlags.Static;
}
return 0;
}
export function levenshtein(s1: string, s2: string): number {
let previous: number[] = new Array(s2.length + 1);
let current: number[] = new Array(s2.length + 1);
+22
View File
@@ -220,6 +220,10 @@ namespace ts {
switch (kind) {
// Names
case SyntaxKind.Identifier:
return updateIdentifier(<Identifier>node, nodesVisitor((<Identifier>node).typeArguments, visitor, isTypeNode));
case SyntaxKind.QualifiedName:
return updateQualifiedName(<QualifiedName>node,
visitNode((<QualifiedName>node).left, visitor, isEntityName),
@@ -255,6 +259,7 @@ namespace ts {
case SyntaxKind.PropertySignature:
return updatePropertySignature((<PropertySignature>node),
nodesVisitor((<PropertySignature>node).modifiers, visitor, isToken),
visitNode((<PropertySignature>node).name, visitor, isPropertyName),
visitNode((<PropertySignature>node).questionToken, tokenVisitor, isToken),
visitNode((<PropertySignature>node).type, visitor, isTypeNode),
@@ -876,6 +881,10 @@ namespace ts {
return updatePartiallyEmittedExpression(<PartiallyEmittedExpression>node,
visitNode((<PartiallyEmittedExpression>node).expression, visitor, isExpression));
case SyntaxKind.CommaListExpression:
return updateCommaList(<CommaListExpression>node,
nodesVisitor((<CommaListExpression>node).elements, visitor, isExpression));
default:
// No need to visit nodes with no children.
return node;
@@ -966,6 +975,15 @@ namespace ts {
break;
// Type member
case SyntaxKind.PropertySignature:
result = reduceNodes((<PropertySignature>node).modifiers, cbNodes, result);
result = reduceNode((<PropertySignature>node).name, cbNode, result);
result = reduceNode((<PropertySignature>node).questionToken, cbNode, result);
result = reduceNode((<PropertySignature>node).type, cbNode, result);
result = reduceNode((<PropertySignature>node).initializer, cbNode, result);
break;
case SyntaxKind.PropertyDeclaration:
result = reduceNodes((<PropertyDeclaration>node).decorators, cbNodes, result);
result = reduceNodes((<PropertyDeclaration>node).modifiers, cbNodes, result);
@@ -1389,6 +1407,10 @@ namespace ts {
result = reduceNode((<PartiallyEmittedExpression>node).expression, cbNode, result);
break;
case SyntaxKind.CommaListExpression:
result = reduceNodes((<CommaListExpression>node).elements, cbNodes, result);
break;
default:
break;
}
+18
View File
@@ -3419,6 +3419,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) {
@@ -3455,6 +3467,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);
}
+1
View File
@@ -2267,6 +2267,7 @@ namespace ts.server.protocol {
insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces?: boolean;
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces?: boolean;
insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean;
insertSpaceAfterTypeAssertion?: boolean;
insertSpaceBeforeFunctionParenthesis?: boolean;
placeOpenBraceOnNewLineForFunctions?: boolean;
placeOpenBraceOnNewLineForControlBlocks?: boolean;
+1 -1
View File
@@ -130,7 +130,7 @@ namespace ts.codefix {
}
function signatureToMethodDeclaration(signature: Signature, enclosingDeclaration: Node, body?: Block) {
const signatureDeclaration = <MethodDeclaration>checker.signatureToSignatureDeclaration(signature, SyntaxKind.MethodDeclaration, enclosingDeclaration);
const signatureDeclaration = <MethodDeclaration>checker.signatureToSignatureDeclaration(signature, SyntaxKind.MethodDeclaration, enclosingDeclaration, NodeBuilderFlags.SuppressAnyReturnType);
if (signatureDeclaration) {
signatureDeclaration.decorators = undefined;
signatureDeclaration.modifiers = modifiers;
+234 -34
View File
@@ -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"
});
}
}
}
@@ -351,7 +359,7 @@ namespace ts.Completions {
start = timestamp();
// Completion not allowed inside comments, bail out if this is the case
const insideComment = isInsideComment(sourceFile, currentToken, position);
const insideComment = isInComment(sourceFile, position, currentToken);
log("getCompletionData: Is inside comment: " + (timestamp() - start));
if (insideComment) {
@@ -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);
}
+2 -2
View File
@@ -554,7 +554,7 @@ namespace ts.FindAllReferences.Core {
}
function isObjectBindingPatternElementWithoutPropertyName(symbol: Symbol): boolean {
const bindingElement = <BindingElement>getDeclarationOfKind(symbol, SyntaxKind.BindingElement);
const bindingElement = getDeclarationOfKind<BindingElement>(symbol, SyntaxKind.BindingElement);
return bindingElement &&
bindingElement.parent.kind === SyntaxKind.ObjectBindingPattern &&
!bindingElement.propertyName;
@@ -562,7 +562,7 @@ namespace ts.FindAllReferences.Core {
function getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol: Symbol, checker: TypeChecker): Symbol | undefined {
if (isObjectBindingPatternElementWithoutPropertyName(symbol)) {
const bindingElement = <BindingElement>getDeclarationOfKind(symbol, SyntaxKind.BindingElement);
const bindingElement = getDeclarationOfKind<BindingElement>(symbol, SyntaxKind.BindingElement);
const typeOfPattern = checker.getTypeAtLocation(bindingElement.parent);
return typeOfPattern && checker.getPropertyOfType(typeOfPattern, (<Identifier>bindingElement.name).text);
}
+27 -13
View File
@@ -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;
}
}
@@ -136,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();
+5 -4
View File
@@ -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. */
+2 -2
View File
@@ -369,6 +369,7 @@ namespace ts {
_incrementExpressionBrand: any;
_unaryExpressionBrand: any;
_expressionBrand: any;
/*@internal*/typeArguments: NodeArray<TypeNode>;
constructor(_kind: SyntaxKind.Identifier, pos: number, end: number) {
super(pos, end);
}
@@ -1862,8 +1863,7 @@ namespace ts {
// OK, we have found a match in the file. This is only an acceptable match if
// it is contained within a comment.
const token = getTokenAtPosition(sourceFile, matchPosition, /*includeJsDocComment*/ false);
if (!isInsideComment(sourceFile, token, matchPosition)) {
if (!isInComment(sourceFile, matchPosition)) {
continue;
}
+29 -23
View File
@@ -200,27 +200,33 @@ namespace ts.SymbolDisplay {
(location.kind === SyntaxKind.ConstructorKeyword && location.parent.kind === SyntaxKind.Constructor)) { // At constructor keyword of constructor declaration
// get the signature from the declaration and write it
const functionDeclaration = <FunctionLikeDeclaration>location.parent;
const allSignatures = functionDeclaration.kind === SyntaxKind.Constructor ? type.getNonNullableType().getConstructSignatures() : type.getNonNullableType().getCallSignatures();
if (!typeChecker.isImplementationOfOverload(functionDeclaration)) {
signature = typeChecker.getSignatureFromDeclaration(functionDeclaration);
}
else {
signature = allSignatures[0];
}
// Use function declaration to write the signatures only if the symbol corresponding to this declaration
const locationIsSymbolDeclaration = findDeclaration(symbol, declaration =>
declaration === (location.kind === SyntaxKind.ConstructorKeyword ? functionDeclaration.parent : functionDeclaration));
if (functionDeclaration.kind === SyntaxKind.Constructor) {
// show (constructor) Type(...) signature
symbolKind = ScriptElementKind.constructorImplementationElement;
addPrefixForAnyFunctionOrVar(type.symbol, symbolKind);
}
else {
// (function/method) symbol(..signature)
addPrefixForAnyFunctionOrVar(functionDeclaration.kind === SyntaxKind.CallSignature &&
!(type.symbol.flags & SymbolFlags.TypeLiteral || type.symbol.flags & SymbolFlags.ObjectLiteral) ? type.symbol : symbol, symbolKind);
}
if (locationIsSymbolDeclaration) {
const allSignatures = functionDeclaration.kind === SyntaxKind.Constructor ? type.getNonNullableType().getConstructSignatures() : type.getNonNullableType().getCallSignatures();
if (!typeChecker.isImplementationOfOverload(functionDeclaration)) {
signature = typeChecker.getSignatureFromDeclaration(functionDeclaration);
}
else {
signature = allSignatures[0];
}
addSignatureDisplayParts(signature, allSignatures);
hasAddedSymbolInfo = true;
if (functionDeclaration.kind === SyntaxKind.Constructor) {
// show (constructor) Type(...) signature
symbolKind = ScriptElementKind.constructorImplementationElement;
addPrefixForAnyFunctionOrVar(type.symbol, symbolKind);
}
else {
// (function/method) symbol(..signature)
addPrefixForAnyFunctionOrVar(functionDeclaration.kind === SyntaxKind.CallSignature &&
!(type.symbol.flags & SymbolFlags.TypeLiteral || type.symbol.flags & SymbolFlags.ObjectLiteral) ? type.symbol : symbol, symbolKind);
}
addSignatureDisplayParts(signature, allSignatures);
hasAddedSymbolInfo = true;
}
}
}
}
@@ -269,7 +275,7 @@ namespace ts.SymbolDisplay {
}
if (symbolFlags & SymbolFlags.Module) {
addNewLineIfDisplayPartsExist();
const declaration = <ModuleDeclaration>getDeclarationOfKind(symbol, SyntaxKind.ModuleDeclaration);
const declaration = getDeclarationOfKind<ModuleDeclaration>(symbol, SyntaxKind.ModuleDeclaration);
const isNamespace = declaration && declaration.name && declaration.name.kind === SyntaxKind.Identifier;
displayParts.push(keywordPart(isNamespace ? SyntaxKind.NamespaceKeyword : SyntaxKind.ModuleKeyword));
displayParts.push(spacePart());
@@ -290,9 +296,9 @@ namespace ts.SymbolDisplay {
}
else {
// Method/function type parameter
let declaration = <Node>getDeclarationOfKind(symbol, SyntaxKind.TypeParameter);
Debug.assert(declaration !== undefined);
declaration = declaration.parent;
const decl = getDeclarationOfKind(symbol, SyntaxKind.TypeParameter);
Debug.assert(decl !== undefined);
const declaration = decl.parent;
if (declaration) {
if (isFunctionLikeKind(declaration.kind)) {
+2 -22
View File
@@ -497,8 +497,8 @@ namespace ts.textChanges {
readonly node: Node;
}
export function getNonformattedText(node: Node, sourceFile: SourceFile, newLine: NewLineKind): NonFormattedText {
const options = { newLine, target: sourceFile.languageVersion };
export function getNonformattedText(node: Node, sourceFile: SourceFile | undefined, newLine: NewLineKind): NonFormattedText {
const options = { newLine, target: sourceFile && sourceFile.languageVersion };
const writer = new Writer(getNewLineCharacter(options));
const printer = createPrinter(options, writer);
printer.writeNode(EmitHint.Unspecified, node, sourceFile, writer);
@@ -528,26 +528,6 @@ namespace ts.textChanges {
return skipTrivia(s, 0) === s.length;
}
const nullTransformationContext: TransformationContext = {
enableEmitNotification: noop,
enableSubstitution: noop,
endLexicalEnvironment: () => undefined,
getCompilerOptions: notImplemented,
getEmitHost: notImplemented,
getEmitResolver: notImplemented,
hoistFunctionDeclaration: noop,
hoistVariableDeclaration: noop,
isEmitNotificationEnabled: notImplemented,
isSubstitutionEnabled: notImplemented,
onEmitNode: noop,
onSubstituteNode: notImplemented,
readEmitHelpers: notImplemented,
requestEmitHelper: noop,
resumeLexicalEnvironment: noop,
startLexicalEnvironment: noop,
suspendLexicalEnvironment: noop
};
function assignPositionsToNode(node: Node): Node {
const visited = visitEachChild(node, assignPositionsToNode, nullTransformationContext, assignPositionsToNodeArray, assignPositionsToNode);
// create proxy node for non synthesized nodes
+46 -90
View File
@@ -256,37 +256,6 @@ namespace ts {
getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node;
}
/** Returns true if the position is within a comment */
export function isInsideComment(sourceFile: SourceFile, token: Node, position: number): boolean {
// The position has to be: 1. in the leading trivia (before token.getStart()), and 2. within a comment
return position <= token.getStart(sourceFile) &&
(isInsideCommentRange(getTrailingCommentRanges(sourceFile.text, token.getFullStart())) ||
isInsideCommentRange(getLeadingCommentRanges(sourceFile.text, token.getFullStart())));
function isInsideCommentRange(comments: CommentRange[]): boolean {
return forEach(comments, comment => {
// either we are 1. completely inside the comment, or 2. at the end of the comment
if (comment.pos < position && position < comment.end) {
return true;
}
else if (position === comment.end) {
const text = sourceFile.text;
const width = comment.end - comment.pos;
// is single line comment or just /*
if (width <= 2 || text.charCodeAt(comment.pos + 1) === CharacterCodes.slash) {
return true;
}
else {
// is unterminated multi-line comment
return !(text.charCodeAt(comment.end - 1) === CharacterCodes.slash &&
text.charCodeAt(comment.end - 2) === CharacterCodes.asterisk);
}
}
return false;
});
}
}
export function getContainerNode(node: Node): Declaration {
while (true) {
node = node.parent;
@@ -651,44 +620,26 @@ namespace ts {
return current;
}
if (includeJsDocComment) {
const jsDocChildren = ts.filter(current.getChildren(), isJSDocNode);
for (const jsDocChild of jsDocChildren) {
const start = allowPositionInLeadingTrivia ? jsDocChild.getFullStart() : jsDocChild.getStart(sourceFile, includeJsDocComment);
if (start <= position) {
const end = jsDocChild.getEnd();
if (position < end || (position === end && jsDocChild.kind === SyntaxKind.EndOfFileToken)) {
current = jsDocChild;
continue outer;
}
else if (includeItemAtEndPosition && end === position) {
const previousToken = findPrecedingToken(position, sourceFile, jsDocChild);
if (previousToken && includeItemAtEndPosition(previousToken)) {
return previousToken;
}
}
}
}
}
// find the child that contains 'position'
for (const child of current.getChildren()) {
// all jsDocComment nodes were already visited
if (isJSDocNode(child)) {
if (isJSDocNode(child) && !includeJsDocComment) {
continue;
}
const start = allowPositionInLeadingTrivia ? child.getFullStart() : child.getStart(sourceFile, includeJsDocComment);
if (start <= position) {
const end = child.getEnd();
if (position < end || (position === end && child.kind === SyntaxKind.EndOfFileToken)) {
current = child;
continue outer;
}
else if (includeItemAtEndPosition && end === position) {
const previousToken = findPrecedingToken(position, sourceFile, child);
if (previousToken && includeItemAtEndPosition(previousToken)) {
return previousToken;
}
if (start > position) {
continue;
}
const end = child.getEnd();
if (position < end || (position === end && child.kind === SyntaxKind.EndOfFileToken)) {
current = child;
continue outer;
}
else if (includeItemAtEndPosition && end === position) {
const previousToken = findPrecedingToken(position, sourceFile, child);
if (previousToken && includeItemAtEndPosition(previousToken)) {
return previousToken;
}
}
}
@@ -834,10 +785,6 @@ namespace ts {
return false;
}
export function isInComment(sourceFile: SourceFile, position: number) {
return isInCommentHelper(sourceFile, position, /*predicate*/ undefined);
}
/**
* returns true if the position is in between the open and close elements of an JSX expression.
*/
@@ -883,15 +830,30 @@ namespace ts {
}
/**
* Returns true if the cursor at position in sourceFile is within a comment that additionally
* satisfies predicate, and false otherwise.
* Returns true if the cursor at position in sourceFile is within a comment.
*
* @param tokenAtPosition Must equal `getTokenAtPosition(sourceFile, position)
* @param predicate Additional predicate to test on the comment range.
*/
function isInCommentHelper(sourceFile: SourceFile, position: number, predicate?: (c: CommentRange) => boolean): boolean {
const token = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false);
export function isInComment(
sourceFile: SourceFile,
position: number,
tokenAtPosition = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false),
predicate?: (c: CommentRange) => boolean): boolean {
return position <= tokenAtPosition.getStart(sourceFile) &&
(isInCommentRange(getLeadingCommentRanges(sourceFile.text, tokenAtPosition.pos)) ||
isInCommentRange(getTrailingCommentRanges(sourceFile.text, tokenAtPosition.pos)));
if (token && position <= token.getStart(sourceFile)) {
const commentRanges = getLeadingCommentRanges(sourceFile.text, token.pos);
function isInCommentRange(commentRanges: CommentRange[]): boolean {
return forEach(commentRanges, c => isPositionInCommentRange(c, position, sourceFile.text) && (!predicate || predicate(c)));
}
}
function isPositionInCommentRange({ pos, end, kind }: ts.CommentRange, position: number, text: string): boolean {
if (pos < position && position < end) {
return true;
}
else if (position === end) {
// The end marker of a single-line comment does not include the newline character.
// In the following case, we are inside a comment (^ denotes the cursor position):
//
@@ -902,15 +864,13 @@ namespace ts {
// /* asdf */^
//
// Internally, we represent the end of the comment at the newline and closing '/', respectively.
return predicate ?
forEach(commentRanges, c => c.pos < position &&
(c.kind === SyntaxKind.SingleLineCommentTrivia ? position <= c.end : position < c.end) &&
predicate(c)) :
forEach(commentRanges, c => c.pos < position &&
(c.kind === SyntaxKind.SingleLineCommentTrivia ? position <= c.end : position < c.end));
return kind === SyntaxKind.SingleLineCommentTrivia ||
// true for unterminated multi-line comment
!(text.charCodeAt(end - 1) === CharacterCodes.slash && text.charCodeAt(end - 2) === CharacterCodes.asterisk);
}
else {
return false;
}
return false;
}
export function hasDocComment(sourceFile: SourceFile, position: number) {
@@ -1093,21 +1053,17 @@ namespace ts {
}
export function isInReferenceComment(sourceFile: SourceFile, position: number): boolean {
return isInCommentHelper(sourceFile, position, isReferenceComment);
function isReferenceComment(c: CommentRange): boolean {
return isInComment(sourceFile, position, /*tokenAtPosition*/ undefined, c => {
const commentText = sourceFile.text.substring(c.pos, c.end);
return tripleSlashDirectivePrefixRegex.test(commentText);
}
});
}
export function isInNonReferenceComment(sourceFile: SourceFile, position: number): boolean {
return isInCommentHelper(sourceFile, position, isNonReferenceComment);
function isNonReferenceComment(c: CommentRange): boolean {
return isInComment(sourceFile, position, /*tokenAtPosition*/ undefined, c => {
const commentText = sourceFile.text.substring(c.pos, c.end);
return !tripleSlashDirectivePrefixRegex.test(commentText);
}
});
}
export function createTextSpanFromNode(node: Node, sourceFile?: SourceFile): TextSpan {
@@ -128,8 +128,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
var i, p;
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
};
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
@@ -169,8 +169,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
};
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
var i, p;
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
};
class C5 {
f() {
@@ -264,8 +264,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
var i, p;
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
};
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
@@ -354,8 +354,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
};
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
var i, p;
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
};
var __values = (this && this.__values) || function (o) {
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
@@ -91,8 +91,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
var i, p;
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
};
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
@@ -130,8 +130,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
};
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
var i, p;
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
};
function f5() {
return __asyncGenerator(this, arguments, function* f5_1() {
@@ -218,8 +218,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
var i, p;
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
};
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
@@ -303,8 +303,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
};
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
var i, p;
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
};
var __values = (this && this.__values) || function (o) {
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
@@ -91,8 +91,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
var i, p;
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
};
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
@@ -130,8 +130,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
};
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
var i, p;
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
};
const f5 = function () {
return __asyncGenerator(this, arguments, function* () {
@@ -218,8 +218,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
var i, p;
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
};
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
@@ -303,8 +303,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
};
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
var i, p;
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
};
var __values = (this && this.__values) || function (o) {
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
@@ -111,8 +111,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
var i, p;
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
};
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
@@ -152,8 +152,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
};
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
var i, p;
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
};
const o5 = {
f() {
@@ -238,8 +238,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
var i, p;
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
};
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
@@ -325,8 +325,8 @@ var __asyncValues = (this && this.__asyncIterator) || function (o) {
};
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
var i, p;
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : v; }; }
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
};
var __values = (this && this.__values) || function (o) {
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
@@ -1,14 +1,11 @@
tests/cases/compiler/enumUsedBeforeDeclaration.ts(1,18): error TS2450: Enum 'Color' used before its declaration.
tests/cases/compiler/enumUsedBeforeDeclaration.ts(2,24): error TS2450: Enum 'ConstColor' used before its declaration.
==== tests/cases/compiler/enumUsedBeforeDeclaration.ts (2 errors) ====
==== tests/cases/compiler/enumUsedBeforeDeclaration.ts (1 errors) ====
const v: Color = Color.Green;
~~~~~
!!! error TS2450: Enum 'Color' used before its declaration.
const v2: ConstColor = ConstColor.Green;
~~~~~~~~~~
!!! error TS2450: Enum 'ConstColor' used before its declaration.
enum Color { Red, Green, Blue }
const enum ConstColor { Red, Green, Blue }
@@ -220,7 +220,7 @@ class testClass {
>testClass : testClass
public func(arg1: number, arg\u0032: string, arg\u0033: boolean, arg4: number) {
>func : (arg1: number, arg\u0032: string, arg\u0033: boolean, arg4: number) => void
>func : (arg1: number, arg2: string, arg3: boolean, arg4: number) => void
>arg1 : number
>arg\u0032 : string
>arg\u0033 : boolean
@@ -1,8 +1,10 @@
tests/cases/conformance/jsx/file.tsx(21,16): error TS2322: Type '{ x: number; }' is not assignable to type 'Attribs1'.
Types of property 'x' are incompatible.
Type 'number' is not assignable to type 'string'.
tests/cases/conformance/jsx/file.tsx(25,16): error TS2322: Type '{ y: string; }' is not assignable to type 'Attribs1'.
Property 'x' is missing in type '{ y: string; }'.
tests/cases/conformance/jsx/file.tsx(21,16): error TS2322: Type 'T' is not assignable to type 'Attribs1'.
Type '{ x: number; }' is not assignable to type 'Attribs1'.
Types of property 'x' are incompatible.
Type 'number' is not assignable to type 'string'.
tests/cases/conformance/jsx/file.tsx(25,16): error TS2322: Type 'T' is not assignable to type 'Attribs1'.
Type '{ y: string; }' is not assignable to type 'Attribs1'.
Property 'x' is missing in type '{ y: string; }'.
tests/cases/conformance/jsx/file.tsx(29,8): error TS2322: Type '{}' is not assignable to type 'Attribs1'.
Property 'x' is missing in type '{}'.
@@ -30,16 +32,18 @@ tests/cases/conformance/jsx/file.tsx(29,8): error TS2322: Type '{}' is not assig
function make2<T extends {x: number}> (obj: T) {
return <test1 {...obj} />; // Error (x is number, not string)
~~~~~~~~
!!! error TS2322: Type '{ x: number; }' is not assignable to type 'Attribs1'.
!!! error TS2322: Types of property 'x' are incompatible.
!!! error TS2322: Type 'number' is not assignable to type 'string'.
!!! error TS2322: Type 'T' is not assignable to type 'Attribs1'.
!!! error TS2322: Type '{ x: number; }' is not assignable to type 'Attribs1'.
!!! error TS2322: Types of property 'x' are incompatible.
!!! error TS2322: Type 'number' is not assignable to type 'string'.
}
function make3<T extends {y: string}> (obj: T) {
return <test1 {...obj} />; // Error, missing x
~~~~~~~~
!!! error TS2322: Type '{ y: string; }' is not assignable to type 'Attribs1'.
!!! error TS2322: Property 'x' is missing in type '{ y: string; }'.
!!! error TS2322: Type 'T' is not assignable to type 'Attribs1'.
!!! error TS2322: Type '{ y: string; }' is not assignable to type 'Attribs1'.
!!! error TS2322: Property 'x' is missing in type '{ y: string; }'.
}
@@ -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
}
@@ -0,0 +1,40 @@
//// [file.tsx]
import React = require('react');
export function makeP<P>(Ctor: React.ComponentClass<P>): React.ComponentClass<P> {
return class extends React.PureComponent<P, void> {
public render(): JSX.Element {
return (
<Ctor {...this.props } />
);
}
};
}
//// [file.jsx]
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
exports.__esModule = true;
var React = require("react");
function makeP(Ctor) {
return (function (_super) {
__extends(class_1, _super);
function class_1() {
return _super !== null && _super.apply(this, arguments) || this;
}
class_1.prototype.render = function () {
return (<Ctor {...this.props}/>);
};
return class_1;
}(React.PureComponent));
}
exports.makeP = makeP;
@@ -0,0 +1,37 @@
=== tests/cases/conformance/jsx/file.tsx ===
import React = require('react');
>React : Symbol(React, Decl(file.tsx, 0, 0))
export function makeP<P>(Ctor: React.ComponentClass<P>): React.ComponentClass<P> {
>makeP : Symbol(makeP, Decl(file.tsx, 0, 32))
>P : Symbol(P, Decl(file.tsx, 2, 22))
>Ctor : Symbol(Ctor, Decl(file.tsx, 2, 25))
>React : Symbol(React, Decl(file.tsx, 0, 0))
>ComponentClass : Symbol(React.ComponentClass, Decl(react.d.ts, 204, 5))
>P : Symbol(P, Decl(file.tsx, 2, 22))
>React : Symbol(React, Decl(file.tsx, 0, 0))
>ComponentClass : Symbol(React.ComponentClass, Decl(react.d.ts, 204, 5))
>P : Symbol(P, Decl(file.tsx, 2, 22))
return class extends React.PureComponent<P, void> {
>React.PureComponent : Symbol(React.PureComponent, Decl(react.d.ts, 179, 5))
>React : Symbol(React, Decl(file.tsx, 0, 0))
>PureComponent : Symbol(React.PureComponent, Decl(react.d.ts, 179, 5))
>P : Symbol(P, Decl(file.tsx, 2, 22))
public render(): JSX.Element {
>render : Symbol((Anonymous class).render, Decl(file.tsx, 3, 52))
>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1))
>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27))
return (
<Ctor {...this.props } />
>Ctor : Symbol(Ctor, Decl(file.tsx, 2, 25))
>this.props : Symbol(React.Component.props, Decl(react.d.ts, 166, 37))
>this : Symbol((Anonymous class), Decl(file.tsx, 3, 7))
>props : Symbol(React.Component.props, Decl(react.d.ts, 166, 37))
);
}
};
}
@@ -0,0 +1,41 @@
=== tests/cases/conformance/jsx/file.tsx ===
import React = require('react');
>React : typeof React
export function makeP<P>(Ctor: React.ComponentClass<P>): React.ComponentClass<P> {
>makeP : <P>(Ctor: React.ComponentClass<P>) => React.ComponentClass<P>
>P : P
>Ctor : React.ComponentClass<P>
>React : any
>ComponentClass : React.ComponentClass<P>
>P : P
>React : any
>ComponentClass : React.ComponentClass<P>
>P : P
return class extends React.PureComponent<P, void> {
>class extends React.PureComponent<P, void> { public render(): JSX.Element { return ( <Ctor {...this.props } /> ); } } : typeof (Anonymous class)
>React.PureComponent : React.PureComponent<P, void>
>React : typeof React
>PureComponent : typeof React.PureComponent
>P : P
public render(): JSX.Element {
>render : () => JSX.Element
>JSX : any
>Element : JSX.Element
return (
>( <Ctor {...this.props } /> ) : JSX.Element
<Ctor {...this.props } />
><Ctor {...this.props } /> : JSX.Element
>Ctor : React.ComponentClass<P>
>this.props : P & { children?: React.ReactNode; }
>this : this
>props : P & { children?: React.ReactNode; }
);
}
};
}
@@ -21,8 +21,8 @@ var MainMenu: React.StatelessComponent<{}> = (props) => (<div>
>MainMenu : React.StatelessComponent<{}>
>React : any
>StatelessComponent : React.StatelessComponent<P>
>(props) => (<div> <h3>Main Menu</h3></div>) : (props: {}) => JSX.Element
>props : {}
>(props) => (<div> <h3>Main Menu</h3></div>) : (props: { children?: React.ReactNode; }) => JSX.Element
>props : { children?: React.ReactNode; }
>(<div> <h3>Main Menu</h3></div>) : JSX.Element
><div> <h3>Main Menu</h3></div> : JSX.Element
>div : any
@@ -40,7 +40,7 @@ var App: React.StatelessComponent<{ children }> = ({children}) => (
>React : any
>StatelessComponent : React.StatelessComponent<P>
>children : any
>({children}) => ( <div > <MainMenu/> </div>) : ({children}: { children: any; }) => JSX.Element
>({children}) => ( <div > <MainMenu/> </div>) : ({children}: { children: any; } & { children?: React.ReactNode; }) => JSX.Element
>children : any
>( <div > <MainMenu/> </div>) : JSX.Element
@@ -1,10 +1,9 @@
tests/cases/conformance/jsx/file.tsx(8,34): error TS2322: Type '{ ignore-prop: 10; prop: number; }' is not assignable to type 'IntrinsicAttributes & { prop: number; "ignore-prop": string; }'.
Type '{ ignore-prop: 10; prop: number; }' is not assignable to type '{ prop: number; "ignore-prop": string; }'.
tests/cases/conformance/jsx/file.tsx(8,34): error TS2322: Type 'T & { ignore-prop: 10; }' is not assignable to type 'IntrinsicAttributes & { prop: number; "ignore-prop": string; }'.
Type 'T & { ignore-prop: 10; }' is not assignable to type '{ prop: number; "ignore-prop": string; }'.
Types of property '"ignore-prop"' are incompatible.
Type '10' is not assignable to type 'string'.
tests/cases/conformance/jsx/file.tsx(13,34): error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & { prop: {}; "ignore-prop": string; }'.
Type '{}' is not assignable to type '{ prop: {}; "ignore-prop": string; }'.
Property 'prop' is missing in type '{}'.
tests/cases/conformance/jsx/file.tsx(13,34): error TS2322: Type 'T' is not assignable to type 'IntrinsicAttributes & { prop: {}; "ignore-prop": string; }'.
Type 'T' is not assignable to type '{ prop: {}; "ignore-prop": string; }'.
tests/cases/conformance/jsx/file.tsx(20,19): error TS2322: Type '{ func: (a: number, b: string) => void; }' is not assignable to type 'IntrinsicAttributes & { func: (arg: number) => void; }'.
Type '{ func: (a: number, b: string) => void; }' is not assignable to type '{ func: (arg: number) => void; }'.
Types of property 'func' are incompatible.
@@ -25,8 +24,8 @@ tests/cases/conformance/jsx/file.tsx(31,10): error TS2453: The type argument for
function Bar<T extends {prop: number}>(arg: T) {
let a1 = <ComponentSpecific1 {...arg} ignore-prop={10} />;
~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2322: Type '{ ignore-prop: 10; prop: number; }' is not assignable to type 'IntrinsicAttributes & { prop: number; "ignore-prop": string; }'.
!!! error TS2322: Type '{ ignore-prop: 10; prop: number; }' is not assignable to type '{ prop: number; "ignore-prop": string; }'.
!!! error TS2322: Type 'T & { ignore-prop: 10; }' is not assignable to type 'IntrinsicAttributes & { prop: number; "ignore-prop": string; }'.
!!! error TS2322: Type 'T & { ignore-prop: 10; }' is not assignable to type '{ prop: number; "ignore-prop": string; }'.
!!! error TS2322: Types of property '"ignore-prop"' are incompatible.
!!! error TS2322: Type '10' is not assignable to type 'string'.
}
@@ -35,9 +34,8 @@ tests/cases/conformance/jsx/file.tsx(31,10): error TS2453: The type argument for
function Baz<T>(arg: T) {
let a0 = <ComponentSpecific1 {...arg} />
~~~~~~~~
!!! error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & { prop: {}; "ignore-prop": string; }'.
!!! error TS2322: Type '{}' is not assignable to type '{ prop: {}; "ignore-prop": string; }'.
!!! error TS2322: Property 'prop' is missing in type '{}'.
!!! error TS2322: Type 'T' is not assignable to type 'IntrinsicAttributes & { prop: {}; "ignore-prop": string; }'.
!!! error TS2322: Type 'T' is not assignable to type '{ prop: {}; "ignore-prop": string; }'.
}
declare function Link<U>(l: {func: (arg: U)=>void}): JSX.Element;
@@ -1,9 +1,12 @@
tests/cases/conformance/jsx/file.tsx(9,33): error TS2322: Type '{ a: number; }' is not assignable to type 'IntrinsicAttributes & { b: {}; a: number; }'.
Type '{ a: number; }' is not assignable to type '{ b: {}; a: number; }'.
Property 'b' is missing in type '{ a: number; }'.
tests/cases/conformance/jsx/file.tsx(10,33): error TS2322: Type '{ b: number; }' is not assignable to type 'IntrinsicAttributes & { b: number; a: {}; }'.
Type '{ b: number; }' is not assignable to type '{ b: number; a: {}; }'.
Property 'a' is missing in type '{ b: number; }'.
tests/cases/conformance/jsx/file.tsx(10,33): error TS2322: Type 'T' is not assignable to type 'IntrinsicAttributes & { b: number; a: {}; }'.
Type '{ b: number; }' is not assignable to type 'IntrinsicAttributes & { b: number; a: {}; }'.
Type '{ b: number; }' is not assignable to type '{ b: number; a: {}; }'.
Type 'T' is not assignable to type '{ b: number; a: {}; }'.
Type '{ b: number; }' is not assignable to type '{ b: number; a: {}; }'.
Property 'a' is missing in type '{ b: number; }'.
==== tests/cases/conformance/jsx/file.tsx (2 errors) ====
@@ -22,7 +25,10 @@ tests/cases/conformance/jsx/file.tsx(10,33): error TS2322: Type '{ b: number; }'
!!! error TS2322: Property 'b' is missing in type '{ a: number; }'.
let a2 = <OverloadComponent {...arg1} ignore-prop /> // missing a
~~~~~~~~~~~~~~~~~~~~~
!!! error TS2322: Type '{ b: number; }' is not assignable to type 'IntrinsicAttributes & { b: number; a: {}; }'.
!!! error TS2322: Type '{ b: number; }' is not assignable to type '{ b: number; a: {}; }'.
!!! error TS2322: Property 'a' is missing in type '{ b: number; }'.
!!! error TS2322: Type 'T' is not assignable to type 'IntrinsicAttributes & { b: number; a: {}; }'.
!!! error TS2322: Type '{ b: number; }' is not assignable to type 'IntrinsicAttributes & { b: number; a: {}; }'.
!!! error TS2322: Type '{ b: number; }' is not assignable to type '{ b: number; a: {}; }'.
!!! error TS2322: Type 'T' is not assignable to type '{ b: number; a: {}; }'.
!!! error TS2322: Type '{ b: number; }' is not assignable to type '{ b: number; a: {}; }'.
!!! error TS2322: Property 'a' is missing in type '{ b: number; }'.
}
@@ -1,7 +1,11 @@
tests/cases/conformance/jsx/file.tsx(15,14): error TS2605: JSX element type 'Element' is not a constructor function for JSX elements.
Property 'render' is missing in type 'Element'.
tests/cases/conformance/jsx/file.tsx(15,15): error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly.
Type argument candidate 'number' is not a valid type argument because it is not a supertype of candidate '"hello"'.
tests/cases/conformance/jsx/file.tsx(16,42): error TS2339: Property 'prop1' does not exist on type 'IntrinsicAttributes & { prop: number; }'.
==== tests/cases/conformance/jsx/file.tsx (1 errors) ====
==== tests/cases/conformance/jsx/file.tsx (3 errors) ====
import React = require('react')
declare function Component<U>(l: U): JSX.Element;
@@ -17,6 +21,12 @@ tests/cases/conformance/jsx/file.tsx(16,42): error TS2339: Property 'prop1' does
let a1 = <ComponentSpecific {...arg} ignore-prop="hi" />; // U is number
let a2 = <ComponentSpecific1 {...arg} ignore-prop={10} />; // U is number
let a3 = <ComponentSpecific {...arg} prop="hello" />; // U is "hello"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2605: JSX element type 'Element' is not a constructor function for JSX elements.
!!! error TS2605: Property 'render' is missing in type 'Element'.
~~~~~~~~~~~~~~~~~
!!! error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly.
!!! error TS2453: Type argument candidate 'number' is not a valid type argument because it is not a supertype of candidate '"hello"'.
let a4 = <ComponentSpecific {...arg} prop1="hello" />; // U is "hello"
~~~~~~~~~~~~~
!!! error TS2339: Property 'prop1' does not exist on type 'IntrinsicAttributes & { prop: number; }'.
@@ -0,0 +1,5 @@
//// [unicodeStringLiteral.ts]
var = "Ü­ਲĭ";
//// [unicodeStringLiteral.js]
var = "Ü­ਲĭ";
@@ -0,0 +1,4 @@
=== tests/cases/compiler/unicodeStringLiteral.ts ===
var ੳ = "Ü­ਲĭ";
>ੳ : Symbol(ੳ, Decl(unicodeStringLiteral.ts, 0, 3))
@@ -0,0 +1,5 @@
=== tests/cases/compiler/unicodeStringLiteral.ts ===
var ੳ = "Ü­ਲĭ";
>ੳ : string
>"Ü­ਲĭ" : "Ü­ਲ\u000Eĭ"
@@ -0,0 +1 @@
var = "Ü­ਲĭ";
@@ -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} />;
}
@@ -0,0 +1,16 @@
// @filename: file.tsx
// @jsx: preserve
// @noLib: true
// @libFiles: react.d.ts,lib.d.ts
import React = require('react');
export function makeP<P>(Ctor: React.ComponentClass<P>): React.ComponentClass<P> {
return class extends React.PureComponent<P, void> {
public render(): JSX.Element {
return (
<Ctor {...this.props } />
);
}
};
}
@@ -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"
});
@@ -1,11 +1,11 @@
/// <reference path='fourslash.ts' />
//// interface I<X> {
//// [x: string]: X;
//// [Ƚ: string]: X;
//// }
////
//// class C implements I<number> {[| |]}
verify.rangeAfterCodeFix(`
[x: string]: number;
[Ƚ: string]: number;
`);
@@ -2,12 +2,12 @@
//// abstract class C1 { }
//// abstract class C2 {
//// abstract f1<T extends number>();
//// abstract f<T extends number>();
//// }
//// interface I1 extends C1, C2 { }
//// class C3 implements I1 {[| |]}
verify.rangeAfterCodeFix(`f1<T extends number>(){
verify.rangeAfterCodeFix(`f<T extends number>(){
throw new Error("Method not implemented.");
}
`);
@@ -0,0 +1,16 @@
/// <reference path='fourslash.ts' />
//// type Either<T> = { val: T } | Error;
//// interface I {
//// x: Either<Either<string>>;
//// foo(x: Either<Either<string>>): void;
//// }
//// class C implements I {[| |]}
verify.rangeAfterCodeFix(`
x: Either<Either<string>>;
foo(x: Either<Either<string>>): void {
throw new Error("Method not implemented.");
}
`);
@@ -0,0 +1,12 @@
/// <reference path='fourslash.ts' />
//// type MyType = [string, number];
//// interface I { x: MyType; test(a: MyType): void; }
//// class C implements I {[| |]}
verify.rangeAfterCodeFix(`
x: [string, number];
test(a: [string, number]): void {
throw new Error("Method not implemented.");
}
`);
@@ -4,7 +4,7 @@
//// x: number;
//// }
//// interface I2 {
//// y: number;
//// y: "𣋝ઢȴ¬⏊";
//// }
////
//// class C implements I1,I2 {[|
@@ -12,7 +12,7 @@
//// }
verify.rangeAfterCodeFix(`
y: number;
y: "𣋝ઢȴ¬⏊";
`);
verify.not.codeFixAvailable();
@@ -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]);
+2
View File
@@ -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");
+4 -4
View File
@@ -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, [
@@ -3,10 +3,10 @@
// @jsx: preserve
// @Filename: C.tsx
////export default class C {}
////export default class /*def*/C {}
// @Filename: a.tsx
////import /*def*/C from "./C";
////import C from "./C";
////const foo = </*use*/C />;
verify.noErrors();

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