/** * Add parsed type definition to proper collection by definition source code place. */ protected void addTypeToResult( ref ParsedTypes result, TypeDefinitionPlace typeDefinitionPlace, bool functionParamSpreadSyntax, string typeItem ) { List <string> typesList = new List <string>(); if ((typeDefinitionPlace & TypeDefinitionPlace.ANY_PROPERTY) != 0) { typesList = result.CfgOrProp; } else if ((typeDefinitionPlace & TypeDefinitionPlace.ANY_PARAM) != 0) { if (functionParamSpreadSyntax) { typesList = result.MethodOrEventSpreadParam; } else { typesList = result.MethodOrEventParam; } } else if ((typeDefinitionPlace & TypeDefinitionPlace.ANY_RETURN) != 0) { typesList = result.MethodOrEventReturn; } typesList.Add(typeItem); }
protected void readAndAddProp(ref ExtClass extClass, ExtObjectMember member, ParsedTypes types, bool ownedByCurrent, bool required) { string name = this.sanitizeName(member.Name); string[] docs = this.readJsDocs(member.Doc, JsDocsType.PROPERTY, extClass.Name.FullName, name); //if (extClass.Name.FullName == "Ext.Base") // Debugger.Break(); Property newPropItem = new Property( name, types.CfgOrProp, docs, member.Owner, ownedByCurrent ); //newPropItem.DefaultValue = String.IsNullOrEmpty(member.Default) ? "" : member.Default; newPropItem.DefaultValue = member.Default == "" ? "''" : member.Default; newPropItem.Deprecated = this.readJsDocsDeprecated( member.Deprecated, extClass.Name.FullName, name ); newPropItem.AccessModJs = this.readItemAccessModifier(member); newPropItem.AccessModTs = newPropItem.AccessModJs; newPropItem.IsStatic = (member.Static.HasValue && member.Static.Value == true); newPropItem.IsReadOnly = (member.Readonly.HasValue && member.Readonly.Value == true); if (!newPropItem.IsReadOnly) { string nameUpper = name.ToUpper(); if (name == nameUpper && types.CfgOrProp.Count == 1) { newPropItem.IsReadOnly = true; // it's looking like some contant: } } newPropItem.Renderable = extClass.Extends == null || name == "self"; // force render if it is class without any parent extClass.AddMemberProperty(newPropItem); }
protected void readAndAddCfgOrProp(ref ExtClass extClass, ExtObjectMember member, string currentClassName, bool cfgsCompleting) { string name = this.sanitizeName(member.Name); ParsedTypes types = this.typesParser.Parse( cfgsCompleting ? TypeDefinitionPlace.CONFIGURATION : TypeDefinitionPlace.PROPERTY, currentClassName, member.Name, member.Type ); bool ownedByCurrent = member.Owner.Length == currentClassName.Length && member.Owner == currentClassName; string rawDocs = String.IsNullOrEmpty(member.Doc) ? "" : member.Doc; bool required = member.Required.HasValue ? member.Required == true : rawDocs.Contains("(required)"); if (cfgsCompleting) { this.readAndAddCfg( ref extClass, member, types, ownedByCurrent, required ); } else { this.readAndAddProp( ref extClass, member, types, ownedByCurrent, required ); } }
protected SpecialParamTypes matchSpecStructParamInParamTypes(ref ParsedTypes paramTypes) { SpecialParamTypes result = new SpecialParamTypes() { Matches = SpecialParamMatch.NONE, MethodOrEventParamTypes = new List <string>(), MethodOrEventSpreadParamTypes = new List <string>(), MethodOrEventAllParamTypes = new List <string>(), }; SpecialParamTypes collectionResult = new SpecialParamTypes() { Matches = SpecialParamMatch.NONE, MethodOrEventAllParamTypes = new List <string>(), }; if (paramTypes.MethodOrEventParam.Count > 0) { collectionResult = this.matchSpecStructParamInParamTypesCollection( paramTypes.MethodOrEventParam, true ); result.Matches |= collectionResult.Matches; if (collectionResult.MethodOrEventAllParamTypes.Count > 0) { result.MethodOrEventParamTypes = new List <string>(collectionResult.MethodOrEventAllParamTypes); result.MethodOrEventAllParamTypes = new List <string>(collectionResult.MethodOrEventAllParamTypes); } } if (paramTypes.MethodOrEventSpreadParam.Count > 0) { collectionResult = this.matchSpecStructParamInParamTypesCollection( paramTypes.MethodOrEventSpreadParam, false ); result.Matches |= collectionResult.Matches; if (collectionResult.MethodOrEventAllParamTypes.Count > 0) { result.MethodOrEventSpreadParamTypes = new List <string>(collectionResult.MethodOrEventAllParamTypes); foreach (string paramType in collectionResult.MethodOrEventAllParamTypes) { if (!result.MethodOrEventAllParamTypes.Contains(paramType)) { result.MethodOrEventAllParamTypes.Add(paramType); } } } } return(result); }
protected void readAndAddCfg(ref ExtClass extClass, ExtObjectMember member, ParsedTypes types, bool ownedByCurrent, bool required) { string name = this.sanitizeName(member.Name); string[] docs = this.readJsDocs(member.Doc, JsDocsType.CONFIGURATION, extClass.Name.FullName, name); Configuration newCfgItem = new Configuration( name, types.CfgOrProp, docs, member.Owner, ownedByCurrent ); newCfgItem.Required = required; //newCfgItem.DefaultValue = String.IsNullOrEmpty(member.Default) ? "" : member.Default; newCfgItem.DefaultValue = member.Default == "" ? "''" : member.Default; newCfgItem.Deprecated = this.readJsDocsDeprecated( member.Deprecated, extClass.Name.FullName, name ); extClass.AddMemberConfiguration(newCfgItem); }
protected internal ParsedTypes Parse( TypeDefinitionPlace typeDefinitionPlace, string definitionFullPath, string memberOrParamName, string rawTypesStr ) { ParsedTypes result = new ParsedTypes() { CfgOrProp = new List <string>(), MethodOrEventParam = new List <string>(), MethodOrEventSpreadParam = new List <string>(), MethodOrEventReturn = new List <string>(), }; // Return "any" type if type definition is empty or null: if (String.IsNullOrEmpty(rawTypesStr)) { this.addTypeToResult( ref result, typeDefinitionPlace, false, "any" ); return(result); } // Check for exception: rawTypesStr = this.checkExceptions(typeDefinitionPlace, definitionFullPath, memberOrParamName, rawTypesStr); // Process very basic replacements to fix syntax errors for proper parsing: rawTypesStr = this.sanitizeRawTypesSyntax(rawTypesStr, typeDefinitionPlace); // Complete boolean flag about if there is method param type definition: bool methodParamDefinition = (typeDefinitionPlace & TypeDefinitionPlace.ANY_PARAM) != 0; // Check if there is method param spread syntax and correct it by ext version if necessary: if (methodParamDefinition && rawTypesStr.Contains("...")) { rawTypesStr = this.correctMethodParamSpreadSyntaxIfNecessary( typeDefinitionPlace, definitionFullPath, memberOrParamName, rawTypesStr ); } // Explode raw types into list of strings: List <string> rawTypesList = this.explodeRawTypes(rawTypesStr); // Complete result types collection(s): this.completeResultList( ref result, rawTypesList, typeDefinitionPlace, methodParamDefinition, definitionFullPath, memberOrParamName ); return(result); }
public IList <ITbsType> AnalyseParseResult(ParseResult parseResult, CompileLog log) { List <ITbsType> promotedTypes = new List <ITbsType>(ParsedTypes.Count() + TbsBuildIn.Types.Count()); promotedTypes.AddRange(TbsBuildIn.Types); IList <ITbsParseType> typesToProcess = parseResult.ParsedTypes.ToList(); while (true) { int noOfProcessedInItteration = 0; for (int i = 0; i < typesToProcess.Count(); i++) { var parsedType = typesToProcess[i]; var tmpLog = new CompileLog(); var promotedType = parsedType.Promote(promotedTypes, tmpLog);//May not log to Output because a fail doesnt mean it wont be possible later if (promotedType != null) { typesToProcess.RemoveAt(i); promotedTypes.Add(promotedType); log.Append(tmpLog); noOfProcessedInItteration++; } } if (noOfProcessedInItteration == 0) { //Nothing can be done anymore (either because every thing is done or because there is a circle dependency in the tbs) break; } } if (typesToProcess.Count() > 0) { log?.Append(new CompileMessage(CompileMessage.Serverity.Error, "There is a Circular Dependency in the given tbs-File")); } promotedTypes.RemoveRange(0, TbsBuildIn.Types.Count()); // Remove BuildIns (they are not parsed) return(promotedTypes); }
protected void readFunctionParamAddToParamsList(MemberParam extObjectMemberParam, ref FuncParamsSyntaxCollections functionParamsSyntaxCollections, ref ParsedTypes paramTypes, string currentClassName, bool eventCompleting, bool lastParamDefinition) { bool optional = ( (extObjectMemberParam.Optional.HasValue && extObjectMemberParam.Optional.Value == true) || (extObjectMemberParam.Doc != null && extObjectMemberParam.Doc.ToLower().Contains("(optional)")) ); string[] docs = this.readJsDocs( extObjectMemberParam.Doc, (eventCompleting ? JsDocsType.EVENT_PARAM : JsDocsType.METHOD_PARAM), currentClassName, extObjectMemberParam.Name ); /*if (!lastParamDefinition) { * functionParamsSyntaxCollections.StandardParamsSyntax.Add(new Param( * this.sanitizeName(extObjectMemberParam.Name), * docs, * paramTypes.MethodOrEventParam, * optional, * false // not last param can NOT have spread syntax - so this could be fixed false * )); * } else {*/ // When last param types are parsed - it's necessary // to determinate single or multiple method forms by spread // and non-spread last param types if ( !functionParamsSyntaxCollections.SpreadParamFound && paramTypes.MethodOrEventParam.Count > 0 && paramTypes.MethodOrEventSpreadParam.Count > 0 ) { // There will be two method forms: functionParamsSyntaxCollections.SpreadParamFound = true; functionParamsSyntaxCollections.SpreadParamsSyntax = new List <Param>( functionParamsSyntaxCollections.StandardParamsSyntax ); functionParamsSyntaxCollections.SpreadParamsSyntax.Add(new Param( this.sanitizeName(extObjectMemberParam.Name), docs, paramTypes.MethodOrEventSpreadParam, optional, true )); functionParamsSyntaxCollections.StandardParamsSyntax.Add(new Param( this.sanitizeName(extObjectMemberParam.Name), docs, paramTypes.MethodOrEventParam, optional, false )); } else if (paramTypes.MethodOrEventParam.Count > 0) { // There will be only standard params method form: functionParamsSyntaxCollections.StandardParamsSyntax.Add(new Param( this.sanitizeName(extObjectMemberParam.Name), docs, paramTypes.MethodOrEventParam, optional, false )); } else if ( !functionParamsSyntaxCollections.SpreadParamFound && paramTypes.MethodOrEventSpreadParam.Count > 0 ) { if (functionParamsSyntaxCollections.StandardParamsSyntax.Count > 0) { // There is something in standard param(s) from previous param - duplicate everything into spread params collection first: functionParamsSyntaxCollections.SpreadParamFound = true; functionParamsSyntaxCollections.SpreadParamsSyntax = new List <Param>( functionParamsSyntaxCollections.StandardParamsSyntax ); functionParamsSyntaxCollections.SpreadParamsSyntax.Add(new Param( this.sanitizeName(extObjectMemberParam.Name), docs, paramTypes.MethodOrEventSpreadParam, optional, true )); } else { // Add into spread params collection: functionParamsSyntaxCollections.SpreadParamFound = true; functionParamsSyntaxCollections.SpreadParamsSyntax.Add(new Param( this.sanitizeName(extObjectMemberParam.Name), docs, paramTypes.MethodOrEventSpreadParam, optional, true )); } } //} }
protected void readFunctionParamSpecials( MemberParam param, ref ParsedTypes paramTypes, bool eventCompleting, string currentClassName, string eventOrMethodName, bool isStatic, bool eventsCompleting ) { string extParamsPseudoCallbackName; string extParamsPseudoClassName; SpecialParamTypes specialTypes = this.matchSpecStructParamInParamTypes(ref paramTypes); if ((specialTypes.Matches & SpecialParamMatch.ANY_FUNC) != 0) { // Described function callback as special class, not rendered later as type but directly: extParamsPseudoCallbackName = this.extClassMethodConfigObjectPresudoClassName( currentClassName, eventOrMethodName, isStatic, eventsCompleting, param.Name, false ); // `extParamsPseudoCallbackName = 'Ext.AbstractManager.methodsCallbackParams.each.Fn';` // `extParamsPseudoCallbackName = 'Ext.Class.staticMethodsCallbackParams.registerPreprocessor.Fn';` this.readFunctionParamCallbackProperties( extParamsPseudoCallbackName, eventOrMethodName, param.Doc, param.Properties, eventCompleting ); // Add described virtual callback type: if ((specialTypes.Matches & SpecialParamMatch.STANDARD_COLLECTION_FUNC) != 0) { paramTypes.MethodOrEventParam.Add(extParamsPseudoCallbackName); } if ((specialTypes.Matches & SpecialParamMatch.STANDARD_COLLECTION_FUNC_ARR) != 0) { paramTypes.MethodOrEventParam.Add(extParamsPseudoCallbackName + "[]"); } if ((specialTypes.Matches & SpecialParamMatch.SPREAD_COLLECTION_FUNC) != 0) { paramTypes.MethodOrEventSpreadParam.Add(extParamsPseudoCallbackName); } } if ((specialTypes.Matches & SpecialParamMatch.ANY_OBJECT) != 0) { // Described config object as special class, rendered later as type, // extended from `Object` TypeScript interface: extParamsPseudoClassName = this.extClassMethodConfigObjectPresudoClassName( currentClassName, eventOrMethodName, isStatic, eventsCompleting, param.Name, true ); // `extParamsPseudoClassName = 'Ext.Ajax.methodsParams.addListener.Options';` // `extParamsPseudoClassName = 'Ext.data.Model.staticMethodsParams.load.Options';` this.readFunctionParamConfObjectProperties( currentClassName, extParamsPseudoClassName, eventOrMethodName, "Object", param.Doc, param.Properties, eventCompleting, isStatic ); if ((specialTypes.Matches & SpecialParamMatch.STANDARD_COLLECTION_OBJECT) != 0) { paramTypes.MethodOrEventParam.Add(extParamsPseudoClassName); } if ((specialTypes.Matches & SpecialParamMatch.STANDARD_COLLECTION_OBJECT_ARR) != 0) { paramTypes.MethodOrEventParam.Add(extParamsPseudoClassName + "[]"); } if ((specialTypes.Matches & SpecialParamMatch.SPREAD_COLLECTION_OBJECT) != 0) { paramTypes.MethodOrEventSpreadParam.Add(extParamsPseudoClassName); } } if ((specialTypes.Matches & SpecialParamMatch.ANY_INTERFACE) != 0) { // Described config object as special class, rendered later as type, // extended from given interface(s): bool numberTypes = specialTypes.MethodOrEventAllParamTypes.Count > 1; int index = 1; bool specTypeIsArr; bool typeIsForStandardCollection; bool typeIsforSpreadCollection; foreach (string specialTypeParent in specialTypes.MethodOrEventAllParamTypes) { specTypeIsArr = specialTypeParent.EndsWith("[]"); extParamsPseudoClassName = this.extClassMethodConfigObjectPresudoClassName( currentClassName, eventOrMethodName, isStatic, eventsCompleting, param.Name, true ); // `extParamsPseudoClassName = 'Ext.button.Segmented.methodsParams.onFocusLeave.E';` if (numberTypes) { extParamsPseudoClassName += index.ToString(); } this.readFunctionParamConfObjectProperties( currentClassName, extParamsPseudoClassName, eventOrMethodName, specTypeIsArr ? specialTypeParent.Substring(0, specialTypeParent.Length - 2) : specialTypeParent, param.Doc, param.Properties, eventCompleting, isStatic ); typeIsForStandardCollection = specialTypes.MethodOrEventParamTypes.Contains(specialTypeParent); typeIsforSpreadCollection = specialTypes.MethodOrEventSpreadParamTypes.Contains(specialTypeParent); if ( typeIsForStandardCollection && (specialTypes.Matches & SpecialParamMatch.STANDARD_COLLECTION_INTERFACE) != 0 ) { paramTypes.MethodOrEventParam.Add(extParamsPseudoClassName); } if ( typeIsForStandardCollection && specTypeIsArr && (specialTypes.Matches & SpecialParamMatch.STANDARD_COLLECTION_INTERFACE_ARR) != 0 ) { paramTypes.MethodOrEventParam.Add(extParamsPseudoClassName + "[]"); } if ( typeIsforSpreadCollection && (specialTypes.Matches & SpecialParamMatch.SPREAD_COLLECTION_INTERFACE) != 0 ) { paramTypes.MethodOrEventSpreadParam.Add(extParamsPseudoClassName); } index += 1; } } }
/** * Complete result types collection(s): */ protected void completeResultList( ref ParsedTypes result, List <string> rawTypesList, TypeDefinitionPlace typeDefinitionPlace, bool methodParamDefinition, string definitionFullPath, string memberOrParamName ) { string typeItem = ""; string typeItemLower = ""; int arrBracketsPos = 0; string arrayBrackets = ""; bool functionParamSpreadSyntax; bool anyMatchedNormal = false; bool anyMatchedSpreadSyntax = false; for (int i = 0; i < rawTypesList.Count; i++) { // Trim type definition string: typeItem = rawTypesList[i].Trim( new char[] { ' ', '\t', '\v', '\r', '\n' } ); // Check and correct the type if there is function param spread syntax detected functionParamSpreadSyntax = methodParamDefinition && typeItem.Contains("..."); if (functionParamSpreadSyntax) { typeItem = typeItem.Replace("...", ""); } // Take off temporary array brackets at the end if there are any: arrBracketsPos = typeItem.IndexOf("[]"); if (arrBracketsPos > -1) { arrayBrackets = typeItem.Substring(arrBracketsPos); typeItem = typeItem.Substring(0, arrBracketsPos); } else { arrayBrackets = ""; } // Create lowercase type definition variant to determinate primitive JS types and define correct typescript type form: if (this.processor.Store.ClassesFixes.ContainsKey(typeItem)) { typeItem = this.processor.Store.ClassesFixes[typeItem]; } typeItemLower = typeItem.ToLower(); // Check internal JS priitives, internal js types, special wildcard definitions, // function arguments type or any other type to register and chack later if (JavascriptInternals.IsJsPrimitiveTypescriptLower(typeItemLower)) { // Primitive JS types has to be lowercased for TypeScript: // https://www.typescriptlang.org/docs/handbook/declaration-files/do-s-and-don-ts.html typeItem = typeItemLower; } else if (typeItemLower == "arguments") { // If type is defined as function arguments object, // correct it to TypeScript `IArguments` interface defined in `lib.es5.d.ts`: typeItem = "IArguments"; } else if (InheritanceResolvers.Types.IsBrowserInternalType(typeItem)) { /*if (JavascriptInternals.JsGlobalsAlsoInExtNamespace.Contains(typeItem)) { * typeItem = SpecialsGenerator.GLOBAL_CLASS_BASE * .Replace("<browserGlobalClassName>", typeItem); * } else*/if (typeItemLower == "array") { // If type is internal JS type or internal EcmaScript DOM type, // correct only `array` to `any[]` and do not register anything for later chacking: typeItem = "any[]"; } } else if (typeItemLower == "mixed" || typeItemLower == "*" || typeItemLower == "type" /* always in private classes */ || typeItemLower == "[type]") { // If type is any special JS Docs wildcard - corect it to TypeScript `any` type: typeItem = "any"; } else { // If type is anything other - register this type for later checking process: if ( !typeItem.StartsWith("'") && // if it is not start with "'" !typeItem.EndsWith("'") && // if it is not end with "'" !Regex.Match(typeItem, @"^([0-9\+\-\.]+)$").Success&& // if it is not numeric !Regex.Match(typeItem, @"^\{(.*)\}$").Success // if it is not direct object: { x:: Number, y: Number, ...} ) { this.processor.Store.AddTypePlace( typeDefinitionPlace, definitionFullPath, memberOrParamName, typeItem ); } } // Add array brackets back at the end if there were any: if (arrayBrackets.Length > 0) { typeItem += arrayBrackets; } // If there is `any` TypeScript type matched - store this information later and ad this type at the result list end if (typeItem == "any") { if (functionParamSpreadSyntax) { anyMatchedSpreadSyntax = true; } else { anyMatchedNormal = true; }; } else { this.addTypeToResult( ref result, typeDefinitionPlace, functionParamSpreadSyntax, typeItem ); } } // add `any` TypeScript type always at the end: if (anyMatchedNormal) // add any always as last { this.addTypeToResult( ref result, typeDefinitionPlace, false, "any" ); } if (anyMatchedSpreadSyntax) // add any always as last { this.addTypeToResult( ref result, typeDefinitionPlace, true, "any" ); } }