Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[C] Improve Goto Definition and Goto Reference #1831

Open
wants to merge 64 commits into
base: master
Choose a base branch
from

Conversation

ismell
Copy link

@ismell ismell commented Jan 9, 2019

In my journey to fix #1830 I ended up re-writing a lot of the syntax. It now more accurately scopes entity.name.* and preprocessor macros. My goal is to make Goto Definition and Goto Reference work a lot better then they currently do.

Function parameters are also scoped better, so we should remove source.c from the Monokai Function argument style.

Tests have been greatly improved. I mostly tested this syntax on the linux kernel and various firmware projects.

My goal is to implement #1861. This will require theme changes though. I think we should blacklist entity.name.variable from the Entity name style.

Before

C - before

After

C - after

rwols
rwols previously approved these changes Jan 23, 2019
@wbond
Copy link
Member

wbond commented Jan 23, 2019

Could we add tests for this construct to the other C variants to make sure it get inherited?

@ismell
Copy link
Author

ismell commented Jan 31, 2019

Done. I need to find some time to give the C syntax some love.

@ismell
Copy link
Author

ismell commented Feb 27, 2019

Don't merge this yet... I have a couple other fixes for this.

So correctly fixing this involved a lot more changes then I expected.

Fixes sublimehq#1830

Signed-off-by: Raul E Rangel <[email protected]>
@ismell
Copy link
Author

ismell commented Mar 4, 2019

So actually fixing struct required a lot more work. I'm pushing up my WIP to get some initial feedback. You can ignore all the debug.* scopes. I will remove those for the final PR. I also haven't fixed the enum, or union keywords completely.That's the reason I have the struct-keyword context added everywhere data-structures is checked. This will eventually be cleaned up once I get around to re-writing union and enum. I want to do that work in another PR thought.

Feature Request, It would be cool if I could enable a syntax developer mode where the context that applied a scope could be determined. Then I could avoid adding all the `debug.* scopes manually.

I was also wondering why the Monokai theme doesn't highlight function arguments?

        {
            "name": "Function argument",
            "scope": "variable.parameter - (source.c | source.c++ | source.objc | source.objc++)",
            "foreground": "var(orange)",
            "font_style": "italic"
        },

I actually almost got them scoped correctly now, so it would be nice to see them highlighted by default.

I chose to mark the struct name in a typedef as an entity because it's
still possible to use `struct MyStruct` in code so we should be able to
navigate to the symbol if it's referenced that way.
@ismell
Copy link
Author

ismell commented Mar 5, 2019

I fixed typedef used with struct declarations and function pointers. Let me know if I'm missing any other cases. I might start cleaning up union next.

The struct|union|enum keyword scopes now act like any other type. This
reduces the number of specific scopes required.
@ismell
Copy link
Author

ismell commented Mar 11, 2019

So I simplified my changes. This reduces the number of top level struct scopes to 1 instead of the three I had. I also fixed union and enum. I replaced the existing function/variable declaration mechanism with the one I had written for the struct body. This now correctly tags multiple variable declarations and multiple function prototype declarations.

There are still some failing cases that I need to work through. Thought I wonder how legit they are.

Expressions in a function declaration?

static string foo(bar() + ';');

Macro invocation return types. Should figure out a way to support this.

MACRO_CALL(int) macro_prefixed_func(){}

Function without the ( on the same line. I'm not sure if I want to support this one because it would make things have to be declared as a function by default instead of a variable. I would rather not pollute the function namespace if it isn't actually a function.

MACRO int
funcname2
()
{
}

Still a WIP, but if anyone wants to test it that would be appreciated :)

@ismell
Copy link
Author

ismell commented Mar 11, 2019

Looks like the preprocessor-practical-workarounds are causing issues. I don't think they are needed anymore. I'll play around with removing them.

@ismell
Copy link
Author

ismell commented Mar 11, 2019

So I fixed the highlighting for macro function calls and macros as types. I think it's looking pretty good except for the couple of edge cases I posted above.

This doesn't support disabling a block with `#if 0`. That requires that
we redefine `preprocessor-data-structures` since enum body has a different
context.
Raul E Rangel added 11 commits April 1, 2019 12:28
linux kernel defines __macro as a prprocessor macro for setting
attributes. I also found this style in other firmware type C code.
We don't want to gobble up actual function definitions.
Also made it so the assignment expressions highlight constants.
I think the function params block might need to be rewritten. It can't
handle the case: fn(int var __attribute__((unused).
@ismell
Copy link
Author

ismell commented Dec 16, 2019

Merged in upstream/master. Should be ready for review again.

@jrappen
Copy link
Contributor

jrappen commented Aug 18, 2021

@ismell maybe you could:

  • provide some numbers regarding performance changes using Tools > Build with ... > Syntax Tests - Performance?
  • re-merge upstream/master to re-run tests with the Build 4112 test binary

@michaelblyons
Copy link
Collaborator

Oh no! Merge conflicts. 😞

@ismell
Copy link
Author

ismell commented Nov 17, 2021

Yeah, I stopped working on this since Will told me he wanted to fix C++ and ObjC as well instead of just C. FWIW, I've been using this for 2 years now doing linux kernel, coreboot, and other firmware projects and it's pretty solid. If there is actual interest in merging this PR I can make some time to do some minor clean up.

@jrappen
Copy link
Contributor

jrappen commented Nov 18, 2021

That would be appreciated. Will isn't working for SublimeHQ anymore. The remaining team seems to be focused on other stuff (currently) and has assigned some collaborators to take care of syntaxes (for them). So this would be useful until somebody tackles a c languages rewrite using inheritance.

@ismell
Copy link
Author

ismell commented Nov 19, 2021

Oops, I should have tested the cpp syntax as well. I'll push a fix.

This file never conflicted in the chain of merges, so the merge
algorithm missed it somehow.

Signed-off-by: Raul E Rangel <[email protected]>
@ismell
Copy link
Author

ismell commented Nov 20, 2021

All tests are passing.

maximzakharov pushed a commit to maximzdev/Packages that referenced this pull request Nov 20, 2021
@ismell
Copy link
Author

ismell commented Dec 21, 2021

Can one of the new reviewers take a look?

@ismell
Copy link
Author

ismell commented Feb 8, 2022

Any hopes of getting this merged in? It will unblock others from improving upon it.

Copy link
Collaborator

@deathaxe deathaxe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe not enough package maintainers use C/C++ to feel a value in reviewing. There are other C/C++ related PRs pending.

Another reason might be the long pending idea of fully rewriting C family syntaxes from scratch to reduce duplication by ST4's inheritance feature and to fix all the open issues. The content of this PR would very likely be subject of heavy changes as well then.

I can't find major flaws with a shallow view at the sources, but don't use the syntaxes enough to judge the changes.

comment: Struct definition
set: struct-body
- match: '{{identifier}}'
scope: support.type.c
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that we use keyword.declaration for struct keyword, storage.type or storage.type.struct for user defined data types. But why do you distinguish declaration from definition? I'd call it entity.name.struct in both cases.

@@ -395,23 +437,43 @@ contexts:

global:
- include: early-expressions
- match: '^\s*(?=\w+)'
push: global-modifier
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Named contexts help with inheritance. So turning them into anonyomous ones feels like a step backward.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this was all written before ST4 when the names weren't really useful for debugging. I can pull it out.

@ismell
Copy link
Author

ismell commented Feb 9, 2022

Maybe not enough package maintainers use C/C++ to feel a value in reviewing. There are other C/C++ related PRs pending.

Right, there has been a lot of duplicated effort since this PR has sat for so long.

Another reason might be the long pending idea of fully rewriting C family syntaxes from scratch to reduce duplication by ST4's inheritance feature and to fix all the open issues. The content of this PR would very likely be subject of heavy changes as well then.

I agree, it could use some modernization, but getting all the test cases landed would be a huge benefit to aiding in the refactor.

Side note, I have no idea how to use Github's PR interface...

@deathaxe
Copy link
Collaborator

deathaxe commented Feb 9, 2022

Merging requires approval from at least 2 authorized contributors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[C] struct field is seen as a declaration inside a struct
7 participants