Code::Blocks Forums

Developer forums (C::B DEVELOPMENT STRICTLY!) => Development => Topic started by: killerbot on December 28, 2012, 07:33:25 pm

Title: code completion enhancement request
Post by: killerbot on December 28, 2012, 07:33:25 pm
recently the code completion was enhanced by recognizing declaration in if / for/while constructs, this is great.

I would like to take it one step small further : range based for :

* say you have a container ==> vector/list/... "container"

Code

for (auto foo : container)

for (const auto foo : container)

for (auto& foo : container)

for (const auto& foo : container)


foo is of the value type (disregarding const and references here) of the container.

Example :
std::vector<MyType> container;   ===> foo is of type MyType

So the syntax seems simple in the "for( ... : ...)", the challenge probably is, do we know the 'container' its value type ? And can we deduce this second level of determination ?


What do our CC experts think ?
Title: Re: code completion enhancement request
Post by: oBFusCATed on December 28, 2012, 08:11:44 pm
So the syntax seems simple in the "for( ... : ...)", the challenge probably is, do we know the 'container' its value type ? And can we deduce this second level of determination ?
Read the standard, I'm sure it explains how the type is deduced. ::)
Title: Re: code completion enhancement request
Post by: ptDev on December 29, 2012, 12:35:44 am
recently the code completion was enhanced by recognizing declaration in if / for/while constructs, this is great.

I would like to take it one step small further : range based for :

* say you have a container ==> vector/list/... "container"

Code

for (auto foo : container)

for (const auto foo : container)

for (auto& foo : container)

for (const auto& foo : container)


foo is of the value type (disregarding const and references here) of the container.

Example :
std::vector<MyType> container;   ===> foo is of type MyType

So the syntax seems simple in the "for( ... : ...)", the challenge probably is, do we know the 'container' its value type ? And can we deduce this second level of determination ?


What do our CC experts think ?


In your examples, the only issue for CC is that "auto" uses template type deduction.
I don't think CC can handle that yet.

Try explicitly declaring the type in those range based loops, and CC won't have a problem.
Title: Re: code completion enhancement request
Post by: killerbot on December 29, 2012, 08:51:31 am
I know that, that's why I call it a challenge.
The auto keyword is there to make life easier, and don't repeat types anymore.

So the question is, is our CC able to do such a thing with let's +- minimal effort. That's the extra level is was talking about, (by limiting the complexity), looking at what is at the right hand side of the ":" and then get the type of it. And once CC knows what's the thing on the right hand side (vector<MyType>) can it then easily determine that "MyType" ? )

So still some static analysis, by avoiding turning our CC into a compiler.

FOr that I am gonna start another thread, but our CC is going to have to use compiler backends, I think there was already an experiemtn with clang ?

But in this topic I just want to see if this particular use case might be easier to achieve ...
Title: Re: code completion enhancement request
Post by: ptDev on January 01, 2013, 04:55:54 pm
I know that, that's why I call it a challenge.
The auto keyword is there to make life easier, and don't repeat types anymore.

So the question is, is our CC able to do such a thing with let's +- minimal effort. That's the extra level is was talking about, (by limiting the complexity), looking at what is at the right hand side of the ":" and then get the type of it. And once CC knows what's the thing on the right hand side (vector<MyType>) can it then easily determine that "MyType" ? )

I thought of that before. If CC was to able to parametrize some classes by known types, then this use case would be simplified, yes. This change alone, however, does require quite a bit of refactoring as it is.

Quote
So still some static analysis, by avoiding turning our CC into a compiler.

FOr that I am gonna start another thread, but our CC is going to have to use compiler backends, I think there was already an experiemtn with clang ?

But in this topic I just want to see if this particular use case might be easier to achieve ...

I remember reading in the forum about someone experimenting with a Clang-based CC, but never heard of any results since...
Title: Re: code completion enhancement request
Post by: p2rkw on January 01, 2013, 09:36:25 pm
Code
for (auto foo : container)
Keep in mind that instead of container there might be expression. And "auto" have different meaning in c++03.

As you can see here: http://en.cppreference.com/w/cpp/language/range-for , loop declaration:
Code
for ( range_declaration : range_expression) loop_statement
is equals to
Code
    auto && __range = range_expression ;
    auto __begin = __range.begin(); // or begin(__range);
    auto __end = __range.end();      // or end(__range);
    for (;__begin != __end; ++__begin) {
        range_declaration = *__begin;
        loop_statement
    }

and declaration
Code
auto foo = expression
is logically equals to
Code
decltype(expression) foo = expression

To implement decltype parser might use NativeParser::AI to find out type of expression (all required tokens should be already in tree), but actually ParserThread doesn't have access to NativeParser object.
Title: Re: code completion enhancement request
Post by: p2rkw on March 30, 2013, 03:55:34 am
I have tried to implement this feature, result here: http://imgur.com/WTWdDPz
but it seems CC cant find "operator*" in std::vector::const_iterator, so it doesn't work for std::vector and probably for all templates.

@developers: can m_NativeParser pointer be pass down to ParserThread?
Title: Re: code completion enhancement request
Post by: ollydbg on July 17, 2013, 03:27:28 am
@developers: can m_NativeParser pointer be pass down to ParserThread?
Why do you want to do that, you want let the ParserThread to access NativeParser class?

I think the control level is: (the most left is the most hight control level)

CodeCompletion class -> NativeParser -> Parser -> ParserThread -> Tokenizer
Title: Re: code completion enhancement request
Post by: p2rkw on July 17, 2013, 10:46:33 pm
Quote
CodeCompletion class -> NativeParser -> Parser -> ParserThread -> Tokenizer
Thats true, but:
source file is parsed in ParserThread, and TokenTree is build there. So what can parser do when "auto" or "decltype" token occurs?
My idea was to detect real type of variable defined as "decltype" using  NativeParserBase::ResolveActualType or somethin like that. All tokens required to detect real type of "auto" variable or function probably will be already in tree.

Lets assume you have access to nativeParser in ParserThread, so you can write something like this in DoParse:
Code
if(token == ParserConsts::dectype)
{
  m_Tokenizer.GetToken(); // eat "decltype"
  m_Tokenizer.GetToken(); // eat "("
  string type = m_Tokenizer.GetToken();
  //release lock here
  TokenIdxSet result;
  nativeParser->resolveActualType(m_tree, type, ..., result) // or AI( ..., type, result)
  //lock again
  Token *newToken = DoAddToken(tkVariable, token, smallTokenizer.GetLineNumber());
  newToken->m_FullType = tree[result.begin()]->m_FullType;
}
Title: Re: code completion enhancement request
Post by: ollydbg on July 18, 2013, 03:51:41 am
I understand your idea.
Code
size_t NativeParserBase::ResolveActualType(TokenTree*         tree,
                                           wxString           searchText,
                                           const TokenIdxSet& searchScope,
                                           TokenIdxSet&       result)
See the third parameter, it is the searchScope, which is a C++ exposed scope(context). It can be introduced by
1, using directive
2, class inheritance
3, scope exposed in its include files
4, other cases
So, how do you get them?

The dirty thing is C++ grammar is context sensitive, it is hard to solve which type when the Parserthread meet a decltype.

Another thing is:
Is it possible to introduce a Token, which has type string named "undefined" or "lasy", then when NativeParser need to show tooltip or code suggestion, it can solve them. (I mean solve the types later when needed)

Final thought, type solving is related to semantic check stage, but our CC's parser mostly do a syntax check, so if we need precise information, a full parser (Clang or GCC) is needed.