static string GetIcon(DocComment dc) { string access = null; if(dc.MemberAccess == null) { } else if(dc.MemberAccess == "protected" || dc.MemberAccess == "internal") { access = "-protected"; } else if(dc.MemberAccess == "private") { access = "-private"; } return dc.MemberType + access; }
public void Process() { DocComment[] dcs = new DocComment[_parser.Data.DocComments.Count]; _parser.Data.DocComments.Values.CopyTo(dcs, 0); foreach(DocComment dc in dcs) { ProcessSignle(dc); } _parser.Data.Global.DocComment = new DocComment() { Type = "Object", Name = "window", System =true }; AutoFill(_parser.Data.Global); }
private void AutoFillTypeByReturnValue(DocComment dc) { if (dc != null && ReturnValue != null) { if (ReturnValue is bool) { dc.AutoFill(NodeNames.Type, "Boolean"); dc.AutoFill(NodeNames.DefaultValue, (bool)ReturnValue == true ? "true" : "false"); } else if (ReturnValue is string) { dc.AutoFill(NodeNames.Type, "String"); dc.AutoFill(NodeNames.DefaultValue, new StringLiteral((string)ReturnValue, '"', Location.Empty, Location.Empty).ToString()); } else if (ReturnValue is double) { dc.AutoFill(NodeNames.Type, "Number"); if (!(double.IsNaN((double)ReturnValue))) dc.AutoFill(NodeNames.DefaultValue, ReturnValue.ToString()); } else if (ReturnValue is ILiteral) { if (ReturnValue is ArrayLiteral) { dc.AutoFill(NodeNames.Type, "Array"); } else if (ReturnValue is NullLiteral) { dc.AutoFill(NodeNames.DefaultValue, "null"); } else if (ReturnValue is RegExpLiteral) { dc.AutoFill(NodeNames.Type, "RegExp"); dc.AutoFill(NodeNames.DefaultValue, ((RegExpLiteral)ReturnValue).ToString()); } else if (ReturnValue is FunctionExpression) { dc.AutoFill(NodeNames.Type, "Function"); dc.AutoFill(NodeNames.MemberType, "method"); if(_project.AutoCreateFunctionParam) { FunctionExpression fn = (FunctionExpression)ReturnValue; var param = (ParamInfoCollection)dc[NodeNames.Param]; if(param == null) { dc[NodeNames.Param] = param = new ParamInfoCollection(); foreach(Identifier p in fn.Params) { param.Add(p.Value); } } } } } } }
/// <summary> /// 自动识别注释中的名字。 /// </summary> /// <param name="dc">赋值的父对象。</param> /// <param name="value">变量。</param> private void AutoFillName(DocComment dc, string name) { if (dc != null && name != null) dc.AutoFill(NodeNames.Name, name); }
/// <summary> /// 根据注释所处位置,自动分析注释的所属对象。 /// </summary> /// <param name="dc"></param> private void AutoFillMemberOf(DocComment dc) { string memberType = dc.MemberType; int memberTypeNo = memberType == "class" ? 0 : memberType == "enum" || memberType == "interface" || memberType == "module" ? 1 : 2; // 处理当前的所属成员问题。 if (dc.NamespaceSetter == null) { if (memberTypeNo <= 1) { if (dc.Name == null) { CurrentScope.CurrentMemberOf = null; CurrentScope.CurrentMemberOfIsClass = false; } else if (memberTypeNo == 0) { CurrentScope.CurrentMemberOf = dc.FullName; CurrentScope.CurrentMemberOfIsClass = !dc.IsStatic; } else if (memberTypeNo == 1) { CurrentScope.CurrentMemberOf = dc.FullName; CurrentScope.CurrentMemberOfIsClass = false; } } } else { if (dc.NamespaceSetter.Length == 0) { CurrentScope.CurrentMemberOf = dc.FullName; } else { CurrentScope.CurrentMemberOf = dc.NamespaceSetter; } CurrentScope.CurrentMemberOfIsClass = false; } // 处理类成员问题。 if (memberTypeNo == 2) { // 如果没有指定 memberOf ,程序需要自行猜测。 if(dc.MemberOf == null) { string parentNamspace; bool parentIsClass; // 如果现在正在 obj = {} 状态下。 DocComment obj = CurrentObject; if(obj != null) { parentNamspace = obj.FullName; parentIsClass = obj.MemberType == "class"; if(obj.Ignore) { dc.Ignore = true; } } else { parentNamspace = CurrentScope.CurrentMemberOf; parentIsClass = CurrentScope.CurrentMemberOfIsClass; } dc.MemberOf = parentNamspace; dc.IsMember = parentIsClass && !dc.IsStatic; } else { } } }
/// <summary> /// 开始对指定的节点解析。 /// </summary> /// <param name="script">语法树。</param> /// <param name="comments">所有注释。</param> /// <returns>全局对象。所有变量都可从这个节点找到。</returns> public void Parse(Script script, DocComment[] comments) { _map = comments; _position = 0; CurrentScope = new Scope() { CurrentMemberOf = "window" }; VisitScript(script); }
void PushScope(DocComment docComment) { Scope scope = new Scope(); scope.Comment = docComment; scope.Parent = CurrentScope; scope.CurrentMemberOf = CurrentScope.CurrentMemberOf; scope.CurrentMemberOfIsClass = CurrentScope.CurrentMemberOfIsClass; CurrentScope = scope; }
void PushObject(DocComment docComment) { _objectStack.Push(docComment); }
private void Process(DocComment dc) { AutoFillMemberOf(dc); }
bool GetNext(Location location, out DocComment dc) { int off; // 如果当前索引在范围内。 if (_position < _map.Length) { // 获取下一个变量。 dc = _map[_position]; off = dc.EndLocation.Line - location.Line; // 如果下一个变量在当前行之上。 if (off <= 0) { _position++; bool r = off < -1; // 假如当前的注释是接近的注释,那检查是否存在更接近的注释。 if (!r && _position < _map.Length) { off = _map[_position].EndLocation.Line - location.Line; if (off == 0 || off == -1) r = true; } return r; } } // 否则,没有可用的变量了。必须回去找。 //for (int i = _position - 1; i >= 0; i--) { // off = _map[i].EndLocation.Line - location.Line; // if (off <= 0) { // if (off == 0 || off == -1) { // dc = _map[i]; // return false; // } // break; // } //} dc = null; return false; }
/// <summary> /// 解析指定的文档数据。 /// </summary> /// <param name="docCommentMap">文档。</param> public void Parse(DocComment[] docCommentMap) { GetDocMembers(docCommentMap); RemoveIgnores(); }
void ProcessSignle(DocComment dc) { Variant p = _parser.Data.Global; if(!String.IsNullOrEmpty(dc.MemberOf)) { string baseMemberName = null; foreach(string memberName in dc.MemberOf.Split('.')) { string newBaseMemberName = baseMemberName + memberName; if(!p.ContainsKey(memberName)) { // 生成父对象。 p[memberName] = new Variant(); DocComment dc2; if(!_parser.Data.DocComments.TryGetValue(newBaseMemberName, out dc2)) { dc2 = new DocComment() { Type = "Object", Name = memberName, MemberOf = baseMemberName, System = true }; _parser.Data.DocComments[newBaseMemberName] = dc2; } p[memberName].DocComment = dc2; } p = p[memberName]; baseMemberName = newBaseMemberName + "."; } } if(dc.IsMember) { if(!p.ContainsKey("prototype")) { p["prototype"] = new Variant() { DocComment = new DocComment() { Type = "Object", Name = "prototype", MemberOf = dc.MemberOf, System = true, MemberType = "namespace" } }; } p = p["prototype"]; } if(!p.ContainsKey(dc.Name)) { p[dc.Name] = new Variant(); } p[dc.Name].DocComment = dc; }
/// <summary> /// 获取全部可用的成员。 /// </summary> /// <param name="docCommentMap"></param> void GetDocMembers(DocComment[] docCommentMap) { for(int i = 0; i < docCommentMap.Length; i++) { DocComment dc = docCommentMap[i]; if(_parser.Project.UseNamingRules && dc.Name != null && dc.Name.StartsWith("_")) { dc.AutoFill(NodeNames.MemberAccess, "private"); } if (dc.Ignore) continue; if (dc.Name != null) { string key = dc.FullName; DocComment old; if (_parser.Data.DocComments.TryGetValue(dc.FullName, out old)) { old.Merge(dc); } else { _parser.Data.DocComments[dc.FullName] = dc; } } else if (dc.NamespaceSetter != null && dc.NamespaceSetter != "window") { string key = dc.NamespaceSetter; int p = key.LastIndexOf('.'); if (p <= 0) { dc.Name = key; dc.MemberOf = "window"; } else { dc.Name = key.Substring(p + 1); dc.MemberOf = key.Substring(0, p); } DocComment old; if (_parser.Data.DocComments.TryGetValue(key, out old)) { old.Merge(dc); } else { _parser.Data.DocComments[key] = dc; } } } }
/// <summary> /// 将指定变量的注释合并到当前变量。 /// </summary> /// <param name="src"></param> public void Merge(DocComment src) { for (int i = 0; i < src.Count; i++) { BaseSet(src.BaseGetKey(i), src.BaseGet(i)); } }
void SaveSimpleComment(DocComment dc, CorePlus.Json.JsonObject obj) { obj.Add("type", dc.MemberType); obj.Add("icon", GetIcon(dc)); }
void SaveClassInfo(DocComment dc, CorePlus.Json.JsonObject obj) { string fullName = dc.FullName; obj.Add("fullName",fullName); obj.Add("source", dc.Source); if(dc.Source != null) { obj.Add("sourceFile", "data/source/" + dc.Source + ".html#" + fullName.Replace('.', '-')); } SortedList<string, DocComment> members = new SortedList<string,DocComment>(); SortedList<string, DocComment> statics = new SortedList<string, DocComment>(); if (dc.MemberType == "class" && dc.Variant.Members != null) { GetMembersAndCopyToTmpList(dc.Variant.Members, members, statics); } // 如果有成员。生成成员字段。 if(dc.Variant.Count > 0) { GetMembersAndCopyToTmpList(dc.Variant, members, statics); } if (_project.DefaultExtends != null && dc.MemberType == "class") { DocComment dc2 ; if (_data.DocComments.TryGetValue(_project.DefaultExtends, out dc2) && dc2.Variant != null) { GetMembersAndCopyToTmpList(dc2.Variant, members, statics); } } DocComment e; if(dc.Extends != null && _data.DocComments.TryGetValue(dc.Extends, out e)) { string extends = dc.Extends; if (e.Variant.Members != null) { GetMembersAndCopyToTmpList(e.Variant.Members, members, statics); } JsonArray baseClasses = new JsonArray(); obj["baseClasses"] = baseClasses; while (extends != null && _data.DocComments.TryGetValue(extends, out e)) { baseClasses.Insert(0, extends); extends = e.Extends; } } if(dc.Implements != null) { foreach(string im in dc.Implements) { if(_data.DocComments.TryGetValue(im, out e)) GetMembersAndCopyToTmpList(e.Variant, members, members); } } string memberOf = dc.FullName; SaveTmpList(members, obj, memberOf, false); SaveTmpList(statics, obj, memberOf, true); if(_extendsInfo.ContainsKey(fullName)) { JsonArray subClasses = new JsonArray(); obj["subClasses"] = subClasses; var list = _extendsInfo[fullName]; list.Sort(); subClasses.AddRange(list); } foreach(string key in dc){ AddSingle(obj, key, dc[key]); } }