0

SCENARIO


Code Jumper is a time-saver extension/plugin for Visual Studio that adds a kind of navigation panel to easily jump between the members of your code with a single click.

For big APIs it's really useful because it avoids scrolling thousands of lines, opening #regions, hidding Xml documentation, searching for a method or member name, etc... its a must-have extension, because It really saves a lot of time:

enter image description here

PROBLEM


Code Jumper has one big problem for my needs, it can't parse Vb.Net Modules, no matter what says in the product description, because the reality is that it can't (its written by a C# guy so maybe he didn't knew the existance of Modules...)

When opening a module, the window of Code jumper is empty, any member is shown.

QUESTION


Here is the downloadable source-code of Code Jumper, written in C#.

What modifications I need to do to make it work with Vb.Net Modules?.

OPTIONAL QUESTION


Someone knows a similar and better extension than Code Jumper?.

RESEARCH


I think this is the most relevant code, in DocumentParser.cs file:

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;
}

I tried to add an additional condition for vsCMElement.vsCMElementModule, however, it still don't work, and I 'm not sure whether I'm on the right direction:

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;
}
ElektroStudios
  • 19,105
  • 33
  • 200
  • 417

1 Answers1

1

I can't get it to compile, but if you look at all references for CodeElementType.Class, almost all of them need to be "duplicated" with CodeElementType.Module, especially in IsStackableElement, probably answering your question.


Partial code to explain the required modifications:

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;
    }
    // ...
}
ElektroStudios
  • 19,105
  • 33
  • 200
  • 417
Mark Hurd
  • 10,665
  • 10
  • 68
  • 101
  • I will try what you mentioned, thanks for answer!.About compiling it,I don't know what problem you found,but I also found problems to compile the first time,maybe this solves your problem: Change the targeting framework to 4.5 (for whatever reason in NetFx 4.0 it can't find the VS assemblies on my PC),If any **VisualStudio.xxxx.dll** reference is failing to be located,delete it and re-reference it from the Visual Studio's public assemblies directory (its on the Visual Studio Installation directory) or from GAC directory (if found there).PS: The VS SDK need to be installed to proceed compiling. – ElektroStudios Apr 03 '16 at 19:22