Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"editor.formatOnSave": true
}
4 changes: 4 additions & 0 deletions snapshots/input/syntax/src/import.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@ export function useEverything(): string {
newFunction()
)
}

export function dynamicImport(): Promise<void> {
return import('./function').then(c => c.newFunction())
}
10 changes: 10 additions & 0 deletions snapshots/input/syntax/src/string-literals.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
interface SomeInterface {
a: number
b: number
c: number
}
// "Go to definition" does not work for the 'a', 'b' and 'c' string literals
// below when using tsserver so it's fine that scip-typescript does not emit
// occurrences here either.
export type OmitInterface = Omit<SomeInterface, 'a' | 'b'>
export type PickInterface = Pick<SomeInterface, 'b' | 'c'>
2 changes: 2 additions & 0 deletions snapshots/output/multi-project/packages/a/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export function a(): string {
// definition @example/a 1.0.0 src/`index.ts`/
//documentation ```ts\nmodule "index.ts"\n```
// ^ definition @example/a 1.0.0 src/`index.ts`/a().
// documentation ```ts\nfunction a(): string\n```
return ''
Expand Down
3 changes: 3 additions & 0 deletions snapshots/output/multi-project/packages/b/src/b.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { a } from '@example/a/src'
// definition @example/b 1.0.0 src/`b.ts`/
//documentation ```ts\nmodule "b.ts"\n```
// ^ reference @example/a 1.0.0 src/`index.ts`/a().
// ^^^^^^^^^^^^^^^^ reference @example/a 1.0.0 src/`index.ts`/

export function b() {
// ^ definition @example/b 1.0.0 src/`b.ts`/b().
Expand Down
2 changes: 2 additions & 0 deletions snapshots/output/pure-js/src/main.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
function fib(n) {
// definition pure-js 1.0.0 src/`main.js`/
//documentation ```ts\nmodule "main.js"\n```
// ^^^ definition pure-js 1.0.0 src/`main.js`/fib().
// documentation ```ts\nfunction fib(n: any): any\n```
// ^ definition pure-js 1.0.0 src/`main.js`/fib().(n)
Expand Down
3 changes: 3 additions & 0 deletions snapshots/output/react/src/LoaderInput.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import React from 'react'
// definition react-example 1.0.0 src/`LoaderInput.tsx`/
//documentation ```ts\nmodule "LoaderInput.tsx"\n```
// ^^^^^ reference @types/react 17.0.0 `index.d.ts`/React/
// ^^^^^^^ reference @types/react 17.0.0 `index.d.ts`/

/** Takes loading prop, input component as child */
interface Props {
Expand Down
3 changes: 3 additions & 0 deletions snapshots/output/react/src/MyTSXElement.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import React from 'react'
// definition react-example 1.0.0 src/`MyTSXElement.tsx`/
//documentation ```ts\nmodule "MyTSXElement.tsx"\n```
// ^^^^^ reference @types/react 17.0.0 `index.d.ts`/React/
// ^^^^^^^ reference @types/react 17.0.0 `index.d.ts`/

export interface MyProps {}
// ^^^^^^^ definition react-example 1.0.0 src/`MyTSXElement.tsx`/MyProps#
Expand Down
4 changes: 4 additions & 0 deletions snapshots/output/react/src/UseMyTSXElement.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import React from "react";
// definition react-example 1.0.0 src/`UseMyTSXElement.tsx`/
//documentation ```ts\nmodule "UseMyTSXElement.tsx"\n```
// ^^^^^ reference @types/react 17.0.0 `index.d.ts`/React/
// ^^^^^^^ reference @types/react 17.0.0 `index.d.ts`/

import { MyProps, MyTSXElement } from "./MyTSXElement";
// ^^^^^^^ reference react-example 1.0.0 src/`MyTSXElement.tsx`/MyProps#
// ^^^^^^^^^^^^ reference react-example 1.0.0 src/`MyTSXElement.tsx`/MyTSXElement.
// ^^^^^^^^^^^^^^^^ reference react-example 1.0.0 src/`MyTSXElement.tsx`/

export const _: React.FunctionComponent<MyProps> =
// ^ definition react-example 1.0.0 src/`UseMyTSXElement.tsx`/_.
Expand Down
2 changes: 2 additions & 0 deletions snapshots/output/syntax/src/accessors.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
class C {
// definition syntax 1.0.0 src/`accessors.ts`/
//documentation ```ts\nmodule "accessors.ts"\n```
// ^ definition syntax 1.0.0 src/`accessors.ts`/C#
// documentation ```ts\nclass C\n```
_length: number = 0
Expand Down
2 changes: 2 additions & 0 deletions snapshots/output/syntax/src/class.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export class Class {
// definition syntax 1.0.0 src/`class.ts`/
//documentation ```ts\nmodule "class.ts"\n```
// ^^^^^ definition syntax 1.0.0 src/`class.ts`/Class#
// documentation ```ts\nclass Class\n```
public classProperty: string
Expand Down
2 changes: 2 additions & 0 deletions snapshots/output/syntax/src/enum.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export enum Enum {
// definition syntax 1.0.0 src/`enum.ts`/
//documentation ```ts\nmodule "enum.ts"\n```
// ^^^^ definition syntax 1.0.0 src/`enum.ts`/Enum#
// documentation ```ts\nenum Enum\n```
A,
Expand Down
2 changes: 2 additions & 0 deletions snapshots/output/syntax/src/function.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export function newFunction(): void {}
// definition syntax 1.0.0 src/`function.ts`/
//documentation ```ts\nmodule "function.ts"\n```
// ^^^^^^^^^^^ definition syntax 1.0.0 src/`function.ts`/newFunction().
// documentation ```ts\nfunction newFunction(): void\n```

23 changes: 23 additions & 0 deletions snapshots/output/syntax/src/import.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import { Class } from './class'
// definition syntax 1.0.0 src/`import.ts`/
//documentation ```ts\nmodule "import.ts"\n```
// ^^^^^ reference syntax 1.0.0 src/`class.ts`/Class#
// ^^^^^^^^^ reference syntax 1.0.0 src/`class.ts`/
import { Enum } from './enum'
// ^^^^ reference syntax 1.0.0 src/`enum.ts`/Enum#
// ^^^^^^^^ reference syntax 1.0.0 src/`enum.ts`/
import { newFunction } from './function'
// ^^^^^^^^^^^ reference syntax 1.0.0 src/`function.ts`/newFunction().
// ^^^^^^^^^^^^ reference syntax 1.0.0 src/`function.ts`/
import { newInterface as renamedInterface } from './interface'
// ^^^^^^^^^^^^ reference syntax 1.0.0 src/`interface.ts`/newInterface().
// ^^^^^^^^^^^^^^^^ reference syntax 1.0.0 src/`interface.ts`/newInterface().
// ^^^^^^^^^^^^^ reference syntax 1.0.0 src/`interface.ts`/

export function useEverything(): string {
// ^^^^^^^^^^^^^ definition syntax 1.0.0 src/`import.ts`/useEverything().
Expand All @@ -27,3 +33,20 @@
)
}

export function dynamicImport(): Promise<void> {
// ^^^^^^^^^^^^^ definition syntax 1.0.0 src/`import.ts`/dynamicImport().
// documentation ```ts\nfunction dynamicImport(): Promise<void>\n```
// ^^^^^^^ reference typescript 4.8.4 lib/`lib.es5.d.ts`/Promise#
// ^^^^^^^ reference typescript 4.8.4 lib/`lib.es2015.iterable.d.ts`/Promise#
// ^^^^^^^ reference typescript 4.8.4 lib/`lib.es2015.promise.d.ts`/Promise.
// ^^^^^^^ reference typescript 4.8.4 lib/`lib.es2015.symbol.wellknown.d.ts`/Promise#
// ^^^^^^^ reference typescript 4.8.4 lib/`lib.es2018.promise.d.ts`/Promise#
return import('./function').then(c => c.newFunction())
// ^^^^^^^^^^^^ reference syntax 1.0.0 src/`function.ts`/
// ^^^^ reference typescript 4.8.4 lib/`lib.es5.d.ts`/Promise#then().
// ^ definition local 3
// documentation ```ts\n(parameter) c: typeof import("/src/function")\n```
// ^ reference local 3
// ^^^^^^^^^^^ reference syntax 1.0.0 src/`function.ts`/newFunction().
}

3 changes: 3 additions & 0 deletions snapshots/output/syntax/src/inheritance.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { Overloader } from './overload'
// definition syntax 1.0.0 src/`inheritance.ts`/
//documentation ```ts\nmodule "inheritance.ts"\n```
// ^^^^^^^^^^ reference syntax 1.0.0 src/`overload.d.ts`/Overloader#
// ^^^^^^^^^^^^ reference syntax 1.0.0 src/`overload.d.ts`/

export interface Superinterface {
// ^^^^^^^^^^^^^^ definition syntax 1.0.0 src/`inheritance.ts`/Superinterface#
Expand Down
2 changes: 2 additions & 0 deletions snapshots/output/syntax/src/interface.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export interface Interface {
// definition syntax 1.0.0 src/`interface.ts`/
//documentation ```ts\nmodule "interface.ts"\n```
// ^^^^^^^^^ definition syntax 1.0.0 src/`interface.ts`/Interface#
// documentation ```ts\ninterface Interface\n```
property: string
Expand Down
2 changes: 2 additions & 0 deletions snapshots/output/syntax/src/issue-45.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export namespace example {
// definition syntax 1.0.0 src/`issue-45.d.ts`/
//documentation ```ts\nmodule "issue-45.d.ts"\n```
// ^^^^^^^ definition syntax 1.0.0 src/`issue-45.d.ts`/example/
// documentation ```ts\nexample: typeof example\n```
class Server {
Expand Down
2 changes: 2 additions & 0 deletions snapshots/output/syntax/src/local.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export function local(): string {
// definition syntax 1.0.0 src/`local.ts`/
//documentation ```ts\nmodule "local.ts"\n```
// ^^^^^ definition syntax 1.0.0 src/`local.ts`/local().
// documentation ```ts\nfunction local(): string\n```
const a = 'a'
Expand Down
4 changes: 4 additions & 0 deletions snapshots/output/syntax/src/module.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
declare module 'a:b' {
// definition syntax 1.0.0 src/`module.d.ts`/
//documentation ```ts\nmodule "module.d.ts"\n```
// ^^^^^ definition syntax 1.0.0 src/`module.d.ts`/`'a:b'`/
// documentation ```ts\n'a:b': typeof import("a:b")\n```
function hello(): string
// ^^^^^ definition syntax 1.0.0 src/`module.d.ts`/`'a:b'`/hello().
// documentation ```ts\nfunction hello(): string\n```
Expand Down
2 changes: 2 additions & 0 deletions snapshots/output/syntax/src/namespace.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
declare namespace a {
// definition syntax 1.0.0 src/`namespace.d.ts`/
//documentation ```ts\nmodule "namespace.d.ts"\n```
// ^ definition syntax 1.0.0 src/`namespace.d.ts`/a/
// documentation ```ts\na: typeof a\n```
function hello(): string
Expand Down
2 changes: 2 additions & 0 deletions snapshots/output/syntax/src/overload.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export interface Overloader {
// definition syntax 1.0.0 src/`overload.d.ts`/
//documentation ```ts\nmodule "overload.d.ts"\n```
// ^^^^^^^^^^ definition syntax 1.0.0 src/`overload.d.ts`/Overloader#
// documentation ```ts\ninterface Overloader\n```
onLiteral(param: 'a'): void
Expand Down
3 changes: 3 additions & 0 deletions snapshots/output/syntax/src/property-assignment-reference.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import {
// definition syntax 1.0.0 src/`property-assignment-reference.ts`/
//documentation ```ts\nmodule "property-assignment-reference.ts"\n```
propertyAssignment,
// ^^^^^^^^^^^^^^^^^^ reference syntax 1.0.0 src/`property-assignment.ts`/propertyAssignment().
shorthandPropertyAssignment,
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference syntax 1.0.0 src/`property-assignment.ts`/shorthandPropertyAssignment().
} from './property-assignment'
// ^^^^^^^^^^^^^^^^^^^^^^^ reference syntax 1.0.0 src/`property-assignment.ts`/

export function run(): string {
// ^^^ definition syntax 1.0.0 src/`property-assignment-reference.ts`/run().
Expand Down
2 changes: 2 additions & 0 deletions snapshots/output/syntax/src/property-assignment.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export function propertyAssignment() {
// definition syntax 1.0.0 src/`property-assignment.ts`/
//documentation ```ts\nmodule "property-assignment.ts"\n```
// ^^^^^^^^^^^^^^^^^^ definition syntax 1.0.0 src/`property-assignment.ts`/propertyAssignment().
// documentation ```ts\nfunction propertyAssignment(): { a: string; }\n```
return { a: 'a' }
Expand Down
29 changes: 29 additions & 0 deletions snapshots/output/syntax/src/string-literals.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
interface SomeInterface {
// definition syntax 1.0.0 src/`string-literals.ts`/
//documentation ```ts\nmodule "string-literals.ts"\n```
// ^^^^^^^^^^^^^ definition syntax 1.0.0 src/`string-literals.ts`/SomeInterface#
// documentation ```ts\ninterface SomeInterface\n```
a: number
// ^ definition syntax 1.0.0 src/`string-literals.ts`/SomeInterface#a.
// documentation ```ts\n(property) a: number\n```
b: number
// ^ definition syntax 1.0.0 src/`string-literals.ts`/SomeInterface#b.
// documentation ```ts\n(property) b: number\n```
c: number
// ^ definition syntax 1.0.0 src/`string-literals.ts`/SomeInterface#c.
// documentation ```ts\n(property) c: number\n```
}
// "Go to definition" does not work for the 'a', 'b' and 'c' string literals
// below when using tsserver so it's fine that scip-typescript does not emit
// occurrences here either.
export type OmitInterface = Omit<SomeInterface, 'a' | 'b'>
// ^^^^^^^^^^^^^ definition syntax 1.0.0 src/`string-literals.ts`/OmitInterface#
// documentation ```ts\ntype OmitInterface\n```
// ^^^^ reference typescript 4.8.4 lib/`lib.es5.d.ts`/Omit#
// ^^^^^^^^^^^^^ reference syntax 1.0.0 src/`string-literals.ts`/SomeInterface#
export type PickInterface = Pick<SomeInterface, 'b' | 'c'>
// ^^^^^^^^^^^^^ definition syntax 1.0.0 src/`string-literals.ts`/PickInterface#
// documentation ```ts\ntype PickInterface\n```
// ^^^^ reference typescript 4.8.4 lib/`lib.es5.d.ts`/Pick#
// ^^^^^^^^^^^^^ reference syntax 1.0.0 src/`string-literals.ts`/SomeInterface#

2 changes: 2 additions & 0 deletions snapshots/output/syntax/src/type-alias.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
type S = string
// definition syntax 1.0.0 src/`type-alias.ts`/
//documentation ```ts\nmodule "type-alias.ts"\n```
// ^ definition syntax 1.0.0 src/`type-alias.ts`/S#
// documentation ```ts\ntype S\n```

Expand Down
2 changes: 2 additions & 0 deletions snapshots/output/syntax/src/type-parameter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export function typeParameter<A, B>(parameter: A, parameter2: B): [A, B] {
// definition syntax 1.0.0 src/`type-parameter.ts`/
//documentation ```ts\nmodule "type-parameter.ts"\n```
// ^^^^^^^^^^^^^ definition syntax 1.0.0 src/`type-parameter.ts`/typeParameter().
// documentation ```ts\nfunction typeParameter<A, B>(parameter: A, parameter2: B): [A, B]\n```
// ^ definition syntax 1.0.0 src/`type-parameter.ts`/typeParameter().[A]
Expand Down
51 changes: 43 additions & 8 deletions src/FileIndexer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import path from 'path'

import * as ts from 'typescript'

import { ProjectOptions } from './CommandLineOptions'
import { Counter } from './Counter'
import {
metaDescriptor,
Expand All @@ -25,22 +28,48 @@ export class FileIndexer {
private localCounter = new Counter()
private propertyCounters: Map<string, Counter> = new Map()
private localSymbolTable: Map<ts.Node, LsifSymbol> = new Map()
private workingDirectoryRegExp: RegExp
constructor(
public readonly checker: ts.TypeChecker,
public readonly options: ProjectOptions,
public readonly input: Input,
public readonly document: lsif.lib.codeintel.lsiftyped.Document,
public readonly globalSymbolTable: Map<ts.Node, LsifSymbol>,
public readonly packages: Packages,
public readonly sourceFile: ts.SourceFile
) {}
) {
this.workingDirectoryRegExp = new RegExp(options.cwd, 'g')
}
public index(): void {
this.emitSourceFileOccurrence()
this.visit(this.sourceFile)
}
private emitSourceFileOccurrence(): void {
const symbol = this.lsifSymbol(this.sourceFile)
if (symbol.isEmpty()) {
return
}
this.document.occurrences.push(
new lsif.lib.codeintel.lsiftyped.Occurrence({
range: [0, 0, 0],
symbol: symbol.value,
symbol_roles: lsiftyped.SymbolRole.Definition,
})
)
const moduleName =
this.sourceFile.moduleName || path.basename(this.sourceFile.fileName)
this.document.symbols.push(
new lsiftyped.SymbolInformation({
symbol: symbol.value,
documentation: ['```ts\nmodule "' + moduleName + '"\n```'],
})
)
}
private visit(node: ts.Node): void {
if (ts.isIdentifier(node)) {
if (ts.isIdentifier(node) || ts.isStringLiteralLike(node)) {
const sym = this.getTSSymbolAtLocation(node)
if (sym) {
this.visitIdentifier(node, sym)
this.visitSymbolOccurrence(node, sym)
}
}
ts.forEachChild(node, node => this.visit(node))
Expand All @@ -52,6 +81,7 @@ export class FileIndexer {
// This code is directly based off src/services/goToDefinition.ts.
private getTSSymbolAtLocation(node: ts.Node): ts.Symbol | undefined {
const symbol = this.checker.getSymbolAtLocation(node)

// If this is an alias, and the request came at the declaration location
// get the aliased symbol instead. This allows for goto def on an import e.g.
// import {A, B} from "mod";
Expand All @@ -71,10 +101,10 @@ export class FileIndexer {
return symbol
}

private visitIdentifier(identifier: ts.Identifier, sym: ts.Symbol): void {
const range = Range.fromNode(identifier).toLsif()
private visitSymbolOccurrence(node: ts.Node, sym: ts.Symbol): void {
const range = Range.fromNode(node).toLsif()
let role = 0
const isDefinition = this.declarationName(identifier.parent) === identifier
const isDefinition = this.declarationName(node.parent) === node
if (isDefinition) {
role |= lsiftyped.SymbolRole.Definition
}
Expand All @@ -92,7 +122,7 @@ export class FileIndexer {
})
)
if (isDefinition) {
this.addSymbolInformation(identifier, sym, declaration, lsifSymbol)
this.addSymbolInformation(node, sym, declaration, lsifSymbol)
this.handleShorthandPropertyDefinition(declaration, range)
// Only emit one symbol for definitions sites, see https://github.com/sourcegraph/lsif-typescript/issues/45
break
Expand Down Expand Up @@ -137,14 +167,19 @@ export class FileIndexer {
}
}

private hideWorkingDirectory(value: string): string {
return value.replace(this.workingDirectoryRegExp, '')
}
private addSymbolInformation(
node: ts.Node,
sym: ts.Symbol,
declaration: ts.Node,
symbol: LsifSymbol
): void {
const documentation = [
'```ts\n' + this.signatureForDocumentation(node, sym) + '\n```',
'```ts\n' +
this.hideWorkingDirectory(this.signatureForDocumentation(node, sym)) +
'\n```',
]
const docstring = sym.getDocumentationComment(this.checker)
if (docstring.length > 0) {
Expand Down
Loading