import { Tools } from 'platform-core'; class AutoCompletionManager { parameters: object[]; valueTypes: object[]; public setParameters(parameters) { this.parameters = parameters; } public setValueTypes(valueTypes) { 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 = []; 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; options.push({ label: property.name, type: 'property', apply: '${' + property.name + '}', info: info }); } return options; } public findParmeter(parameterName) { for (const parameter of this.parameters) { if (parameter.name === parameterName) { return parameter; } } return null; } public findValueType(valueTypeString, valueTypeVersion) { for (const valueType of this.valueTypes) { if (valueType.code === valueTypeString && valueType.version === valueTypeVersion) { return valueType; } } return null; } public findValueTypeByProperty(valueTypeString, valueTypeVersion, propertyName) { 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 = []; for (const parameter of this.parameters) { const valueType = this.findValueType(parameter.valueType, parameter.valueTypeVersion); 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 = 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 = []; parameterType.properties.forEach((property) => { options.push({ label: property.name, type: 'property', apply: '${' + property.name + '}', detail: this.findValueTypeInfo(property.valueType) }); }); return options; } } public autoCompletionParameters(to, matchedText): any { return { from: to, options: this.getParameterOptions(), validFor: /(.*)?/, }; } public autoCompletionProperties(to, matchedText): any { const matchedTextReverse = Tools.reverseString(matchedText); const regReverse = /(\.\}(.+?)\{\$)+/g; //匹配 '.}xxx{$' 模式 const matcheds = matchedTextReverse.match(regReverse); if (Tools.isUndefinedOrNull(matcheds) || matcheds.length <= 0) { return null; } const matched = Tools.reverseString(matcheds[0]); const parameterName = matched.replace(/\$\{(.+?)\}/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 autoCompletion(context): 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; } } } export { AutoCompletionManager };