Browse Source

v28

* Add completion support detail return values
* Fix support of dapp files with random values set.
* Demo of dappsys cache
Juan Blanco 3 years ago
parent
commit
3a14d43ff7

+ 1 - 1
package.json

@@ -7,7 +7,7 @@
     "blockchain",
     "compiler"
   ],
-  "version": "0.0.27",
+  "version": "0.0.28",
   "publisher": "JuanBlanco",
   "engines": {
     "vscode": "^1.8.0"

BIN
screenshots/autocompletedemoDappSys.gif


BIN
screenshots/autocompletedemoGlobal.gif


+ 82 - 39
src/completionService.ts

@@ -3,6 +3,15 @@ import * as projectService from './projectService';
 import {ContractCollection} from './model/contractsCollection';
 import { CompletionItem, CompletionItemKind, Command } from 'vscode-languageserver';
 
+// TODO implement caching, dirty on document change, reload, etc.
+// store
+// export class CompletionFile {
+//    public path: string;
+//    public imports: string[]
+//    public inspectionResult : any
+// }
+
+
 export class CompletionService {
 
     public rootPath: string;
@@ -35,31 +44,58 @@ export class CompletionService {
         return literalType + suffixType;
     }
 
-    public createFunctionEventCompletionItem(contractElement: any, type: string, contractName: string): CompletionItem {
-        let completionItem =  CompletionItem.create(contractElement.name);
-        completionItem.kind = CompletionItemKind.Function;
-        let paramsInfo = '';
+    public createFunctionParamsSnippet(params: any): string {
         let paramsSnippet = '';
         let counter = 0;
-        if (typeof contractElement.params !== 'undefined' && contractElement.params !== null) {
-            contractElement.params.forEach( parameterElement => {
-                counter = counter + 1;
-                let currentParamSnippet = '${' + counter + ':' + parameterElement.id + '}';
-                const typeString = this.getTypeString(parameterElement.literal);
+        if (typeof params !== 'undefined' && params !== null) {
+            params.forEach( parameterElement => {
+               const typeString = this.getTypeString(parameterElement.literal);
+               counter = counter + 1;
+               let currentParamSnippet = '${' + counter + ':' + parameterElement.id + '}';
+                if (paramsSnippet === '') {
+                    paramsSnippet = currentParamSnippet;
+                }else {
+                    paramsSnippet = paramsSnippet + ', ' + currentParamSnippet;
+                }
+            });
+        }
+        return paramsSnippet;
+    }
 
-                let currentParamInfo = typeString + ' ' + parameterElement.id;
+    public createParamsInfo(params: any): string {
+        let paramsInfo = '';
+        if (typeof params !== 'undefined' && params !== null) {
+            params.forEach( parameterElement => {
+               const typeString = this.getTypeString(parameterElement.literal);
+                let currentParamInfo = '';
+                if (typeof parameterElement.id !== 'undefined' && parameterElement.id !== null ) { // no name on return parameters
+                    currentParamInfo = typeString + ' ' + parameterElement.id;
+                } else {
+                    currentParamInfo = typeString;
+                }
                 if (paramsInfo === '') {
                     paramsInfo = currentParamInfo;
-                    paramsSnippet =  currentParamSnippet;
                 }else {
                     paramsInfo = paramsInfo + ', ' + currentParamInfo;
-                    paramsSnippet = paramsSnippet + ', ' + currentParamSnippet;
                 }
             });
         }
+        return paramsInfo;
+    }
+
+    public createFunctionEventCompletionItem(contractElement: any, type: string, contractName: string): CompletionItem {
+
+        let completionItem =  CompletionItem.create(contractElement.name);
+        completionItem.kind = CompletionItemKind.Function;
+        let paramsInfo = this.createParamsInfo(contractElement.params);
+        let paramsSnippet = this.createFunctionParamsSnippet(contractElement.params);
+        let returnParamsInfo = this.createParamsInfo(contractElement.returnParams);
+        if (returnParamsInfo !== '') {
+            returnParamsInfo = ' returns (' + returnParamsInfo + ')';
+        }
         completionItem.insertTextFormat = 2;
         completionItem.insertText = contractElement.name + '(' + paramsSnippet + ');';
-        const info = '(' + type + ' in ' + contractName + ') ' + contractElement.name + '(' + paramsInfo + ')';
+        const info = '(' + type + ' in ' + contractName + ') ' + contractElement.name + '(' + paramsInfo + ')' + returnParamsInfo;
         completionItem.documentation = info;
         completionItem.detail = info;
         return completionItem;
@@ -67,36 +103,43 @@ export class CompletionService {
 
     public getDocumentCompletionItems(documentText: string): CompletionItem[] {
         let completionItems = [];
-        let result = solparse.parse(documentText);
-        // console.log(JSON.stringify(result));
-        // TODO struct, modifier
-        result.body.forEach(element => {
-            if (element.type === 'ContractStatement' ||  element.type === 'LibraryStatement') {
-                let contractName = element.name;
-                if (typeof element.body !== 'undefined' && element.body !== null) {
-                    element.body.forEach(contractElement => {
-                        if (contractElement.type === 'FunctionDeclaration') {
-                            // ignore the constructor TODO add to contract initialiasation
-                            if (contractElement.name !== contractName) {
-                                completionItems.push(this.createFunctionEventCompletionItem(contractElement, 'function', contractName ));
+        try {
+            let result = solparse.parse(documentText);
+            // console.log(JSON.stringify(result));
+            // TODO struct, modifier
+            result.body.forEach(element => {
+                if (element.type === 'ContractStatement' ||  element.type === 'LibraryStatement') {
+                    let contractName = element.name;
+                    if (typeof element.body !== 'undefined' && element.body !== null) {
+                        element.body.forEach(contractElement => {
+                            if (contractElement.type === 'FunctionDeclaration') {
+                                // ignore the constructor TODO add to contract initialiasation
+                                if (contractElement.name !== contractName) {
+                                    completionItems.push(
+                                            this.createFunctionEventCompletionItem(contractElement, 'function', contractName ));
+                                }
                             }
-                        }
 
-                        if (contractElement.type === 'EventDeclaration') {
-                            completionItems.push(this.createFunctionEventCompletionItem(contractElement, 'event', contractName ));
-                        }
+                            if (contractElement.type === 'EventDeclaration') {
+                                completionItems.push(this.createFunctionEventCompletionItem(contractElement, 'event', contractName ));
+                            }
 
-                        if (contractElement.type === 'StateVariableDeclaration') {
-                            let completionItem =  CompletionItem.create(contractElement.name);
-                            completionItem.kind = CompletionItemKind.Field;
-                            const typeString = this.getTypeString(contractElement.literal);
-                            completionItem.detail = '(state variable in ' + contractName + ') ' + typeString + ' ' + contractElement.name;
-                            completionItems.push(completionItem);
-                        }
-                    });
+                            if (contractElement.type === 'StateVariableDeclaration') {
+                                let completionItem =  CompletionItem.create(contractElement.name);
+                                completionItem.kind = CompletionItemKind.Field;
+                                const typeString = this.getTypeString(contractElement.literal);
+                                completionItem.detail = '(state variable in ' + contractName + ') '
+                                                                    + typeString + ' ' + contractElement.name;
+                                completionItems.push(completionItem);
+                            }
+                        });
+                    }
                 }
-            }
-        });
+            });
+        } catch (error) {
+          // gracefule catch
+          // console.log(error.message);
+        }
         // console.log('file completion items' + completionItems.length);
         return completionItems;
     }

+ 17 - 3
src/projectService.ts

@@ -19,12 +19,26 @@ function createPackage(rootPath: string) {
         projectPackage.absoluletPath = rootPath;
         if (packageConfig) {
             if (packageConfig.layout !== undefined) {
+                if (projectPackage.build_dir !== undefined) {
                 projectPackage.build_dir = packageConfig.layout.build_dir;
+                }
+                if (projectPackage.sol_sources !== undefined) {
                 projectPackage.sol_sources = packageConfig.layout.sol_sources;
+                }
+            }
+            if (projectPackage.name !== undefined) {
+                projectPackage.name = packageConfig.name;
+            }else {
+                projectPackage.name = path.basename(rootPath);
+            }
+
+            if (projectPackage.version !== undefined) {
+                projectPackage.version = packageConfig.name;
+            }
+
+            if (projectPackage.dependencies !== undefined) {
+                projectPackage.dependencies = packageConfig.dependencies;
             }
-            projectPackage.name = packageConfig.name;
-            projectPackage.version = packageConfig.version;
-            projectPackage.dependencies = packageConfig.dependencies;
         }
         return projectPackage;
     }

+ 4 - 1
src/server.ts

@@ -13,7 +13,7 @@ import {
     Files, DiagnosticSeverity, Diagnostic,
     TextDocumentChangeEvent, TextDocumentPositionParams,
     CompletionItem, CompletionItemKind,
-    Range, Position, Location,
+    Range, Position, Location, SignatureHelp,
 } from 'vscode-languageserver';
 
 interface Settings {
@@ -82,6 +82,9 @@ function validate(document) {
     }
 }
 
+connection.onSignatureHelp((textDocumentPosition: TextDocumentPositionParams): SignatureHelp => {
+    return null;
+});
 
 connection.onCompletion((textDocumentPosition: TextDocumentPositionParams): CompletionItem[] => {
     // The pass parameter contains the position of the text document in