static private bool FindAliasInSameQmlFile(EQmlFile eQmlFile, string referenceName, ref string typeName) { typeName = ""; try { //Console.WriteLine($"{eQmlFile.name} procurando o alias {referenceName}. "); //let's check if it's something like txtField.maximumLength, where txtField is a Element defined in this file var regex = new Regex("(\\w+)\\.(\\w+)", RegexOptions.Singleline); Match match = regex.Match(referenceName); string subReference = ""; if (match.Success) { referenceName = match.Groups[1].Value; //ex: txtField subReference = match.Groups[2].Value; //ex: maximumLength } foreach (EQMLElement eqmlElement in eQmlFile.elementsList) { if (eqmlElement.id == referenceName) { Console.WriteLine(""); typeName = eqmlElement.typeName; typeName = QmlBasicComponents.FindPropertyType(typeName, subReference); if (typeName != null) { return(true); } } } } catch (Exception e) { Logger.LogError(e); } return(false); }
static private void GetAllJsFunctionsFromFile(EQmlFile eqmlFile) { var regex = new Regex("function\\s+(\\w+)\\s*\\((.*)\\)", RegexOptions.Multiline); MatchCollection matches = regex.Matches(eqmlFile.content); foreach (Match match in matches) { string functionBaseName = match.Groups[1].Value; string functionArguments = match.Groups[2].Value; string[] args = functionArguments.Split(","); string completeSignature = functionBaseName + "("; for (int i = 0; i < args.Length; i++) { string argName = args.ElementAt(i); if (string.IsNullOrEmpty(argName)) { continue; } if (i == (args.Length - 1)) { completeSignature += argName + ": any"; } else { completeSignature += argName + ": any, "; } } completeSignature += ")"; eqmlFile.functionList.Add(new ETypescriptFunction { signature = completeSignature, returnType = "any" }); } }
static public bool AnalyseFiles(string frontendPath) { try { Globals.eQMLFormFiles.Clear(); IEnumerable <string> files = Directory.EnumerateFiles(frontendPath, "*.qml", SearchOption.AllDirectories); Logger.LogInfoIfDebugLevel(DebugLevels.Basic | DebugLevels.Files | DebugLevels.Functions | DebugLevels.All, "Reading qml files from frontend: " + frontendPath); foreach (string qmlFile in files) { if (!File.Exists(qmlFile)) { continue; } FileInfo fileInfo = new FileInfo(qmlFile); Logger.LogInfoIfDebugLevel(DebugLevels.Files | DebugLevels.Functions | DebugLevels.All, "\t" + fileInfo.Name); EQmlFile eQMLFormFile = new EQmlFile { completeFilePath = qmlFile, name = fileInfo.Name.Replace(".qml", String.Empty).Replace(".ui.qml", String.Empty), content = File.ReadAllText(qmlFile) }; if (!StringHelper.ContainsAnyInString(eQMLFormFile.content, "TQuickItem", "[RestInPeaceQmlComponent]")) { continue; //nao precisa mais colocar RestInPeaceQmlUI } if (eQMLFormFile.content.Contains("TQuickItem")) { eQMLFormFile.qmlFileType = QmlFileType.AppForm; } if (eQMLFormFile.content.Contains("[RestInPeaceQmlComponent]")) { eQMLFormFile.qmlFileType = QmlFileType.AppComponent; } //if (eQMLFormFile.qmlFileType == QmlFileType.AppComponent) { if (!GetAllQmlSignalsFromFile(eQMLFormFile)) { return(false); } //} GetAllQmlElementsFromFile(ref eQMLFormFile); Globals.qmlElements.AddRange(eQMLFormFile.elementsList); if (!AnalyseFile(eQMLFormFile)) { return(false); } Globals.eQMLFormFiles.Add(eQMLFormFile); //if (!SetTypescriptPropertyTypes()) return false; } return(true); } catch (Exception e) { Logger.LogError(e); } return(false); }
static private bool WriteTypescriptComponentFile(EQmlFile eQmlFormFile) { try { string tsComponentFileName = eQmlFormFile.name + ".d.ts"; string completeFilePath = Globals.frontendRestInPeaceFolder + "/" + tsComponentFileName; Logger.LogInfoIfDebugLevel(DebugLevels.Files | DebugLevels.Functions | DebugLevels.All, "\t" + tsComponentFileName); StringBuilder fileContent = new StringBuilder(); fileContent.Append("\n"); DTSWriter.WriteTypescriptImports(eQmlFormFile, ref fileContent); fileContent.Append("\n"); if (!string.IsNullOrEmpty(eQmlFormFile.extendsElementName)) { fileContent.Append("export declare class " + eQmlFormFile.name + " extends " + eQmlFormFile.extendsElementName + " {\n"); } else { fileContent.Append("export declare class " + eQmlFormFile.name + " {\n"); } foreach (EQMLFormProperty eQmlFormProperty in eQmlFormFile.propertyList) { fileContent.Append("\t" + eQmlFormProperty.name + ": " + eQmlFormProperty.type + ";\n"); } fileContent.Append("\n"); foreach (EQmlSignal eQmlSignal in eQmlFormFile.signalList) { fileContent.Append("\t" + eQmlSignal.name + ": MySimpleEvent<" + eQmlSignal.argTypeName + ">;\n"); } foreach (ETypescriptFunction eTypescriptFunction in eQmlFormFile.functionList) { fileContent.Append("\t" + eTypescriptFunction.signature + ": " + eTypescriptFunction.returnType + ";\n"); } fileContent.Append("}"); //Logger.LogInfo(newFileContent.ToString()); string oldContent = ""; if (File.Exists(completeFilePath)) { oldContent = File.ReadAllText(completeFilePath); } if (fileContent.ToString() != oldContent) { File.WriteAllText(completeFilePath, fileContent.ToString()); } return(true); } catch (Exception e) { Logger.LogError(e); } return(false); }
static private bool WriteTypescriptFormFile(EQmlFile eQmlFormFile, string frontendQmlPagesFolder) { try { string typescriptFormFileName = eQmlFormFile.name + ".ts"; string completeFilePath = frontendQmlPagesFolder + "/" + typescriptFormFileName; if (File.Exists(completeFilePath)) { return(true); } Logger.LogInfoIfDebugLevel(DebugLevels.Files | DebugLevels.Functions | DebugLevels.All, "\t" + typescriptFormFileName); StringBuilder fileContent = new StringBuilder(); fileContent.Append("//region imports\n"); fileContent.Append("import {" + eQmlFormFile.name + "Form" + "} from '../RestInPeace/" + eQmlFormFile.name + "Form';\n"); //fileContent.Append("import {ECppObjects} from '../RestInPeace/ECppObjects';\n"); fileContent.Append("import {EBase} from '../RestInPeace/EBase';\n"); fileContent.Append("//endregion\n"); fileContent.Append("\n"); fileContent.Append("export class " + eQmlFormFile.name + " {\n"); //fileContent.Append("\n"); // fileContent.Append("\t//region fields\n"); // fileContent.Append("\tform: " + eQmlFormFile.name + "Form;\n"); // fileContent.Append("\teCppObjects: ECppObjects;\n"); // fileContent.Append("\tbase: EBase;\n"); // fileContent.Append("\t//endregion\n"); fileContent.Append("\n"); // fileContent.Append("\tsetup(eCppObjects: ECppObjects, form: " + eQmlFormFile.name + "Form): void{\n"); // fileContent.Append("\t\tthis.form=form;\n"); // fileContent.Append("\t\tthis.eCppObjects=eCppObjects;\n"); // fileContent.Append("\t\tthis.base=eCppObjects.base;\n"); // fileContent.Append("\t}\n"); fileContent.Append("}"); //Logger.LogInfo(newFileContent.ToString()); string oldContent = ""; if (File.Exists(completeFilePath)) { oldContent = File.ReadAllText(completeFilePath); } if (fileContent.ToString() != oldContent) { File.WriteAllText(completeFilePath, fileContent.ToString()); } return(true); } catch (Exception e) { Logger.LogError(e); } return(false); }
static private void GetAllQmlElementsFromFile(ref EQmlFile eQmlFile) { try { var regex = new Regex("(\\w+)\\s*{\\s*\\n\\s*\\t*(id):\\s*(\\w+)", RegexOptions.Multiline); MatchCollection matches = regex.Matches(eQmlFile.content); foreach (Match match in matches) { EQMLElement eqmlElement = new EQMLElement { typeName = match.Groups[1].Value, id = match.Groups[3].Value }; eQmlFile.elementsList.Add(eqmlElement); } } catch (Exception e) { Logger.LogError(e); } }
static public void WriteTypescriptImports(EQmlFile eQmlFormFile, ref StringBuilder fileContent) { try { List <string> importFileTypes = new List <string>(); if (eQmlFormFile.signalList.Count > 0) { fileContent.Append("import {MySimpleEvent} from './MySimpleEvent';\n"); importFileTypes.Add("MySimpleEvent"); } foreach (EImport eImport in eQmlFormFile.typescriptImports) { if (!importFileTypes.Contains(eImport.className)) { string resumedClassName = GetResumedTypeName(eImport.className); if (resumedClassName == "TQuickItem") { continue; } fileContent.Append("import {" + resumedClassName + "} from '" + eImport.path + resumedClassName + "';\n"); importFileTypes.Add(resumedClassName); } } //todo talvez deixar de usar o formato abaixo e usar apenas via typescriptImports acima foreach (EQMLFormProperty eqmlFormProperty in eQmlFormFile.propertyList) { if (Helper.IsBasicTypescriptType(eqmlFormProperty.type)) { continue; } if (!importFileTypes.Contains(eqmlFormProperty.type)) { string resumedClassName = GetResumedTypeName(eqmlFormProperty.type); if (eQmlFormFile.name == resumedClassName) { continue; //we can not import the current file } fileContent.Append("import {" + resumedClassName + "} from './" + resumedClassName + "';\n"); importFileTypes.Add(resumedClassName); } } } catch (Exception e) { Logger.LogError(e); } }
static private void AddQtInputMethod() { EQmlFile textField = new EQmlFile { name = "QInputMethod", qmlFileType = QmlFileType.CppComponent, functionList = new List <ETypescriptFunction>() { new ETypescriptFunction { signature = "hide()", returnType = "void" }, new ETypescriptFunction { signature = "commit()", returnType = "void" }, } }; cppComponents.Add(textField); }
static private void AddEFirebase() { EQmlFile eQmlFile = new EQmlFile { name = "EFirebase", qmlFileType = QmlFileType.CppComponent, propertyList = new List <EQMLFormProperty>() { new EQMLFormProperty { name = "token", type = "string" }, }, signalList = new List <EQmlSignal>() { new EQmlSignal { name = "messageReceived", argTypeName = "any" }, new EQmlSignal { name = "messageReceivedWithObject", argTypeName = "any" }, new EQmlSignal { name = "tokenChanged", argTypeName = "string" }, }, functionList = new List <ETypescriptFunction>() { new ETypescriptFunction { signature = "containsKey(key: string)", returnType = "boolean" }, new ETypescriptFunction { signature = "getValue(key: string)", returnType = "string" }, new ETypescriptFunction { signature = "clearHash()", returnType = "void" }, new ETypescriptFunction { signature = "setQmlObject(qmlObject:any)", returnType = "void" }, } }; cppComponents.Add(eQmlFile); }
static private bool GetAllQmlSignalsFromFile(EQmlFile eQmlFile) { var regex = new Regex("signal\\s+(\\w+)\\s*\\((.*)\\)", RegexOptions.Multiline); MatchCollection matches = regex.Matches(eQmlFile.content); foreach (Match match in matches) { string signalName = match.Groups[1].Value; string signalArguments = match.Groups[2].Value; if (signalArguments.Contains(",")) { Logger.LogError($"Signal can not have multiple arg types yet. File {eQmlFile.name}"); return(false); } Logger.LogInfoIfDebugLevel(DebugLevels.Functions | DebugLevels.All, "\t\tsignal " + signalName); //string[] args= signalArguments.Split(","); string signalArgName = signalArguments.Trim(); if (string.IsNullOrEmpty(signalArgName)) { signalArgName = "void"; } else { var argRegex = new Regex("(\\w+)\\s+(\\w+)", RegexOptions.Singleline); var argMatch = argRegex.Match(signalArguments.Trim()); if (!argMatch.Success) { Logger.LogError($"Invalid signal argument in signal {signalName}. File {eQmlFile.name}"); return(false); } signalArgName = Helper.ConvertQmlBasicTypeToTypescriptBasicType(argMatch.Groups[1].Value); } eQmlFile.signalList.Add(new EQmlSignal { name = signalName, argTypeName = signalArgName }); } return(true); }
static public bool WriteTypescriptDefinitionToFrontEnd(EQmlFile eQmlFile) { try { string tsComponentFileName = eQmlFile.name + ".d.ts"; string completeFilePath = Globals.frontendRestInPeaceFolder + "/" + tsComponentFileName; Logger.LogInfoIfDebugLevel(DebugLevels.Files | DebugLevels.Functions | DebugLevels.All, "\t" + tsComponentFileName); StringBuilder fileContent = new StringBuilder(); fileContent.Append("\n"); WriteTypescriptImports(eQmlFile, ref fileContent); fileContent.Append("\n"); if (!string.IsNullOrEmpty(eQmlFile.extendsElementName)) { fileContent.Append("export declare class " + eQmlFile.name + " extends " + eQmlFile.extendsElementName + " {\n"); } else { fileContent.Append("export declare class " + eQmlFile.name + " {\n"); } if (eQmlFile.propertyList.Any()) { fileContent.Append("\t//region fields\n"); } foreach (EQMLFormProperty eQmlFormProperty in eQmlFile.propertyList) { string st = ""; if (eQmlFormProperty.isStatic) { st = "static "; } if (eQmlFormProperty.isReadOnly) { st = " readonly "; } fileContent.Append("\t" + st + eQmlFormProperty.name + ": " + eQmlFormProperty.type + ";\n"); } if (eQmlFile.propertyList.Any()) { fileContent.Append("\t//endregion\n"); } fileContent.Append("\n"); //let's write the enums if (eQmlFile.enumList.Any()) { fileContent.Append("\t//region enums\n"); } foreach (EEnumFile eEnumFile in eQmlFile.enumList) { foreach (EEnumValue eEnumValue in eEnumFile.valueList) { fileContent.Append($"\tstatic readonly {eEnumValue.name};\n"); } } if (eQmlFile.enumList.Any()) { fileContent.Append("\t//endregion\n"); } fileContent.Append("\n"); foreach (EQmlSignal eQmlSignal in eQmlFile.signalList) { if (eQmlSignal.argTypeName != "void" && (!string.IsNullOrEmpty(eQmlSignal.argTypeName))) { fileContent.Append("\t" + eQmlSignal.name + ": MySimpleEvent<" + eQmlSignal.argTypeName + ">;\n"); } else { fileContent.Append("\t" + eQmlSignal.name + ": MySimpleEvent<void>;\n"); } } foreach (ETypescriptFunction eTypescriptFunction in eQmlFile.functionList) { string st = ""; if (eTypescriptFunction.isStatic) { st = "static "; } fileContent.Append("\t" + st + eTypescriptFunction.signature + ": " + eTypescriptFunction.returnType + ";\n"); } fileContent.Append("}"); //Logger.LogInfo(newFileContent.ToString()); string oldContent = ""; if (File.Exists(completeFilePath)) { oldContent = File.ReadAllText(completeFilePath); } if (fileContent.ToString() != oldContent) { File.WriteAllText(completeFilePath, fileContent.ToString()); } return(true); } catch (Exception e) { Console.WriteLine(e); throw; } }
static private void AddEBase() { EQmlFile textField = new EQmlFile { name = "EBase", qmlFileType = QmlFileType.CppComponent, propertyList = new List <EQMLFormProperty>() { new EQMLFormProperty { name = "screenHeight", type = "number" }, new EQMLFormProperty { name = "screenWidth", type = "number" }, new EQMLFormProperty { name = "qmlBaseURL", type = "string" }, new EQMLFormProperty { name = "baseURL", type = "string" }, new EQMLFormProperty { name = "token", type = "string" }, new EQMLFormProperty { name = "hotReloadEnabled", type = "boolean" }, new EQMLFormProperty { name = "listCount", type = "number" }, new EQMLFormProperty { name = "appVersion", type = "string" }, }, functionList = new List <ETypescriptFunction>() { new ETypescriptFunction { signature = "quit()", returnType = "void" }, new ETypescriptFunction { signature = "getIpAddress()", returnType = "string" }, new ETypescriptFunction { signature = "getOSVersion()", returnType = "string" }, new ETypescriptFunction { signature = "openUrl(url: string)", returnType = "void" }, new ETypescriptFunction { signature = "closeDialogs(obj: any)", returnType = "void" }, new ETypescriptFunction { signature = "createGUID()", returnType = "void" }, new ETypescriptFunction { signature = "isDesktop()", returnType = "boolean" }, new ETypescriptFunction { signature = "tr(txt: string)", returnType = "string" }, new ETypescriptFunction { signature = "setScreenOrientationMask(orientation: any)", returnType = "void" }, new ETypescriptFunction { signature = "setValue(key: any, value: any)", returnType = "void" }, new ETypescriptFunction { signature = "getValue(key: any)", returnType = "any" }, new ETypescriptFunction { signature = "containsKey(key: any)", returnType = "boolean" }, new ETypescriptFunction { signature = "removeKey(key: any)", returnType = "void" }, new ETypescriptFunction { signature = "readFileInBase64(completeFilePath: string)", returnType = "string" }, } }; cppComponents.Add(textField); }
static private void AddQt() { EQmlFile textField = new EQmlFile { name = "Qt", qmlFileType = QmlFileType.CppComponent, typescriptImports = { new EImport { className = "QInputMethod", path = "./" } }, propertyList = { new EQMLFormProperty { name = "inputMethod", type = "QInputMethod", isStatic = true }, }, enumList = { new EEnumFile { enumName = "Qt", valueList = new List <EEnumValue>() { new EEnumValue { name = "PrimaryOrientation", }, new EEnumValue { name = "LandscapeOrientation" }, new EEnumValue { name = "PortraitOrientation" }, } } }, functionList = new List <ETypescriptFunction>() { new ETypescriptFunction { signature = "resolvedUrl(url: string)", returnType = "string", isStatic = true }, new ETypescriptFunction { signature = "quit()", returnType = "void", isStatic = true }, new ETypescriptFunction { signature = "exit(retCode: number)", returnType = "void", isStatic = true }, new ETypescriptFunction { signature = "size(width: number, height: number)", returnType = "any", isStatic = true }, //ver return new ETypescriptFunction { signature = "incluse(url: string, callback: any)", returnType = "void", isStatic = true }, new ETypescriptFunction { signature = "isQtObject(object)", returnType = "boolean", isStatic = true }, new ETypescriptFunction { signature = "qsTr(txt: string)", returnType = "string", isStatic = true }, new ETypescriptFunction { signature = "openUrlExternally(target: string)", returnType = "boolean", isStatic = true }, new ETypescriptFunction { signature = "createComponent(url: string, mode: any, parent: any)", returnType = "any", isStatic = true }, //ver paramers types e returntype new ETypescriptFunction { signature = "createQmlObject(qml: string, parent: object, filePath: string)", returnType = "any", isStatic = true }, //ver return type new ETypescriptFunction { signature = "formatDate(dt: any, format: string)", returnType = "string", isStatic = true }, new ETypescriptFunction { signature = "formatDateTime(dtTime: any, format: string)", returnType = "string", isStatic = true }, new ETypescriptFunction { signature = "formatTime(dtTime: any, format: string)", returnType = "string", isStatic = true }, new ETypescriptFunction { signature = "md5(txt: string)", returnType = "string", isStatic = true }, } }; cppComponents.Add(textField); }
static private bool AnalyseFile(EQmlFile eQMLFormFile) { try { IEnumerable <string> linesList = eQMLFormFile.content.Split('\n'); var regex = new Regex("(\\w+)\\s*{(.*)}", RegexOptions.Multiline | RegexOptions.Singleline, TimeSpan.FromMilliseconds(5000)); Match putMatch = regex.Match(eQMLFormFile.content); if (!putMatch.Success) { Logger.LogError("unable to read qml file " + eQMLFormFile.completeFilePath); return(false); } string rootElement = putMatch.Groups[1].Value; string rootElementContent = putMatch.Groups[2].Value; //let's extend the rootElement eQMLFormFile.extendsElementName = rootElement; eQMLFormFile.typescriptImports.Add(new EImport { className = rootElement, path = "./" }); GetAllJsFunctionsFromFile(eQMLFormFile); //let's get all properties ending with : something regex = new Regex("\\s*(property)\\s*(alias)?\\s*(\\w+)\\s*(\\w+)?\\s*(?=:\\s*(.*))?", RegexOptions.Multiline); MatchCollection matches = regex.Matches(rootElementContent); foreach (Match match in matches) { bool isAlias = match.Groups[2].Value == "alias"; string propertyName = ""; string propertyType = ""; string propertyValue = ""; if (isAlias) //ex: property alias inverted: false { propertyName = match.Groups[3].Value; } else //ex: property bool inverted: false { propertyType = match.Groups[3].Value; propertyName = match.Groups[4].Value; } propertyValue = match.Groups[5].Value;//it might be something like txtField.maximumLength if (!string.IsNullOrEmpty(propertyValue)) { propertyValue = match.Groups[5].Value.Replace("\r\n", "").Replace("\r", "").Replace("\n", ""); if (isAlias) { var found = FindAliasInSameQmlFile(eQMLFormFile, propertyValue, ref propertyType); if (!found) { if (!FindPropertyReferenceTypeName(propertyValue, ref propertyType)) { Logger.LogError($"(QmlTSFormReader)unable to find qml property {propertyValue} as reference type. File:" + eQMLFormFile.completeFilePath + ".Line:" + match.Groups[0].Value); return(false); } } } } EQMLFormProperty eqmlFormProperty = new EQMLFormProperty { name = propertyName, type = Helper.ConvertQmlBasicTypeToTypescriptBasicType(propertyType) }; eQMLFormFile.propertyList.Add(eqmlFormProperty); } return(true); } catch (Exception e) { Logger.LogError(e); } return(false); }