使 'Code Jumper' 扩展(它的源代码)与 Vb.Net 模块一起工作

Make 'Code Jumper' extension (its source-code) work with Vb.Net Modules

场景


Code JumperVisual Studio 的省时工具 extension/plugin 添加了一种导航面板,只需单击一下即可在代码成员之间轻松跳转。

对于大型 API,它非常有用,因为它避免了滚动数千行、打开#regions、隐藏 Xml 文档、搜索方法或成员名称等......它是必备的扩展,因为它真的节省了很多时间:

问题


Code Jumper 对我的需求有一个大问题,它无法解析 Vb.Net 模块,无论产品描述中怎么说,因为现实是它不能(它是由 C# 人编写的,所以也许他不知道模块的存在...)

打开模块时,跳码的window为空,显示任意成员

问题


HereCode Jumper 的可下载源代码,用 C# 编写。

我需要做哪些修改才能使其与 Vb.Net 模块一起使用?

可选问题


有人知道与 Code Jumper 相似且更好的扩展吗?

研究


我认为这是最相关的代码,在 DocumentParser.cs 文件中:

public void RecurseCodeElements(CodeElements elements, CodeElementAggregate aggregate) {

    if (elements == null)
        return;
    _recurseCount++;

    if (_recurseCount % 2 == 0) {
        if (ParserProgress != null)
            _appConfig.elementView.Dispatcher.BeginInvoke((Action)(() => ParserProgress(this)));
    }

    foreach (CodeElement element in elements) {

        System.Threading.Thread.Sleep(10);

        if (element.Kind == vsCMElement.vsCMElementClass) {
            RecurseCodeElements(GetMembers(element), aggregate.Add(element));
        }

        if (element.Kind == vsCMElement.vsCMElementInterface) {
            RecurseCodeElements(GetMembers(element), aggregate.Add(element));
        }

        if (element.Kind == vsCMElement.vsCMElementStruct) {
            RecurseCodeElements(GetMembers(element), aggregate.Add(element));
        }

        if (element.Kind == vsCMElement.vsCMElementNamespace) {
            RecurseCodeElements(GetMembers(element), aggregate);
        }

        if (element.Kind == vsCMElement.vsCMElementEnum) {
            RecurseCodeElements(GetMembers(element), aggregate.Add(element));
        }

        if (element.Kind == vsCMElement.vsCMElementFunction ||
            element.Kind == vsCMElement.vsCMElementProperty ||
            element.Kind == vsCMElement.vsCMElementVariable ||
            element.Kind == vsCMElement.vsCMElementDelegate ||
            element.Kind == vsCMElement.vsCMElementEvent)
        {
            var func = element as CodeFunction;
            aggregate.Add(element);
        }
    }
}

private CodeElements GetMembers(CodeElement element) {

    if (element == null)
        return null;

    if (element.Kind == vsCMElement.vsCMElementNamespace) {
        return (element as CodeNamespace).Members;
    }

    if (element.Kind == vsCMElement.vsCMElementClass) {
        return (element as CodeClass).Members;
    }

    if (element.Kind == vsCMElement.vsCMElementInterface) {
        return (element as CodeInterface).Members;
    }

    if (element.Kind == vsCMElement.vsCMElementEnum) {
        return (element as CodeEnum).Members;
    }

    if (element.Kind == vsCMElement.vsCMElementStruct) {
        return (element as CodeStruct).Members;
    }
    return null;
}

我尝试为vsCMElement.vsCMElementModule添加附加条件,但是还是不行,我不确定我是否在正确方向:

public void RecurseCodeElements(CodeElements elements, CodeElementAggregate aggregate) {

    if (elements == null)
        return;
    _recurseCount++;

    if (_recurseCount % 2 == 0) {
        if (ParserProgress != null)
            _appConfig.elementView.Dispatcher.BeginInvoke((Action)(() => ParserProgress(this)));
    }

    foreach (CodeElement element in elements) {

        System.Threading.Thread.Sleep(10);

        if (element.Kind == vsCMElement.vsCMElementClass) {
            RecurseCodeElements(GetMembers(element), aggregate.Add(element));
        }

        if (element.Kind == vsCMElement.vsCMElementModule) {
            RecurseCodeElements(GetMembers(element), aggregate.Add(element));
        }

        if (element.Kind == vsCMElement.vsCMElementInterface) {
            RecurseCodeElements(GetMembers(element), aggregate.Add(element));
        }

        if (element.Kind == vsCMElement.vsCMElementStruct) {
            RecurseCodeElements(GetMembers(element), aggregate.Add(element));
        }

        if (element.Kind == vsCMElement.vsCMElementNamespace) {
            RecurseCodeElements(GetMembers(element), aggregate);
        }

        if (element.Kind == vsCMElement.vsCMElementEnum) {
            RecurseCodeElements(GetMembers(element), aggregate.Add(element));
        }

        if (element.Kind == vsCMElement.vsCMElementFunction ||
            element.Kind == vsCMElement.vsCMElementProperty ||
            element.Kind == vsCMElement.vsCMElementVariable ||
            element.Kind == vsCMElement.vsCMElementDelegate ||
            element.Kind == vsCMElement.vsCMElementEvent)
        {
            var func = element as CodeFunction;
            aggregate.Add(element);
        }
    }
}

private CodeElements GetMembers(CodeElement element) {

    if (element == null)
        return null;

    if (element.Kind == vsCMElement.vsCMElementNamespace) {
        return (element as CodeNamespace).Members;
    }

    if (element.Kind == vsCMElement.vsCMElementModule) {
        return (element as CodeClass).Members;
    }

    if (element.Kind == vsCMElement.vsCMElementClass) {
        return (element as CodeClass).Members;
    }

    if (element.Kind == vsCMElement.vsCMElementInterface) {
        return (element as CodeInterface).Members;
    }

    if (element.Kind == vsCMElement.vsCMElementEnum) {
        return (element as CodeEnum).Members;
    }

    if (element.Kind == vsCMElement.vsCMElementStruct) {
        return (element as CodeStruct).Members;
    }
    return null;
}

我无法编译它,但是如果你查看所有关于 CodeElementType.Class 的参考资料,几乎所有的参考资料都需要 "duplicated" 和 CodeElementType.Module,尤其是 IsStackableElement,可能会回答你的问题。


解释所需修改的部分代码:

public void RecurseCodeElements(CodeElements elements, CodeElementAggregate aggregate) {
    // ...
    foreach (CodeElement element in elements) {
        // ...
        if (element.Kind == vsCMElement.vsCMElementModule) {
            RecurseCodeElements(GetMembers(element), aggregate.Add(element));
        }
        // ...
    }
}

private CodeElements GetMembers(CodeElement element) {
    // ...
    if (element.Kind == vsCMElement.vsCMElementModule) {
        return (element as CodeClass).Members;
    }
    // ...
}
public bool IsStackableElement {
    get
    {
        if (IsRoot) 
            // ...
            return (ElementType == CodeElementType.Class || ElementType == CodeElementType.Module || ... )
            // ...
    }
}

public static CodeElementType GetElementType(CodeElement element) {
    switch (element.Kind) {
        // ...
        case vsCMElement.vsCMElementModule:
            return CodeElementType.Module;
        // ...
    }
}

public void Draw() {
    // ...
    if (ElementType == CodeElementType.Module) {
        _elementStackPanel.Background = _appConfig.ClassBackgroundBrush;
    }
    // ...
}

public void Update() {
    // ...
    if (ElementType == CodeElementType.Module)
    {
        ElementLabel.AddExpander(_elementStackPanel);
        ElementLabel.AddPictureToSingleGrid(ElementInfo.ElementImage);
        ElementLabel.AddPictureToSingleGrid(ElementInfo.Accessibility.AccessibilityImage);
        ElementLabel.AddText(ElementInfo.Name, _appConfig.ClassTextBrush, _appConfig.HyperlinkTextImageSpacer, FontWeights.Bold);
    }
    // ...
}

private bool GetElementInfo() {
    // ...
    if (ElementInfo.ElementType == CodeElementType.Module) {
        ElementInfo.ElementImage = _appConfig.GetImage("staticclass");
    }
    // ...
}

private void ParseCodeElement() {
    // ...
    if (ElementInfo.ElementType == CodeElementType.Module)
    {
        ElementInfo.IsStackable = true;
        var codeClass = (CodeClass)Original;
        var codeClass2 = (CodeClass2)Original;
        ElementInfo.Accessibility = new AccessibilityContainer(_appConfig, codeClass.Access);
        ElementInfo.IsStatic = true;
    }
    // ...
}