AvaloniaVS icon indicating copy to clipboard operation
AvaloniaVS copied to clipboard

Continued completion engine and intellisense upgrades

Open amwx opened this issue 1 year ago • 6 comments

Just pulling this out of my PR for visibility and tracking, but this is a list of things I marked as TODOs for continuing to upgrade the completion engine and intellisense in VS to support newer Avalonia features and be smarter about the suggestions offered. Some of these are things implemented in the core completion engine, and some are more on the VS intellisense side (or both).

Just to recap what was in #275:

  • Improved completion of pseudoclasses, including getting all pseudoclasses from the attribute
  • Fixed handling completion on '.' character so it does swallow the '.' in something like Window.Resources
  • Fixed the double intellisense popup when adding xml namespaces

These are still left:

  • [ ] find and list all defined resources instead of using static, hard-coded ones (hopefully, if not will add to future todos) that don't really apply to anything outside the old default theme
    • Ideally with this we need to make sure at least the active document (maybe even the current project) can update the suggestions more frequently without requiring a build (which is how the metadata is currently invalidated) as if you add a resource to the current file, I would expect it to immediately show without having to build the project. External assemblies could probably be cached like normal on build only since they're static unless the ref is explicitly updated
  • [x] Filter out non-public types from suggestions
    • @workgroupengineering Now that the completion engine is in this repo, you should be able to complete your PR (#216)
  • [ ] Fix getting properties in nested style selectors. Nested style selectors without a type Selector="^:pointerover" will fail to offer valid suggestions
  • [ ] Add better context awareness for suggestions, including:
    • filtering the suggestions to only include what makes sense at the given point in the document (this is mostly already how it is, but I think there are a few places where this could be improved, as an example, don't suggest VerticalContentAlignment unless it absolutely makes sense to do so (only suggest VerticalAlignment)
    • In a Style Selector, we could probably make it only suggest things that make sense given the cursor position, e.g., don't suggest /template/ or pseudoclasses at the start of the selector, no pseudoclasses directly after /template/, etc
    • In #275, I've also added some code to tell VS to auto select the first suggestion in the list - previously, it wouldn't usually do this and you had to physically interact (mouse or arrow keys) to get the completion to work. We could probably improve this to guess the best item and select it instead based on context
    • Only offering pseudoclasses valid for a particular control
    • Don't suggest properties that are already set on a given control, or within a particular Style block
  • [ ] Fix editing existing text and accepting a completion
    • Currently if you type ponterover and try to correct it, adding the i will suggest :pointerover, but accepting that completion will end up with pointerovernterover as it just inserts the suggested text and doesn't check anything for replacing
  • [ ] When adding an xml namespace, don't accept a completion on the '.' character as it may complete on the wrong namespaces
  • [ ] Allow hiding members/classes with [EditorBrowsable]

amwx avatar Dec 10 '22 03:12 amwx

It feels like at some point we will have to start using XamlX compiler for the XAML editor as well. For multiple reasons:

  • Warnings and errors highlighing (https://github.com/kekekeks/XamlX/pull/25, https://github.com/kekekeks/XamlX/pull/27 are needed, as well as warnings and xml-node range information (instead of simple position and line)
  • More integrated support of context-based features. Like DataContext lookup used for compiled bindings, chunk of code could be reused.
  • It also can help with resources lookup

maxkatz6 avatar Dec 13 '22 14:12 maxkatz6

I'm looking for building StaticResource autocomplete. From what I've found there are 2 ways of doing this:

  1. Consult with VS to get all .axaml files in project/solution, parse them and find resources.

    • pros:
      1. relatively simple to implement
      2. easy to add "go to definition"
      3. quick response, no need to recompile in order to see changes
      4. unlikely to break, since xaml is stable
    • cons:
      1. Works only with current solution, no autocomplete from external sources (packages, avalonia)
  2. Decompile CompiledAvaloniaXaml.!AvaloniaResources.Populate:/filename.axaml in consumed assembly

    • pros:
      1. works with anything (own assemblies, third-party ones)
      2. possible to add "go to definition" since sequence points are present in debug assemblies
    • cons:
      1. Relies on compiled representation of xaml. If it changes, designer gonna break. Potentially needs versioning if compiled format could change
      2. No type information is present inside compiled xaml. XamlClosure_x returns object. Further decompilation is needed to get actual type of resource
      3. legal issues?

I think that mix of both solutions is required

jl0pd avatar Apr 26 '23 05:04 jl0pd

@jl0pd correct solution would be to update compiler to inject markers (possible assembly attributes) with information for each resource. And then use these markers in the previewer.

maxkatz6 avatar Apr 26 '23 07:04 maxkatz6

Problem of such solution is that is will bloat assembly size, while it won't be necessary in runtime.

[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public sealed class DeclaredResourceAttribute : Attribute
{
    public DeclaredResourceAttribute(string path, object key, Type resourceType)
    {
    }
}

Attribute in such form would be used as [assembly: DeclaredResource("/Themes/Generic.axaml", "myResourceKey2", typeof(string))]. Unfortunate truth is that attributes are bad at size, since all arguments are converted into single blob. So "/Themes/Geneirc.axaml" won't be shared between multiple attributes. Each one will take 100+ bytes in resulting dll file.


Edit:

For example Avalonia.Themes.Fluent contains 1650 resources, each adds 100 bytes to assembly, so we get 165,000 bytes. Size of compiled dll in release is 1,674,000 bytes. Approximately 10% size increase is expected

jl0pd avatar Apr 26 '23 08:04 jl0pd

We could replace "path" with integer ID of XAML file theoretically. Object key is questionable, as it won't be allowed in the attribute, only string I suppose (which is mostly enough).

maxkatz6 avatar Apr 26 '23 20:04 maxkatz6

Possibly some const blob of bytes can be generated as an alternative, which is serialized by the compiler and deserialized by the previewer. Should save some size, but not too much as we still won't be able to reuse key string values (which already exist in binary data section).

maxkatz6 avatar Apr 26 '23 20:04 maxkatz6