Skip to content

Commit

Permalink
Merge pull request #68 from alephium/Add-muti-project
Browse files Browse the repository at this point in the history
Add multi project
  • Loading branch information
suyanlong authored Nov 27, 2022
2 parents 696b6e9 + eb209fa commit dc26bb2
Show file tree
Hide file tree
Showing 19 changed files with 108 additions and 24 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "ralph-vscode",
"displayName": "ralph vscode",
"description": "ralph vscode",
"version": "0.1.6",
"version": "0.1.7",
"engines": {
"vscode": "^1.69.0",
"node": ">=v18.0.0"
Expand Down
79 changes: 79 additions & 0 deletions src/ast/project.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import vscode, { Uri } from 'vscode'
import path from 'path'
import { Root } from './root'
import { Identifier } from './identifier'
import { Word } from './word'
import { Position } from './position'

export class MultiProjects {
projects: Map<string, Root>

constructor() {
this.projects = new Map<string, Root>()
}

projectDir(projectPath: Uri | string): string {
if (projectPath instanceof Uri) {
if (vscode.workspace.rootPath) {
return projectPath.path.split(vscode.workspace.rootPath)[1].split(path.sep)[1]
}
return 'root'
}
return <string>projectPath
}

merge(path: Uri, members: Identifier[]) {
const dir = this.projectDir(path)
if (this.projects.get(dir)) {
this.root(path)?.merge(path, members)
} else {
const root = new Root()
root.merge(path, members)
this.projects.set(dir, root)
}
}

remove(path: Uri) {
return this.root(path)?.remove(path)
}

def(path: Uri | string, word: Word): Identifier | undefined {
return this.root(path)?.def(word)
}

defs(path?: Uri | string): Identifier[] {
if (path) {
const root = this.root(path)
if (root) return root.defs()
return []
}
const items: Identifier[] = []
this.projects.forEach((root) => items.push(...root.defs()))
return items
}

get(path: Uri | string, name: string): Identifier | undefined {
return this.root(path)?.get(name)
}

container(path: Uri | string, position: Position): Identifier | undefined {
return this.root(path)?.container(position)
}

findAll(path: Uri | string, identifier: Word): Identifier[] {
const root = this.root(path)
if (root) return root.findAll(identifier)
return []
}

root(path: Uri | string): Root {
const dir = this.projectDir(path)
const root = this.projects.get(dir)
if (root) return root
return new Root()
}

analyse() {
this.projects.forEach((root) => root.analyse())
}
}
2 changes: 1 addition & 1 deletion src/ast/property.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export class Property extends SemanticNode {
}

getType(): Identifier | undefined {
return caches.get(<string>this.type_?.name)
return caches.get(this.getUri()!, <string>this.type_?.name)
}

label(): string {
Expand Down
2 changes: 1 addition & 1 deletion src/ast/root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export class Root extends Base {
})
}

get(name: string) {
get(name: string): Identifier | undefined {
return this.members.get(name)
}

Expand Down
2 changes: 1 addition & 1 deletion src/ast/variable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export class Variable extends SemanticNode {
}

getType(): Identifier | undefined {
return caches.get(<string>this.type_?.name)
return caches.get(this.getUri()!, <string>this.type_?.name)
}

label(): string {
Expand Down
5 changes: 3 additions & 2 deletions src/cache/cache.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Root } from '../ast/root'
import { MultiProjects } from '../ast/project'

const cache = new Root()
// const cache = new Root()
const cache = new MultiProjects()
export default cache
2 changes: 1 addition & 1 deletion src/provider/completion/emitProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export class EmitProvider extends Filter implements vscode.CompletionItemProvide
token: vscode.CancellationToken,
context: vscode.CompletionContext
): vscode.ProviderResult<vscode.CompletionItem[] | vscode.CompletionList> {
return this.emitter(cache.container({ point: position, uri: document.uri }))
return this.emitter(cache.container(document.uri, { point: position, uri: document.uri }))
}

resolveCompletionItem(item: vscode.CompletionItem, token: CancellationToken): ProviderResult<vscode.CompletionItem> {
Expand Down
2 changes: 1 addition & 1 deletion src/provider/completion/enumProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export class EnumProvider extends Filter implements vscode.CompletionItemProvide
): vscode.ProviderResult<vscode.CompletionItem[] | vscode.CompletionList> {
const word = this.word(document, position, -1)
if (word) {
const member = cache.def(word)
const member = cache.def(document.uri, word)
if (member) return member?.getChild?.().map((value) => value.completionItem!())
}
return undefined
Expand Down
2 changes: 1 addition & 1 deletion src/provider/completion/globalProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ export class GlobalProvider extends Filter implements vscode.CompletionItemProvi
context: vscode.CompletionContext
): vscode.ProviderResult<vscode.CompletionItem[] | vscode.CompletionList> {
if (this.isSkip(document, position)) return undefined
return cache.defs()?.map((value) => value.completionItem!())
return cache.defs(document.uri)?.map((value) => value.completionItem!())
}
}
2 changes: 1 addition & 1 deletion src/provider/completion/identifierProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export class IdentifierProvider extends Filter implements vscode.CompletionItemP
): vscode.ProviderResult<vscode.CompletionItem[] | vscode.CompletionList> {
if (this.isSkip(document, position)) return undefined
const pos = { uri: document.uri, point: position }
const container = cache.container(pos)
const container = cache.container(document.uri, pos)
return this.defs(container)
}

Expand Down
2 changes: 1 addition & 1 deletion src/provider/completion/memberProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class MemberProvider extends Filter implements vscode.CompletionItemProvi
const word = this.word(document, position, -1)
if (word) {
return cache
.def(word)
.def(document.uri, word)
?.getType?.()
?.defs?.()
.filter((value) => {
Expand Down
2 changes: 1 addition & 1 deletion src/provider/filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export class Filter {
point: position,
uri: document.uri,
}
let caller = cache.def(word)
let caller = cache.def(document.uri, word)
let i = 0
while (true) {
if (wordSet.length - 1 === i) {
Expand Down
2 changes: 1 addition & 1 deletion src/provider/implementationProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export class RalphImplementationProvider extends Filter implements vscode.Implem
): ProviderResult<Definition | DefinitionLink[]> {
const word = this.word(document, position)
if (word && word.name) {
const base = cache.get(word.name)
const base = cache.get(document.uri, word.name)
if (base instanceof Interface) {
return Array.from(base.implementer.values()).map((value) => value.location())
}
Expand Down
2 changes: 1 addition & 1 deletion src/provider/referenceProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ export class RalphReferenceProvider extends Filter implements ReferenceProvider
): ProviderResult<Location[]> {
if (this.isSkip(document, position)) return undefined
const word = document.getText(document.getWordRangeAtPosition(position, /[a-zA-Z][0-9a-zA-Z]*/i))
return cache.findAll({ name: word }).map((value) => value.location!())
return cache.findAll(document.uri, { name: word }).map((value) => value.location!())
}
}
2 changes: 1 addition & 1 deletion src/provider/renameProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export class RalphRenameProvider extends Filter implements RenameProvider {
// }
// }
const word = document.getText(document.getWordRangeAtPosition(position, /[a-zA-Z][0-9a-zA-Z]*/i))
cache.findAll({ name: word }).forEach((member) =>
cache.findAll(document.uri, { name: word }).forEach((member) =>
edit.replace(<Uri>member.getUri?.(), <vscode.Range>member.getWordRange?.(), newName, {
label: member.name!,
needsConfirmation: true,
Expand Down
7 changes: 5 additions & 2 deletions src/provider/symbolProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export class SymbolProvider implements vscode.DocumentSymbolProvider, vscode.Wor
*/
provideDocumentSymbols(document: vscode.TextDocument): vscode.ProviderResult<vscode.DocumentSymbol[] | vscode.SymbolInformation[]> {
return cache
.defs()
.defs(document.uri)
?.filter((c) => c.getUri?.()?.path === document.uri.path)
.map((item) => item.documentSymbol!())
}
Expand All @@ -36,6 +36,9 @@ export class SymbolProvider implements vscode.DocumentSymbolProvider, vscode.Wor
* signaled by returning `undefined`, `null`, or an empty array.
*/
provideWorkspaceSymbols(query: string, token: CancellationToken): ProviderResult<SymbolInformation[]> {
return cache.findAll({ name: query }).map((value) => value.symbolInformation!())
if (vscode.window.activeTextEditor) {
return cache.findAll(vscode.window.activeTextEditor.document.uri, { name: query }).map((value) => value.symbolInformation!())
}
return undefined
}
}
2 changes: 1 addition & 1 deletion src/provider/typeDefinitionProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export class RalphTypeDefinitionProvider extends Filter implements TypeDefinitio
token: CancellationToken
): ProviderResult<Definition | DefinitionLink[]> {
const word = this.word(document, position)
if (word && word.name) return cache.get(word.name)?.location?.()
if (word && word.name) return cache.get(document.uri, word.name)?.location?.()
return undefined
}
}
7 changes: 4 additions & 3 deletions src/provider/typeHierarchyProvider.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { CancellationToken, Position, ProviderResult, TextDocument, TypeHierarchyItem, TypeHierarchyProvider } from 'vscode'
import it from 'node:test'
import { Filter } from './filter'
import cache from '../cache/cache'
import { Contract } from '../ast/contract'
Expand All @@ -22,7 +23,7 @@ export class RalphTypeHierarchyProvider extends Filter implements TypeHierarchyP
token: CancellationToken
): ProviderResult<TypeHierarchyItem | TypeHierarchyItem[]> {
const word = this.word(document, position)
if (word && word.name) return cache.get(word.name)?.typeHierarchyItem?.()
if (word && word.name) return cache.get(document.uri, word.name)?.typeHierarchyItem?.()
return undefined
}

Expand All @@ -37,7 +38,7 @@ export class RalphTypeHierarchyProvider extends Filter implements TypeHierarchyP
* signaled by returning `undefined` or `null`.
*/
provideTypeHierarchySupertypes(item: TypeHierarchyItem, token: CancellationToken): ProviderResult<TypeHierarchyItem[]> {
const instance = cache.get(item.name)
const instance = cache.get(item.uri, item.name)
const parts: TypeHierarchyItem[] = []
if (instance instanceof Contract) {
if (instance.interfaces)
Expand All @@ -63,7 +64,7 @@ export class RalphTypeHierarchyProvider extends Filter implements TypeHierarchyP
* signaled by returning `undefined` or `null`.
*/
provideTypeHierarchySubtypes(item: TypeHierarchyItem, token: CancellationToken): ProviderResult<TypeHierarchyItem[]> {
const instance = cache.get(item.name)
const instance = cache.get(item.uri, item.name)
const parts = []
if (instance instanceof Contract) parts.push(...Array.from(instance.subclass.values()).map((value) => value.typeHierarchyItem()))
if (instance instanceof Interface) parts.push(...Array.from(instance.implementer.values()).map((value) => value.typeHierarchyItem()))
Expand Down
6 changes: 3 additions & 3 deletions src/visitors/ralphVisitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export class RalphVisitor extends AbstractParseTreeVisitor<Result> implements Ra
base.setRuleContext(ctx)
base.uri = this.uri
base._sourceIntervalDetail = ctx.sourceInterval.differenceNotProperlyContained(ctx.typeStructBody().sourceInterval)
base.setParent(cache)
base.setParent(cache.root(this.uri))
base.setRange(ctx.start, ctx.stop)
this.visitParams(ctx.paramList?.(), base)
this.visitBody(ctx.typeStructBody?.(), base)
Expand All @@ -107,7 +107,7 @@ export class RalphVisitor extends AbstractParseTreeVisitor<Result> implements Ra
const block = new Context(contract)
const identifier = ctx.IDENTIFIER()
contract.append(block.typeNode(identifier))
const parent = cache.get(identifier.symbol.text!)
const parent = cache.get(this.uri, identifier.symbol.text!)
if (parent instanceof Contract) {
contract.parentClass.set(parent.name!, parent)
parent.subclass.set(contract.name!, contract)
Expand All @@ -126,7 +126,7 @@ export class RalphVisitor extends AbstractParseTreeVisitor<Result> implements Ra
const identifier = ctx.IDENTIFIER()
const block = new Context(contract)
contract.append(block.typeNode(identifier))
const parent = cache.get(identifier.symbol.text!)
const parent = cache.get(this.uri, identifier.symbol.text!)
if (parent instanceof Interface) {
contract.interfaces.set(parent.name!, parent)
parent.implementer.set(contract.name!, contract)
Expand Down

0 comments on commit dc26bb2

Please sign in to comment.