add new parser

pull/2908/head
filip mertens 2 years ago
parent 52386ff94d
commit 6380739517
  1. 7
      apps/remix-ide/src/app/plugins/parser/code-parser.tsx
  2. 44
      apps/remix-ide/src/app/plugins/parser/services/code-parser-antlr-service.ts
  3. 42251
      apps/remix-ide/src/assets/js/parser/index.iife.js
  4. 7
      apps/remix-ide/src/assets/js/parser/index.iife.js.map
  5. 2
      apps/remix-ide/src/index.html
  6. 12
      libs/remix-ui/editor/src/lib/providers/completionProvider.ts

@ -90,7 +90,10 @@ export class CodeParser extends Plugin {
async handleChangeEvents() {
const completionSettings = await this.call('config', 'getAppParameter', 'auto-completion')
if (completionSettings) {
await this.antlrService.getCurrentFileAST()
// current timestamp
console.log('get ast', Date.now())
//this.antlrService.getCurrentFileAST()
console.log('done', Date.now())
}
const showGasSettings = await this.call('config', 'getAppParameter', 'show-gas')
const showErrorSettings = await this.call('config', 'getAppParameter', 'display-errors')
@ -551,7 +554,7 @@ export class CodeParser extends Plugin {
async getNodeLink(node: genericASTNode) {
const lineColumn = await this.getLineColumnOfNode(node)
const position = await this.positionOfDefinition(node)
if (this.compilerAbstract && this.compilerAbstract.source) {
if (this.compilerAbstract && this.compilerAbstract.source && position) {
const fileName = this.compilerAbstract.getSourceName(position.file)
return lineColumn ? `${fileName} ${lineColumn.start.line}:${lineColumn.start.column}` : null
}

@ -33,7 +33,7 @@ export default class CodeParserAntlrService {
if (!this.plugin.currentFile) return
const fileContent = text || await this.plugin.call('fileManager', 'readFile', this.plugin.currentFile)
try {
const ast = await this.parseSolidity(fileContent)
const ast = (SolidityParser as any).parse(fileContent, { loc: true, range: true, tolerant: true })
this.plugin.antlrParserResult = ast
} catch (e) {
// do nothing
@ -127,6 +127,22 @@ export default class CodeParserAntlrService {
}
return lastNode
}
/*
* get the code blocks of the current file
*/
async getCurrentFileBlocks(text: string | null = null) {
this.plugin.currentFile = await this.plugin.call('fileManager', 'file')
if (this.plugin.currentFile && this.plugin.currentFile.endsWith('.sol')) {
if (!this.plugin.currentFile) return
const fileContent = text || await this.plugin.call('fileManager', 'readFile', this.plugin.currentFile)
try {
const blocks = (SolidityParser as any).parseBlock(fileContent, { loc: true, range: true, tolerant: true })
return blocks
} catch (e) {
// do nothing
}
}
}
/**
* Returns the block surrounding the given position
@ -136,23 +152,21 @@ export default class CodeParserAntlrService {
* @return {any}
* */
async getANTLRBlockAtPosition(position: any, text: string = null) {
await this.getCurrentFileAST(text)
const allowedTypes = ['SourceUnit', 'ContractDefinition', 'FunctionDefinition']
const walkAst = (node: any) => {
if (node.loc.start.line <= position.lineNumber && node.loc.end.line >= position.lineNumber) {
const children = node.children || node.subNodes
if (children && allowedTypes.indexOf(node.type) !== -1) {
for (const child of children) {
const result = walkAst(child)
if (result) return result
}
const blocks = await this.getCurrentFileBlocks(text)
const walkAst = (blocks) => {
let nodeFound = null
for(const object of blocks){
if(object.start <= position && object.end >= position){
nodeFound = object
break
}
return node
}
return null
return nodeFound
}
if (!this.plugin.antlrParserResult) return
return walkAst(this.plugin.antlrParserResult)
if (!blocks) return
const block = walkAst(blocks)
console.log(block)
return block
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -41,7 +41,7 @@
<script type="text/javascript" src="assets/js/loader.js"></script>
<script src="https://kit.fontawesome.com/41dd021e94.js" crossorigin="anonymous"></script>
<script type="text/javascript" src="assets/js/intro.min.js"></script>
<script type="text/javascript" src="assets/js/parser/antlr.js"></script>
<script type="text/javascript" src="assets/js/parser/index.iife.js"></script>
</body>
</html>

@ -228,12 +228,10 @@ export class RemixCompletionProvider implements languages.CompletionItemProvider
}
}
private getBlockNodesAtPosition = async (position: Position) => {
private getBlockNodesAtPosition = async (position: Position, ANTLRBlock) => {
let nodes: any[] = []
const cursorPosition = this.props.editorAPI.getCursorPosition()
const nodesAtPosition = await this.props.plugin.call('codeParser', 'nodesAtPosition', cursorPosition)
// try to get the block from ANTLR of which the position is in
const ANTLRBlock = await this.props.plugin.call('codeParser', 'getANTLRBlockAtPosition', position, null)
// if the block has a name and a type we can maybe find it in the contract nodes
const fileNodes = await this.props.plugin.call('codeParser', 'getCurrentFileNodes')
@ -275,7 +273,7 @@ export class RemixCompletionProvider implements languages.CompletionItemProvider
nodes = nodes.filter(node => {
if (node.src) {
const position = sourceMappingDecoder.decode(node.src)
if (position.start >= ANTLRBlock.range[0] && (position.start + position.length) <= ANTLRBlock.range[1]) {
if (position.start >= ANTLRBlock.start && (position.start + position.length) <= ANTLRBlock.end) {
return true
}
}
@ -291,10 +289,10 @@ export class RemixCompletionProvider implements languages.CompletionItemProvider
const cursorPosition = this.props.editorAPI.getCursorPosition()
let nodesAtPosition = await this.props.plugin.call('codeParser', 'nodesAtPosition', cursorPosition)
// if no nodes exits at position, try to get the block of which the position is in
const block = await this.props.plugin.call('codeParser', 'getANTLRBlockAtPosition', position, null)
const block = await this.props.plugin.call('codeParser', 'getANTLRBlockAtPosition', cursorPosition, null)
if (!nodesAtPosition.length) {
if (block) {
nodesAtPosition = await this.props.plugin.call('codeParser', 'nodesAtPosition', block.range[0])
nodesAtPosition = await this.props.plugin.call('codeParser', 'nodesAtPosition', block.start)
}
}
// find the contract and get the nodes of the contract and the base contracts and imports
@ -309,7 +307,7 @@ export class RemixCompletionProvider implements languages.CompletionItemProvider
nodes = [...Object.values(contractNodes.baseNodesWithBaseContractScope), ...nodes]
nodes = [...Object.values(fileNodes.imports), ...nodes]
// at the nodes at the block itself
nodes = [...nodes, ...await this.getBlockNodesAtPosition(position)]
nodes = [...nodes, ...await this.getBlockNodesAtPosition(position, block)]
// filter private nodes, only allow them when contract ID is the same as the current contract
nodes = nodes.filter(node => {
if (node.visibility) {

Loading…
Cancel
Save