mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into literalEnumTypes
# Conflicts: # src/compiler/checker.ts # src/compiler/diagnosticMessages.json # src/compiler/types.ts # src/compiler/utilities.ts # src/services/completions.ts
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
// @strictNullChecks:true
|
||||
|
||||
/*
|
||||
* Note: This test is a public API sample. The sample sources can be found
|
||||
* Note: This test is a public API sample. The sample sources can be found
|
||||
at: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#a-minimal-compiler
|
||||
* Please log a "breaking change" issue for any API breaking change affecting this issue
|
||||
*/
|
||||
@@ -22,8 +22,12 @@ export function compile(fileNames: string[], options: ts.CompilerOptions): void
|
||||
var allDiagnostics = ts.getPreEmitDiagnostics(program);
|
||||
|
||||
allDiagnostics.forEach(diagnostic => {
|
||||
var { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
|
||||
var message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
|
||||
if (!diagnostic.file) {
|
||||
console.log(message);
|
||||
return;
|
||||
}
|
||||
var { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!);
|
||||
console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
|
||||
});
|
||||
|
||||
@@ -35,4 +39,4 @@ export function compile(fileNames: string[], options: ts.CompilerOptions): void
|
||||
compile(process.argv.slice(2), {
|
||||
noEmitOnError: true, noImplicitAny: true,
|
||||
target: ts.ScriptTarget.ES5, module: ts.ModuleKind.CommonJS
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// @strictNullChecks:true
|
||||
|
||||
/*
|
||||
* Note: This test is a public API sample. The sample sources can be found
|
||||
* Note: This test is a public API sample. The sample sources can be found
|
||||
at: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#incremental-build-support-using-the-language-services
|
||||
* Please log a "breaking change" issue for any API breaking change affecting this issue
|
||||
*/
|
||||
@@ -95,7 +95,7 @@ function watch(rootFileNames: string[], options: ts.CompilerOptions) {
|
||||
allDiagnostics.forEach(diagnostic => {
|
||||
let message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n");
|
||||
if (diagnostic.file) {
|
||||
let { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
|
||||
let { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!);
|
||||
console.log(` Error ${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
|
||||
}
|
||||
else {
|
||||
@@ -110,4 +110,4 @@ const currentDirectoryFiles = fs.readdirSync(process.cwd()).
|
||||
filter(fileName=> fileName.length >= 3 && fileName.substr(fileName.length - 3, 3) === ".ts");
|
||||
|
||||
// Start the watcher
|
||||
watch(currentDirectoryFiles, { module: ts.ModuleKind.CommonJS });
|
||||
watch(currentDirectoryFiles, { module: ts.ModuleKind.CommonJS });
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
// @target: es5
|
||||
// @outFile: out.js
|
||||
// @module: amd
|
||||
|
||||
// #15734 failed when test.ts comes before typings.d.ts
|
||||
// @Filename: test.ts
|
||||
namespace C {
|
||||
export class Name {
|
||||
static funcData = A.AA.func();
|
||||
static someConst = A.AA.foo;
|
||||
|
||||
constructor(parameters) {}
|
||||
}
|
||||
}
|
||||
|
||||
// @Filename: typings.d.ts
|
||||
declare namespace A {
|
||||
namespace AA {
|
||||
function func(): number;
|
||||
const foo = "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// @target: es5
|
||||
for (var i = 0; i < 10; i++) {
|
||||
var str = 'x', len = str.length;
|
||||
let lambda1 = (y) => { };
|
||||
let lambda2 = () => lambda1(len);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// @Filename: weird.js
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @strict: true
|
||||
// @noEmit: true
|
||||
// @out: foo.js
|
||||
someFunction(function(BaseClass) {
|
||||
'use strict';
|
||||
const DEFAULT_MESSAGE = "nop!";
|
||||
class Hello extends BaseClass {
|
||||
constructor() {
|
||||
super();
|
||||
this.foo = "bar";
|
||||
}
|
||||
_render(error) {
|
||||
const message = error.message || DEFAULT_MESSAGE;
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @noEmit: true
|
||||
// @noImplicitAny: true
|
||||
// @fileName: a.js
|
||||
class C {
|
||||
constructor() {
|
||||
/** @type {boolean} */
|
||||
this.a = true;
|
||||
this.a = !!this.a;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
function f(b: boolean) {
|
||||
let Foo: any;
|
||||
if (b) {
|
||||
Foo = class Foo {
|
||||
static y = new Foo();
|
||||
|
||||
static x() {
|
||||
new Foo();
|
||||
}
|
||||
|
||||
m() {
|
||||
new Foo();
|
||||
}
|
||||
};
|
||||
|
||||
new Foo();
|
||||
}
|
||||
else {
|
||||
class Foo {
|
||||
static y = new Foo();
|
||||
|
||||
static x() {
|
||||
new Foo();
|
||||
}
|
||||
|
||||
m() {
|
||||
new Foo();
|
||||
}
|
||||
}
|
||||
|
||||
new Foo();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// @target: es5
|
||||
// @module: commonjs
|
||||
// @declaration: true
|
||||
|
||||
interface PrivateInterface {
|
||||
}
|
||||
|
||||
export class ExportedClass1 {
|
||||
private constructor(data: PrivateInterface) { }
|
||||
}
|
||||
|
||||
export class ExportedClass2 {
|
||||
private constructor(private data: PrivateInterface) { }
|
||||
}
|
||||
|
||||
export class ExportedClass3 {
|
||||
private constructor(private data: PrivateInterface, private n: number) { }
|
||||
}
|
||||
|
||||
export class ExportedClass4 {
|
||||
private constructor(private data: PrivateInterface, public n:number) { }
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// @target: es5
|
||||
// @module: commonjs
|
||||
// @declaration: true
|
||||
|
||||
interface PrivateInterface {
|
||||
}
|
||||
|
||||
export class ExportedClass1 {
|
||||
private constructor(public data: PrivateInterface) { }
|
||||
}
|
||||
|
||||
|
||||
export class ExportedClass2 {
|
||||
protected constructor(data: PrivateInterface) { }
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// @declaration: true
|
||||
namespace Test
|
||||
{
|
||||
export interface IFace
|
||||
{
|
||||
}
|
||||
|
||||
export class SomeClass implements IFace
|
||||
{
|
||||
}
|
||||
|
||||
export class Derived extends getClass<IFace>()
|
||||
{
|
||||
}
|
||||
|
||||
export function getClass<T>() : new() => T
|
||||
{
|
||||
return SomeClass as (new() => T);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// @target: es5
|
||||
const example = {
|
||||
get foo() {
|
||||
return item => this.bar(item);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
// @importHelpers: true
|
||||
// @target: es5
|
||||
// @module: commonjs
|
||||
// @lib: esnext
|
||||
// @moduleResolution: classic
|
||||
// @experimentalDecorators: true
|
||||
// @emitDecoratorMetadata: true
|
||||
// @filename: main.ts
|
||||
export async function * f() {
|
||||
await 1;
|
||||
yield 2;
|
||||
yield* [3];
|
||||
}
|
||||
|
||||
// @filename: tslib.d.ts
|
||||
export {}
|
||||
@@ -0,0 +1,8 @@
|
||||
// @isolatedModules: true
|
||||
// @target: es6
|
||||
|
||||
// @filename: /a.ts
|
||||
export type T = number;
|
||||
|
||||
// @filename: /b.ts
|
||||
export * from "./a";
|
||||
@@ -0,0 +1,31 @@
|
||||
// @isolatedModules: true
|
||||
|
||||
// @Filename: /exportT.ts
|
||||
export type T = number;
|
||||
|
||||
// @Filename: /exportValue.ts
|
||||
export class C {}
|
||||
|
||||
// @Filename: /exportEqualsT.ts
|
||||
declare type T = number;
|
||||
export = T;
|
||||
|
||||
|
||||
// @Filename: /user.ts
|
||||
// Error, can't re-export something that's only a type.
|
||||
export { T } from "./exportT";
|
||||
export import T2 = require("./exportEqualsT");
|
||||
|
||||
// OK, has a value side
|
||||
export { C } from "./exportValue";
|
||||
|
||||
// OK, even though the namespace it exports is only types.
|
||||
import * as NS from "./exportT";
|
||||
export { NS };
|
||||
|
||||
// OK, syntactically clear that a type is being re-exported.
|
||||
export type T3 = T;
|
||||
|
||||
// Error, not clear (to an isolated module) whether `T4` is a type.
|
||||
import { T } from "./exportT";
|
||||
export { T as T4 };
|
||||
@@ -0,0 +1,5 @@
|
||||
// 10 bobs on the first line
|
||||
// the last two bobs should not have did-you-mean spelling suggestions
|
||||
var blob;
|
||||
bob; bob; bob; bob; bob; bob; bob; bob; bob; bob;
|
||||
bob; bob;
|
||||
@@ -0,0 +1,18 @@
|
||||
// @experimentalDecorators: true
|
||||
// @emitDecoratorMetadata: true
|
||||
// @target: es5
|
||||
// @module: commonjs
|
||||
|
||||
// @filename: auxiliry.ts
|
||||
export class SomeClass {
|
||||
field: string;
|
||||
}
|
||||
|
||||
//@filename: test.ts
|
||||
import { SomeClass } from './auxiliry';
|
||||
function annotation(): PropertyDecorator {
|
||||
return (target: any): void => { };
|
||||
}
|
||||
export class ClassA {
|
||||
@annotation() array: SomeClass | null;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// @experimentalDecorators: true
|
||||
// @emitDecoratorMetadata: true
|
||||
// @target: es5
|
||||
// @module: commonjs
|
||||
|
||||
// @filename: auxiliry.ts
|
||||
export class SomeClass {
|
||||
field: string;
|
||||
}
|
||||
|
||||
//@filename: test.ts
|
||||
import { SomeClass } from './auxiliry';
|
||||
function annotation(): PropertyDecorator {
|
||||
return (target: any): void => { };
|
||||
}
|
||||
export class ClassA {
|
||||
@annotation() array: SomeClass | null | string;
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// @noimplicitany: true
|
||||
|
||||
var x = {}["hello"];
|
||||
var x = {}["hello"];
|
||||
var y: string = { '': 'foo' }[''];
|
||||
@@ -0,0 +1,83 @@
|
||||
// @strict: true
|
||||
|
||||
// Repro from #14091
|
||||
|
||||
interface Foo {
|
||||
foo(): void
|
||||
}
|
||||
|
||||
class A<P extends Partial<Foo>> {
|
||||
props: Readonly<P>
|
||||
doSomething() {
|
||||
this.props.foo && this.props.foo()
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #14415
|
||||
|
||||
interface Banana {
|
||||
color: 'yellow';
|
||||
}
|
||||
|
||||
class Monkey<T extends Banana | undefined> {
|
||||
a: T;
|
||||
render() {
|
||||
if (this.a) {
|
||||
this.a.color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface BigBanana extends Banana {
|
||||
}
|
||||
|
||||
class BigMonkey extends Monkey<BigBanana> {
|
||||
render() {
|
||||
if (this.a) {
|
||||
this.a.color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Another repro
|
||||
|
||||
type Item = {
|
||||
(): string;
|
||||
x: string;
|
||||
}
|
||||
|
||||
function f1<T extends Item | undefined>(obj: T) {
|
||||
if (obj) {
|
||||
obj.x;
|
||||
obj["x"];
|
||||
obj();
|
||||
}
|
||||
}
|
||||
|
||||
function f2<T extends Item | undefined>(obj: T | undefined) {
|
||||
if (obj) {
|
||||
obj.x;
|
||||
obj["x"];
|
||||
obj();
|
||||
}
|
||||
}
|
||||
|
||||
function f3<T extends Item | undefined>(obj: T | null) {
|
||||
if (obj) {
|
||||
obj.x;
|
||||
obj["x"];
|
||||
obj();
|
||||
}
|
||||
}
|
||||
|
||||
function f4<T extends string[] | undefined>(obj: T | undefined, x: number) {
|
||||
if (obj) {
|
||||
obj[x].length;
|
||||
}
|
||||
}
|
||||
|
||||
function f5<T, K extends keyof T>(obj: T | undefined, key: K) {
|
||||
if (obj) {
|
||||
obj[key];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
var ੳ = "Üਲĭ";
|
||||
@@ -0,0 +1,46 @@
|
||||
// Tests that types are marked as used, even if used in places that don't accept type arguments.
|
||||
|
||||
// @noUnusedLocals: true
|
||||
|
||||
// @Filename: /typeReference.ts
|
||||
type N = number;
|
||||
type U = number;
|
||||
export type Z = U<N>;
|
||||
|
||||
// @Filename: /classReference.ts
|
||||
type N = number;
|
||||
class C { }
|
||||
// This uses getTypeFromClassOrInterfaceReference instead of getTypeFromTypeAliasReference.
|
||||
export class D extends C<N> {}
|
||||
|
||||
// @Filename: /interface.ts
|
||||
import { Foo } from "unknown";
|
||||
export interface I<T> { x: Foo<T>; }
|
||||
|
||||
// @Filename: /call.ts
|
||||
import { foo } from "unknown";
|
||||
type T = number;
|
||||
foo<T>();
|
||||
|
||||
// @Filename: /new.ts
|
||||
import { Foo } from "unkown";
|
||||
type T = number;
|
||||
new Foo<T>();
|
||||
|
||||
// @Filename: /callAny.ts
|
||||
declare var g: any;
|
||||
type U = number;
|
||||
g<U>();
|
||||
g<InvalidReference>(); // Should get error for type argument
|
||||
|
||||
// @Filename: /super.ts
|
||||
import { C } from "unknown";
|
||||
|
||||
type T = number;
|
||||
|
||||
export class D extends C {
|
||||
m() {
|
||||
super.m<T>(1);
|
||||
super.m<InvalidReference>(); // Should get error for type argument
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
declare function all(a?: number, b?: number): void;
|
||||
declare function weird(a?: number | string, b?: number | string): void;
|
||||
declare function prefix(s: string, a?: number, b?: number): void;
|
||||
declare function rest(s: string, a?: number, b?: number, ...rest: number[]): void;
|
||||
declare function normal(s: string): void;
|
||||
declare function thunk(): string;
|
||||
|
||||
declare var ns: number[];
|
||||
declare var mixed: (number | string)[];
|
||||
declare var tuple: [number, string];
|
||||
|
||||
// good
|
||||
all(...ns)
|
||||
weird(...ns)
|
||||
weird(...mixed)
|
||||
weird(...tuple)
|
||||
prefix("a", ...ns)
|
||||
rest("d", ...ns)
|
||||
|
||||
|
||||
// this covers the arguments case
|
||||
normal("g", ...ns)
|
||||
normal("h", ...mixed)
|
||||
normal("i", ...tuple)
|
||||
thunk(...ns)
|
||||
thunk(...mixed)
|
||||
thunk(...tuple)
|
||||
|
||||
// bad
|
||||
all(...mixed)
|
||||
all(...tuple)
|
||||
prefix("b", ...mixed)
|
||||
prefix("c", ...tuple)
|
||||
rest("e", ...mixed)
|
||||
rest("f", ...tuple)
|
||||
prefix(...ns) // required parameters are required
|
||||
prefix(...mixed)
|
||||
prefix(...tuple)
|
||||
@@ -0,0 +1,36 @@
|
||||
// @filename: file.tsx
|
||||
// @jsx: preserve
|
||||
// @noLib: true
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
import React = require('react');
|
||||
|
||||
interface ButtonProp {
|
||||
a: number,
|
||||
b: string,
|
||||
children: Button;
|
||||
}
|
||||
|
||||
class Button extends React.Component<ButtonProp, any> {
|
||||
render() {
|
||||
let condition: boolean;
|
||||
if (condition) {
|
||||
return <InnerButton {...this.props} />
|
||||
}
|
||||
else {
|
||||
return (<InnerButton {...this.props} >
|
||||
<div>Hello World</div>
|
||||
</InnerButton>);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface InnerButtonProp {
|
||||
a: number
|
||||
}
|
||||
|
||||
class InnerButton extends React.Component<InnerButtonProp, any> {
|
||||
render() {
|
||||
return (<button>Hello</button>);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// @filename: file.tsx
|
||||
// @jsx: preserve
|
||||
// @noLib: true
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
import React = require('react');
|
||||
|
||||
interface ButtonProp {
|
||||
a: number,
|
||||
b: string,
|
||||
children: Button;
|
||||
}
|
||||
|
||||
class Button extends React.Component<ButtonProp, any> {
|
||||
render() {
|
||||
// Error children are specified twice
|
||||
return (<InnerButton {...this.props} children="hi">
|
||||
<div>Hello World</div>
|
||||
</InnerButton>);
|
||||
}
|
||||
}
|
||||
|
||||
interface InnerButtonProp {
|
||||
a: number
|
||||
}
|
||||
|
||||
class InnerButton extends React.Component<InnerButtonProp, any> {
|
||||
render() {
|
||||
return (<button>Hello</button>);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// @target: es2017
|
||||
// @jsx: react
|
||||
// @moduleResolution: node
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
// @filename: declaration.d.ts
|
||||
declare module "classnames";
|
||||
|
||||
// @filename: 0.tsx
|
||||
///<reference path="declaration.d.ts" />
|
||||
import * as cx from 'classnames';
|
||||
import * as React from "react";
|
||||
|
||||
let buttonProps; // any
|
||||
let k = <button {...buttonProps}>
|
||||
<span className={cx('class1', { class2: true })} />
|
||||
</button>;
|
||||
@@ -0,0 +1,17 @@
|
||||
// @target: es2017
|
||||
// @jsx: react
|
||||
// @moduleResolution: node
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
// @filename: declaration.d.ts
|
||||
declare module "classnames";
|
||||
|
||||
// @filename: 0.tsx
|
||||
///<reference path="declaration.d.ts" />
|
||||
import * as cx from 'classnames';
|
||||
import * as React from "react";
|
||||
|
||||
let buttonProps : {[attributeName: string]: ''}
|
||||
let k = <button {...buttonProps}>
|
||||
<span className={cx('class1', { class2: true })} />
|
||||
</button>;
|
||||
@@ -0,0 +1,18 @@
|
||||
// @target: es2017
|
||||
// @jsx: react
|
||||
// @moduleResolution: node
|
||||
// @noImplicitAny: true
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
// @filename: declaration.d.ts
|
||||
declare module "classnames";
|
||||
|
||||
// @filename: 0.tsx
|
||||
///<reference path="declaration.d.ts" />
|
||||
import * as cx from 'classnames';
|
||||
import * as React from "react";
|
||||
|
||||
let buttonProps;
|
||||
let k = <button {...buttonProps}>
|
||||
<span className={cx('class1', { class2: true })} />
|
||||
</button>;
|
||||
@@ -0,0 +1,15 @@
|
||||
// @target: es2017
|
||||
// @jsx: react
|
||||
// @moduleResolution: node
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
// @filename: declaration.d.ts
|
||||
declare module "classnames";
|
||||
|
||||
// @filename: 0.tsx
|
||||
///<reference path="declaration.d.ts" />
|
||||
import * as cx from 'classnames';
|
||||
import * as React from "react";
|
||||
|
||||
let buttonProps : {[attributeName: string]: ''}
|
||||
let k = <button {...buttonProps} className={cx('class1', { class2: true })} />;
|
||||
@@ -32,7 +32,7 @@ var obj4 = { x: 32, y: 32 };
|
||||
var obj5 = { x: 32, y: 32 };
|
||||
<test1 x="ok" {...obj5} />
|
||||
|
||||
// Error
|
||||
// Ok
|
||||
var obj6 = { x: 'ok', y: 32, extra: 100 };
|
||||
<test1 {...obj6} />
|
||||
|
||||
|
||||
@@ -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 } />
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// @filename: file.tsx
|
||||
// @jsx: preserve
|
||||
// @noLib: true
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
import React = require('react');
|
||||
|
||||
interface Prop {
|
||||
a: number,
|
||||
b: string
|
||||
}
|
||||
|
||||
declare class MyComp<P = Prop> extends React.Component<P, {}> {
|
||||
internalProp: P;
|
||||
}
|
||||
|
||||
let x = <MyComp a={10} b="hi" />
|
||||
@@ -0,0 +1,19 @@
|
||||
// @filename: file.tsx
|
||||
// @jsx: preserve
|
||||
// @noLib: true
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
import React = require('react');
|
||||
|
||||
interface Prop {
|
||||
a: number,
|
||||
b: string
|
||||
}
|
||||
|
||||
declare class MyComp<P = Prop> extends React.Component<P, {}> {
|
||||
internalProp: P;
|
||||
}
|
||||
|
||||
// Error
|
||||
let x = <MyComp />
|
||||
let x1 = <MyComp a="hi"/>
|
||||
@@ -0,0 +1,22 @@
|
||||
// @filename: file.tsx
|
||||
// @jsx: preserve
|
||||
// @noLib: true
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
import React = require('react');
|
||||
|
||||
interface Prop {
|
||||
a: number,
|
||||
b: string
|
||||
}
|
||||
|
||||
declare class MyComp<P extends Prop> extends React.Component<P, {}> {
|
||||
internalProp: P;
|
||||
}
|
||||
|
||||
// OK: we fille in missing type argument with empty object
|
||||
let x1 = <MyComp />
|
||||
|
||||
// Error
|
||||
let x = <MyComp a={10} b="hi" />
|
||||
let x2 = <MyComp a="hi"/>
|
||||
@@ -32,3 +32,5 @@ let anyobj: any;
|
||||
let x = <OverWriteAttr {...obj} y overwrite="hi" {...obj1} />
|
||||
let x1 = <OverWriteAttr overwrite="hi" {...obj1} x={3} {...{y: true}} />
|
||||
let x2 = <OverWriteAttr {...anyobj} x={3} />
|
||||
let x3 = <OverWriteAttr overwrite="hi" {...obj1} {...{y: true}} />
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// @filename: file.tsx
|
||||
// @jsx: preserve
|
||||
// @noLib: true
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
import React = require('react');
|
||||
|
||||
interface ComponentProps {
|
||||
property1: string;
|
||||
property2: number;
|
||||
}
|
||||
|
||||
export default function Component(props: ComponentProps) {
|
||||
let condition1: boolean;
|
||||
if (condition1) {
|
||||
return (
|
||||
<ChildComponent {...props} />
|
||||
);
|
||||
}
|
||||
else {
|
||||
return (<ChildComponent {...props} property1="NewString" />);
|
||||
}
|
||||
}
|
||||
|
||||
interface AnotherComponentProps {
|
||||
property1: string;
|
||||
}
|
||||
|
||||
function ChildComponent({ property1 }: AnotherComponentProps) {
|
||||
return (
|
||||
<span>{property1}</span>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// @filename: file.tsx
|
||||
// @jsx: preserve
|
||||
// @noLib: true
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
import React = require('react');
|
||||
|
||||
interface ComponentProps {
|
||||
property1: string;
|
||||
property2: number;
|
||||
}
|
||||
|
||||
export default function Component(props: ComponentProps) {
|
||||
return (
|
||||
// Error extra property
|
||||
<AnotherComponent {...props} Property1/>
|
||||
);
|
||||
}
|
||||
|
||||
interface AnotherComponentProps {
|
||||
property1: string;
|
||||
}
|
||||
|
||||
function AnotherComponent({ property1 }: AnotherComponentProps) {
|
||||
return (
|
||||
<span>{property1}</span>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// @filename: file.tsx
|
||||
// @jsx: preserve
|
||||
// @noLib: true
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
import React = require('react');
|
||||
|
||||
interface ComponentProps {
|
||||
property1: string;
|
||||
property2: number;
|
||||
}
|
||||
|
||||
export default function Component(props: ComponentProps) {
|
||||
return (
|
||||
<AnotherComponent {...props} property2 AnotherProperty1="hi"/>
|
||||
);
|
||||
}
|
||||
|
||||
interface AnotherComponentProps {
|
||||
property1: string;
|
||||
AnotherProperty1: string;
|
||||
property2: boolean;
|
||||
}
|
||||
|
||||
function AnotherComponent({ property1 }: AnotherComponentProps) {
|
||||
return (
|
||||
<span>{property1}</span>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// @filename: file.tsx
|
||||
// @jsx: preserve
|
||||
// @noLib: true
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
import React = require('react');
|
||||
|
||||
interface ComponentProps {
|
||||
property1: string;
|
||||
property2: number;
|
||||
}
|
||||
|
||||
export default function Component(props: ComponentProps) {
|
||||
return (
|
||||
// Error: missing property
|
||||
<AnotherComponent {...props} />
|
||||
);
|
||||
}
|
||||
|
||||
interface AnotherComponentProps {
|
||||
property1: string;
|
||||
AnotherProperty1: string;
|
||||
property2: boolean;
|
||||
}
|
||||
|
||||
function AnotherComponent({ property1 }: AnotherComponentProps) {
|
||||
return (
|
||||
<span>{property1}</span>
|
||||
);
|
||||
}
|
||||
@@ -21,4 +21,6 @@ const obj = {};
|
||||
// Error
|
||||
let p = <Poisoned {...obj} />;
|
||||
let y = <Poisoned />;
|
||||
let z = <Poisoned x y/>;
|
||||
let z = <Poisoned x y/>;
|
||||
let w = <Poisoned {...{x: 5, y: "2"}}/>;
|
||||
let w1 = <Poisoned {...{x: 5, y: "2"}} X="hi" />;
|
||||
@@ -34,5 +34,5 @@ class EmptyProp extends React.Component<{}, {}> {
|
||||
let o = {
|
||||
prop1: false
|
||||
}
|
||||
// Error
|
||||
// Ok
|
||||
let e = <EmptyProp {...o} />;
|
||||
@@ -18,7 +18,7 @@ let obj2: any;
|
||||
const c0 = <OneThing extraProp />; // extra property;
|
||||
const c1 = <OneThing yy={10}/>; // missing property;
|
||||
const c2 = <OneThing {...obj} yy1 />; // type incompatible;
|
||||
const c3 = <OneThing {...obj} {...{extra: "extra attr"}} />; // Extra attribute;
|
||||
const c3 = <OneThing {...obj} {...{extra: "extra attr"}} />; // This is OK becuase all attribute are spread
|
||||
const c4 = <OneThing {...obj} y1={10000} />; // extra property;
|
||||
const c5 = <OneThing {...obj} {...{yy: true}} />; // type incompatible;
|
||||
const c6 = <OneThing {...obj2} {...{extra: "extra attr"}} />; // Should error as there is extra attribute that doesn't match any. Current it is not
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
// @filename: file.tsx
|
||||
// @jsx: preserve
|
||||
// @module: amd
|
||||
// @noLib: true
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
import React = require('react')
|
||||
|
||||
interface MyComponentProp {
|
||||
values: string;
|
||||
}
|
||||
|
||||
function MyComponent<T = MyComponentProp>(attr: T) {
|
||||
return <div>attr.values</div>
|
||||
}
|
||||
|
||||
// OK
|
||||
let i = <MyComponent values />; // We infer type arguments here
|
||||
let i1 = <MyComponent values="Hello"/>;
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
// @filename: file.tsx
|
||||
// @jsx: preserve
|
||||
// @module: amd
|
||||
// @noLib: true
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
import React = require('react')
|
||||
|
||||
interface MyComponentProp {
|
||||
values: string;
|
||||
}
|
||||
|
||||
function MyComponent1<T extends MyComponentProp>(attr: T) {
|
||||
return <div>attr.values</div>
|
||||
}
|
||||
|
||||
|
||||
// Error
|
||||
let i1 = <MyComponent1 values={5}/>;
|
||||
@@ -46,7 +46,7 @@ let o = {
|
||||
prop1: true;
|
||||
}
|
||||
|
||||
// Error
|
||||
// OK as access properties are allow when spread
|
||||
let i2 = <EmptyPropSFC {...o} />
|
||||
|
||||
let o1: any;
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
import React = require('react')
|
||||
|
||||
// Error, can only spread object type
|
||||
declare function Component<U>(l: U): JSX.Element;
|
||||
function createComponent<T extends { prop: number }>(arg: T) {
|
||||
let a1 = <Component {...arg} />;
|
||||
@@ -16,9 +15,9 @@ function createComponent<T extends { prop: number }>(arg: T) {
|
||||
declare function ComponentSpecific<U>(l: { prop: U }): JSX.Element;
|
||||
declare function ComponentSpecific1<U>(l: { prop: U, "ignore-prop": number }): JSX.Element;
|
||||
|
||||
// Error, can only spread object type
|
||||
function Bar<T extends { prop: number }>(arg: T) {
|
||||
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"
|
||||
let a4 = <ComponentSpecific {...arg} prop1="hello" />; // U is "hello"
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
});
|
||||
|
||||
@@ -11,4 +11,4 @@ verify.rangeAfterCodeFix(`class C {
|
||||
static method() {
|
||||
this.foo = 10;
|
||||
}
|
||||
}`);
|
||||
}`, /*includeWhiteSpace*/false, /*errorCode*/ undefined, /*index*/ 0);
|
||||
|
||||
@@ -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 fA<T extends number>();
|
||||
//// }
|
||||
//// interface I1 extends C1, C2 { }
|
||||
//// class C3 implements I1 {[| |]}
|
||||
|
||||
verify.rangeAfterCodeFix(`f1<T extends number>(){
|
||||
verify.rangeAfterCodeFix(`fA<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);
|
||||
@@ -84,23 +84,18 @@ goTo.marker('8');
|
||||
verify.completionListContains('number');
|
||||
|
||||
goTo.marker('9');
|
||||
verify.completionListCount(40);
|
||||
verify.completionListContains("@argument");
|
||||
|
||||
goTo.marker('10');
|
||||
verify.completionListCount(40);
|
||||
verify.completionListContains("@returns");
|
||||
|
||||
goTo.marker('11');
|
||||
verify.completionListCount(40);
|
||||
verify.completionListContains("@argument");
|
||||
|
||||
goTo.marker('12');
|
||||
verify.completionListCount(40);
|
||||
verify.completionListContains("@constructor");
|
||||
|
||||
goTo.marker('13');
|
||||
verify.completionListCount(40);
|
||||
verify.completionListContains("@param");
|
||||
|
||||
goTo.marker('14');
|
||||
|
||||
@@ -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,17 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////interface A { a: number; };
|
||||
////interface B { a: number; b: number; };
|
||||
////function f<T extends keyof A>(key: T) {}
|
||||
////f("/*f*/");
|
||||
////function g<T extends keyof B>(key: T) {}
|
||||
////g("/*g*/");
|
||||
|
||||
goTo.marker("f");
|
||||
verify.completionListCount(1);
|
||||
verify.completionListContains("a");
|
||||
|
||||
goTo.marker("g");
|
||||
verify.completionListCount(2);
|
||||
verify.completionListContains("a");
|
||||
verify.completionListContains("b");
|
||||
@@ -0,0 +1,6 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////enum [|{| "isWriteAccess": true, "isDefinition": true |}E|] { A }
|
||||
////let e: [|E|].A;
|
||||
|
||||
verify.singleReferenceGroup("enum E");
|
||||
@@ -0,0 +1,6 @@
|
||||
/// <reference path="fourslash.ts"/>
|
||||
|
||||
////enum E { [|{| "isWriteAccess": true, "isDefinition": true |}A|], B }
|
||||
////const e: E.[|A|] = E.[|A|];
|
||||
|
||||
verify.singleReferenceGroup("(enum member) E.A = 0");
|
||||
@@ -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]);
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
////interface T { [|{| "isWriteAccess": true, "isDefinition": true |}a|]: number; }
|
||||
////type U = { readonly [K in keyof T]?: string };
|
||||
////declare const t: T;
|
||||
////t.[|a|];
|
||||
////declare const u: U;
|
||||
////u.[|a|];
|
||||
|
||||
const ranges = test.ranges();
|
||||
const [r0, r1, r2] = ranges;
|
||||
verify.referenceGroups([r0, r1], [{ definition: "(property) T.a: number", ranges }]);
|
||||
verify.referenceGroups(r2, [
|
||||
{ definition: "(property) T.a: number", ranges: [r0, r1] },
|
||||
{ definition: "(property) a: string", ranges: [r2] }]);
|
||||
@@ -0,0 +1,11 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// https://github.com/Microsoft/TypeScript/issues/15452
|
||||
|
||||
// @Filename: /a.ts
|
||||
////export const [|{| "isWriteAccess": true, "isDefinition": true |}x|] = 0;
|
||||
|
||||
// @Filename: /b.ts
|
||||
////import "./a";
|
||||
|
||||
verify.singleReferenceGroup("const x: 0");
|
||||
@@ -1,16 +1,14 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
//@Filename: a.ts
|
||||
////export class [|{| "isWriteAccess": true, "isDefinition": true |}Class|] {
|
||||
////}
|
||||
////export class [|{| "isWriteAccess": true, "isDefinition": true |}Class|] {}
|
||||
|
||||
//@Filename: b.ts
|
||||
////import { [|{| "isWriteAccess": true, "isDefinition": true |}Class|] as [|{| "isWriteAccess": true, "isDefinition": true |}C2|] } from "./a";
|
||||
////
|
||||
////import { [|Class|] as [|{| "isWriteAccess": true, "isDefinition": true |}C2|] } from "./a";
|
||||
////var c = new [|C2|]();
|
||||
|
||||
//@Filename: c.ts
|
||||
////export { [|{| "isWriteAccess": true, "isDefinition": true |}Class|] as [|{| "isWriteAccess": true, "isDefinition": true |}C3|] } from "./a";
|
||||
////export { [|Class|] as [|{| "isWriteAccess": true, "isDefinition": true |}C3|] } from "./a";
|
||||
|
||||
const ranges = test.rangesByText();
|
||||
const classRanges = ranges.get("Class");
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// @Filename: /a.ts
|
||||
////var [|{| "isWriteAccess": true, "isDefinition": true |}x|];
|
||||
////export { [|{| "isWriteAccess": true, "isDefinition": true |}x|] };
|
||||
////export { [|{| "isWriteAccess": true, "isDefinition": true |}x|] as [|{| "isWriteAccess": true, "isDefinition": true |}y|] };
|
||||
////export { [|x|] as [|{| "isWriteAccess": true, "isDefinition": true |}y|] };
|
||||
|
||||
// @Filename: /b.ts
|
||||
////import { [|{| "isWriteAccess": true, "isDefinition": true |}x|], [|{| "isWriteAccess": true, "isDefinition": true |}y|] } from "./a";
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
////export function [|{| "isWriteAccess": true, "isDefinition": true |}foo|](): void {}
|
||||
|
||||
// @Filename: /b.ts
|
||||
////export { [|{| "isWriteAccess": true, "isDefinition": true |}foo|] as [|{| "isWriteAccess": true, "isDefinition": true |}bar|] } from "./a";
|
||||
////export { [|foo|] as [|{| "isWriteAccess": true, "isDefinition": true |}bar|] } from "./a";
|
||||
|
||||
// @Filename: /c.ts
|
||||
////export { [|{| "isWriteAccess": true, "isDefinition": true |}foo|] as [|{| "isWriteAccess": true, "isDefinition": true |}default|] } from "./a";
|
||||
////export { [|foo|] as [|{| "isWriteAccess": true, "isDefinition": true |}default|] } from "./a";
|
||||
|
||||
// @Filename: /d.ts
|
||||
////export { [|{| "isWriteAccess": true, "isDefinition": true |}default|] } from "./c";
|
||||
@@ -15,7 +15,7 @@
|
||||
// @Filename: /e.ts
|
||||
////import { [|{| "isWriteAccess": true, "isDefinition": true |}bar|] } from "./b";
|
||||
////import [|{| "isWriteAccess": true, "isDefinition": true |}baz|] from "./c";
|
||||
////import { [|{| "isWriteAccess": true, "isDefinition": true |}default|] as [|{| "isWriteAccess": true, "isDefinition": true |}bang|] } from "./c";
|
||||
////import { [|default|] as [|{| "isWriteAccess": true, "isDefinition": true |}bang|] } from "./c";
|
||||
////import [|{| "isWriteAccess": true, "isDefinition": true |}boom|] from "./d";
|
||||
////[|bar|](); [|baz|](); [|bang|](); [|boom|]();
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @Filename: /a.ts
|
||||
////export function [|{| "isWriteAccess": true, "isDefinition": true |}foo|](): void {}
|
||||
|
||||
// @Filename: /b.ts
|
||||
////import { [|foo|] as [|{| "isWriteAccess": true, "isDefinition": true |}oof|] } from "./a";
|
||||
|
||||
verify.noErrors();
|
||||
const [r0, r1, r2] = test.ranges();
|
||||
verify.referenceGroups(r0, [
|
||||
{ definition: "function foo(): void", ranges: [r0, r1] },
|
||||
{ definition: "import oof", ranges: [r2] }
|
||||
]);
|
||||
@@ -4,7 +4,7 @@
|
||||
////export const [|{| "isWriteAccess": true, "isDefinition": true |}x|] = 0;
|
||||
|
||||
//@Filename: /b.ts
|
||||
////import { [|{| "isWriteAccess": true, "isDefinition": true |}x|] as [|{| "isWriteAccess": true, "isDefinition": true |}x|] } from "./a";
|
||||
////import { [|x|] as [|{| "isWriteAccess": true, "isDefinition": true |}x|] } from "./a";
|
||||
////[|x|];
|
||||
|
||||
verify.noErrors();
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
/// <reference path="fourslash.ts"/>
|
||||
|
||||
////class C {
|
||||
//// /*method*/async [0]() { }
|
||||
////}
|
||||
|
||||
format.document();
|
||||
goTo.marker("method");
|
||||
verify.currentLineContentIs(" async [0]() { }");
|
||||
@@ -0,0 +1,9 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
/////*1*/interface Gourai { new () {} }
|
||||
/////*2*/type Stylet = { new () {} }
|
||||
format.document();
|
||||
goTo.marker("1");
|
||||
verify.currentLineContentIs("interface Gourai { new() {} }");
|
||||
goTo.marker("2");
|
||||
verify.currentLineContentIs("type Stylet = { new() {} }");
|
||||
@@ -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");
|
||||
|
||||
@@ -7,4 +7,4 @@
|
||||
//// export function f1() {}
|
||||
//// export var v1 = 5;
|
||||
|
||||
verify.importFixAtPosition([`{ v1, f1 }`]);
|
||||
verify.importFixAtPosition([`{ v1, f1 }`]);
|
||||
|
||||
@@ -8,4 +8,4 @@
|
||||
//// export var v1 = 5;
|
||||
//// export default var d1 = 6;
|
||||
|
||||
verify.importFixAtPosition([`{ v1, f1 }`]);
|
||||
verify.importFixAtPosition([`{ v1, f1 }`]);
|
||||
|
||||
@@ -18,4 +18,4 @@ verify.importFixAtPosition([
|
||||
v2,
|
||||
f1
|
||||
}`
|
||||
]);
|
||||
]);
|
||||
|
||||
@@ -18,4 +18,4 @@ verify.importFixAtPosition([
|
||||
v3,
|
||||
f1
|
||||
}`
|
||||
]);
|
||||
]);
|
||||
|
||||
@@ -9,4 +9,4 @@
|
||||
//// export var v2 = 5;
|
||||
//// export var v3 = 5;
|
||||
|
||||
verify.importFixAtPosition([`{ f1 }`]);
|
||||
verify.importFixAtPosition([`{ f1 }`]);
|
||||
|
||||
@@ -12,5 +12,5 @@ verify.importFixAtPosition([
|
||||
import { f1 } from "./module";
|
||||
f1();`,
|
||||
`import * as ns from "./module";
|
||||
ns.f1();`
|
||||
]);
|
||||
ns.f1();`,
|
||||
]);
|
||||
|
||||
@@ -14,5 +14,5 @@ verify.importFixAtPosition([
|
||||
ns.f1();`,
|
||||
`import d, * as ns from "./module" ;
|
||||
import { f1 } from "./module";
|
||||
f1();`,
|
||||
]);
|
||||
f1();`
|
||||
]);
|
||||
|
||||
@@ -11,4 +11,4 @@
|
||||
verify.importFixAtPosition([
|
||||
`import d, { f1 } from "./module";
|
||||
f1();`
|
||||
]);
|
||||
]);
|
||||
|
||||
@@ -9,4 +9,4 @@
|
||||
|
||||
verify.importFixAtPosition([`import "./module";
|
||||
import { f1 } from "./module";
|
||||
f1();`]);
|
||||
f1();`]);
|
||||
|
||||
@@ -10,4 +10,4 @@
|
||||
//// export var v1 = 5;
|
||||
//// export function f1();
|
||||
|
||||
verify.importFixAtPosition([`{ v1, f1 }`]);
|
||||
verify.importFixAtPosition([`{ v1, f1 }`]);
|
||||
|
||||
@@ -7,4 +7,4 @@
|
||||
//// export var v1 = 5;
|
||||
//// export function f1();
|
||||
|
||||
verify.importFixAtPosition([`{ v1, f1 }`]);
|
||||
verify.importFixAtPosition([`{ v1, f1 }`]);
|
||||
|
||||
@@ -9,4 +9,4 @@
|
||||
//// export var v2 = 5;
|
||||
//// export var v3 = 5;
|
||||
|
||||
verify.importFixAtPosition([`{v1, v2, v3, f1,}`]);
|
||||
verify.importFixAtPosition([`{v1, v2, v3, f1,}`]);
|
||||
|
||||
@@ -13,4 +13,4 @@ verify.importFixAtPosition([
|
||||
`{
|
||||
v1, f1
|
||||
}`
|
||||
]);
|
||||
]);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user