import { axios, Tools } from 'platform-core'; class AutoCompletionManager { parameters: any[]; valueTypes: any[]; constructor() { this.parameters = []; this.valueTypes = []; } public setParameters(parameters: any) { this.parameters = parameters; } public setValueTypes(valueTypes: any) { this.valueTypes = valueTypes; } public getOptions(path: string): any { if (!path) { return this.getParameterOptions(); } if (path.endsWith('.')) { path = path.substring(0, path.length - 1); } const names = path.split('.'); if (!names) { return this.getParameterOptions(); } //参数 const parameter = this.findParmeter(names[0]); if (!parameter) { return null; } const valueTypeString = parameter.valueType; const valueTypeVersion = parameter.valueTypeVersion; let valueType = this.findValueType(valueTypeString, valueTypeVersion); if (!valueType || !valueType.properties || valueType.properties.length <= 0) { return null; } let index = 1; while (index < names.length) { valueType = this.findValueTypeByProperty(valueType.code, valueType.version, names[index++]); } const options: any[] = []; for (const property of valueType.properties) { const propertyValueType = this.findValueType(property.valueType, property.valueTypeVersion); if (!propertyValueType) { continue; } const info = propertyValueType.version ? propertyValueType.name + '(V' + propertyValueType.version + ')' : propertyValueType.name; if (property.valueType.startsWith('java.util.List<')) { options.push({ label: property.name, type: 'property', apply: '${' + property.name + '}[0]', info: info }); } else { options.push({ label: property.name, type: 'property', apply: '${' + property.name + '}', info: info }); } } return options; } public findParmeter(parameterName: string) { for (const parameter of this.parameters) { if (parameter.name === parameterName) { return parameter; } } return null; } public findValueType(valueTypeString: string, valueTypeVersion: number): any { if (valueTypeString.startsWith('java.util.List<')) { valueTypeString = valueTypeString.substring(15, valueTypeString.length - 1); } for (const valueType of this.valueTypes) { if (valueType.code === valueTypeString && valueType.version === valueTypeVersion) { return valueType; } } return null; } public findValueTypeByProperty(valueTypeString: string, valueTypeVersion: number, propertyName: string) { const valueType = this.findValueType(valueTypeString, valueTypeVersion); if (!valueType) { return null; } for (const property of valueType.properties) { if (property.name === propertyName) { return this.findValueType(property.valueType, property.valueTypeVersion); } } } public getParameterOptions(): any { const options: any[] = []; for (const parameter of this.parameters) { const valueType = this.findValueType(parameter.valueType, parameter.valueTypeVersion); if (valueType) { const info = valueType.version ? valueType.name + '(V' + valueType.version + ')' : valueType.name; options.push({ label: parameter.name, type: 'variable', apply: '${' + parameter.name + '}', info: info }); } } return options; } public getPropertyOptions(parameterName: string): any { let parameterType: any = undefined; for (const parameter of this.parameters) { if (parameter.name === parameterName) { parameterType = parameter.valueType; } } if (!parameterType) { return null; } for (const type of this.valueTypes) { if (type.code === parameterType) { parameterType = type; } } if (!parameterType) { return null; } if (parameterType.properties && parameterType.properties.length > 0) { const options: any = []; parameterType.properties.forEach((property) => { options.push({ label: property.name, type: 'property', apply: '${' + property.name + '}', detail: property.valueType }); }); return options; } } public autoCompletionParameters(to: any, matchedText?: any): any { return { from: to, options: this.getParameterOptions(), validFor: /(.*)?/, }; } public autoCompletionProperties(to: any, matchedText?: any): any { const matchedTextReverse = Tools.reverseString(matchedText); console.log(matchedTextReverse); const regReverse = /(\.(\]\S*(.+?)\S*\[)?\}(.+?)\{\$)+/g; //匹配 '.]xxx[}yyy{$' 模式 //const regReverse = /(\.\}(.+?)\{\$)+/g; //匹配 '.}]xxx[yyy{$' 模式 const matcheds: any = matchedTextReverse.match(regReverse); if (Tools.isUndefinedOrNull(matcheds) || matcheds.length <= 0) { return null; } const matched = Tools.reverseString(matcheds[0]); const parameterName = matched.replace(/\$\{(.+?)\}(\[\S*(.+?)\S*\])?/g, '$1'); if (Tools.isUndefinedOrNull(parameterName)) { return null; } const options = this.getOptions(parameterName); if (Tools.isUndefinedOrNull(options)) { return null; } return { from: to, options: options, validFor: /^(.*)?$/, }; } public doAutoCompletion(context: any): any { const beforeMatched = context.matchBefore(/(.+?)/g); if (Tools.isUndefinedOrNull(beforeMatched)) { return null; } const beforeText = beforeMatched.text || ''; if (beforeText.endsWith('.')) { //匹配属性 return this.autoCompletionProperties(beforeMatched.to, beforeText); } else if (beforeText.endsWith(' ')) { //匹配参数 return this.autoCompletionParameters(beforeMatched.to); } else { return null; } } public load(url: string) { axios.get(url).then((response) => { this.setParameters(response.data.parameters); this.setValueTypes(response.data.valueTypes); }); } public autoCompletion(): any { const THIS = this; return function (context: any) { return THIS.doAutoCompletion(context); }; } } export { AutoCompletionManager };