Skip to content

Comments

Refactoring of the Objective-C integration#5766

Closed
jacob-carlborg wants to merge 2 commits intodlang:masterfrom
jacob-carlborg:objc_refactor
Closed

Refactoring of the Objective-C integration#5766
jacob-carlborg wants to merge 2 commits intodlang:masterfrom
jacob-carlborg:objc_refactor

Conversation

@jacob-carlborg
Copy link
Contributor

I'm not sure if there's a better place for the functions in objc_glue.c.

@jacob-carlborg
Copy link
Contributor Author

@yebblies Refactoring of the Objective-C integration

@WalterBright
Copy link
Member

Can you give a brief description of the purpose of the refactoring? My cursory look at it is it appears to move ObjC logic out of objc modules and dispersing it into the rest of the front end. Why?

@jacob-carlborg
Copy link
Contributor Author

  • Currently the Objective-C integration is the only feature that is organized in this, slightly weird, way. With this refactoring it brings the feature up to the same level as the rest of the features
  • It doesn't work with cross-compiling which is important for LDC and might become important later for DMD as well. Currently all the Objective-C logic is removed at compile time if the target doesn't support Objective-C. The decision if Objective-C is supported or not need to occur at runtime and not compile time for cross-compiling to work
  • This all the functions with the weird names that was a result of being force to moved out logic that should have been inline in the rest of the code
  • It simplifies the design because objc.d, objc_stubs.d and objc_glue_stubs.c are all removed

I talked with Daniel and Iain during dconf about this and they both think that this is the right decision. I'm pretty sure that David agrees as well.

@jacob-carlborg
Copy link
Contributor Author

Hmm, seems I need to give this refactoring some more thought.

@jacob-carlborg jacob-carlborg force-pushed the objc_refactor branch 4 times, most recently from 9bb6cc8 to c495956 Compare May 12, 2016 08:37
@WalterBright
Copy link
Member

the only feature that is organized in this, slightly weird, way.

No, it's not. Header generation, json generation, ddoc, array ops, etc., are all factored out into separate modules. I would like to increase this sort of encapsulation, not decrease it. The main modules are already far too large and convoluted. Distributing the objc support among them will make things more convoluted and harder to understand.

Your other goals with this are good, but I do not believe they require distributing their contents around the rest of the code to achieve them.

@yebblies
Copy link
Contributor

Those other features are not adding new types, semantic processing, etc. We do not have a nice system for factoring out extern language support in dmd, and rather than making it clearer this layout just makes a mess. An entire function for two lines of code? It's a joke, and it doesn't work.

Either this is a first-class feature that deserves being integrated with the rest of dmd, or we should delete it.

@ibuclaw
Copy link
Member

ibuclaw commented May 12, 2016

Objective-C implementation is pretty dumb, I couldn't find a way to integrate it into GDC without #4813

@ibuclaw
Copy link
Member

ibuclaw commented May 12, 2016

Everything should have been put into an Objc namespace from the start. extern C functions are not a form of encapsulation.

@dnadlinger
Copy link
Contributor

Either this is a first-class feature that deserves being integrated with the rest of dmd, or we should delete it.

This.

@WalterBright
Copy link
Member

I am interested in proper encapsulation in order to reduce bugs and complexity. I am not interested in status symbols of where code is located. If objc is support is lacking (and I don't know if it is or is not) we can address that.

An entire function for two lines of code? It's a joke, and it doesn't work.

We have lots of functions in dmd that are a couple lines. They serve encapsulation purposes. As I recall you asked for a one-liner in root/outbuffer yesterday (a length() function). Besides, func.d is acquiring a number of functions with many more than 2 lines of code in them.

The front end, in my not-so-humble opinion, has major problems with lack of encapsulation. The lack of encapsulation is not a justification for even less encapsulation.

@dnadlinger
Copy link
Contributor

The frontend definitely suffers from a lot of encapsulation problems. The question is just whether "Objective-C support" is an useful unit of encapsulation.

@jacob-carlborg
Copy link
Contributor Author

If objc is support is lacking (and I don't know if it is or is not) we can address that

That's what I intend to work on. After the huge 12k+ lines of code PR which was the initial one, we decided to split it up in more manageable pieces. The rest of the Objective-C support has not been integrated yet. I talked with Daniel at dconf and we agreed that we should do this refactoring first (assuming this is what he had in mind).

@jacob-carlborg
Copy link
Contributor Author

"Objective-C support" is an useful unit of encapsulation

The full integration will touch many (most) parts of the compiler.

TypeInfoClassDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration
bool com; // true if this is a COM class (meaning it derives from IUnknown)
bool cpp; // true if this is a C++ interface
bool objc; // true if this is an Objective-C class/interface
Copy link
Member

Choose a reason for hiding this comment

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

Classes can only be com, cpp, or objc, but never two at once, right? These bool flags could be squashed into an enum later, perhaps.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, as far as I know. If it's objc it cannot be anything else at least. I guess a new PR would be a better fit for that.

Copy link
Contributor

Choose a reason for hiding this comment

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

IIRC there is at least one other way to mark a class as c++, it could do with some cleaning up.

@yebblies
Copy link
Contributor

I am interested in proper encapsulation in order to reduce bugs and complexity. I am not interested in status symbols of where code is located. If objc is support is lacking (and I don't know if it is or is not) we can address that.

My point is that unless we're planning to delete it (and therefore want it nicely isolated and easy to delete) then we should put the parts where they logically make sense - next to the handling of other extern types in dmd.

We have lots of functions in dmd that are a couple lines. They serve encapsulation purposes.

These functions do not serve encapsulation purposes. They are simply manually outlined chunks of code, that only have one caller. If your concern is that it might not be immediately obvious what they're for, then adding comments would be a less disruptive solution.

As I recall you asked for a one-liner in root/outbuffer yesterday (a length() function).

Because it give a name to a common pattern... there is a difference here.

The front end, in my not-so-humble opinion, has major problems with lack of encapsulation. The lack of encapsulation is not a justification for even less encapsulation.

I would agree with you if I thought that outlining objective-C support into another file improved encapsulation. Instead it just hides the code from people editing the related functions, and adds more false dependencies between modules.

Just look at how the line count changes...

@jacob-carlborg
Copy link
Contributor Author

BTW, I added documentation for most of the remaining functions.

Any reason why the Windows builds are still pending? It looks like it already has built twice on the other platforms.

@jacob-carlborg
Copy link
Contributor Author

I assume the Windows failures are not related: core.exception.AssertError@std\datetime.d(28135): TZName which is missing: Easter Island Standard Time

@Hackerpilot
Copy link
Contributor

@jacob-carlborg
Copy link
Contributor Author

@Hackerpilot thanks. Can we rerun the Windows tests?

@jacob-carlborg
Copy link
Contributor Author

Awesome, all tests are passing now.

void accept(Visitor *v) { v->visit(this); }
};

struct ObjcSelector
Copy link
Member

Choose a reason for hiding this comment

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

This should go in objc.d, there's no reason to make the fields and methods available throughout the compiler.

Symbol *sfunc = toSymbol(fd);

if (esel)
if (global.params.hasObjectiveC && esel)
Copy link
Member

Choose a reason for hiding this comment

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

I don't see how this is an improvement.

@WalterBright
Copy link
Member

I object to moving the code into func.d. I don't see how that improves anything. It reduces encapsulation by making the objc structs and members visible everywhere. I don't see how it makes anything easier to understand.

@jacob-carlborg
Copy link
Contributor Author

Could we please come to some form of agreement here. I would like to continue with the Objective-C integration but we need to decide how to structure the code.

@WalterBright
Copy link
Member

It simplifies the design because objc.d, objc_stubs.d and objc_glue_stubs.c are all removed

Removing files has no correlation with simplifying the design. But I see no reason why the ObjC logic cannot all be contained in objc.d, objc.h, and objc_glue.c. Then, one only has 3 files to look at to follow the ObjC design and figure out how it works.

@ibuclaw
Copy link
Member

ibuclaw commented May 15, 2016

Could we please come to some form of agreement here?

I would say that all data structures and functions prefixed with objc_ClassDeclaration and objc_FuncDeclaration should be first class citizens of their respective classes. Having an objc param in globals is not strictly necessary as we can put it elsewhere, such as in Objc::isSupported.

Other routines that hide the internals implementation should be in an Objc interface. Think how Target or Port works.

@yebblies
Copy link
Contributor

Having an objc param in globals is not strictly necessary as we can put it elsewhere, such as in Objc::isSupported.

I'd rather have global state in globals where possible.

@jacob-carlborg
Copy link
Contributor Author

jacob-carlborg commented May 31, 2016

Yet another PR that is stalled. @WalterBright you seem to be the only one against this change.

@WalterBright
Copy link
Member

Yes, I am against it, for reasons stated.

@jacob-carlborg
Copy link
Contributor Author

You want encapsulation, but way the current Objective-C integration is written doesn't increase encapsulation.

You mentioned that header generation, json generation and ddoc all have separate files. But the (I assume) do not need to modify the AST in anyway, they just read the AST and generate the output.

@jacob-carlborg
Copy link
Contributor Author

@WalterBright @yebblies what if we do a compromise. If I inline calls like objc_ClassDeclaration_semantic_PASSinit_LINKobjc and objc_callfunc_setupMethodSelector but keep code like struct ObjcSelector and validateSelector in the objc.d/c file?

@WalterBright
Copy link
Member

I don't understand what the proposed compromise does.

@jacob-carlborg
Copy link
Contributor Author

I don't understand what the proposed compromise does.

@WalterBright I have not changed any code yet in the PR. Currently the definition of objc_ClassDeclaration_semantic_PASSinit_LINKobjc looks like this [1] and is used here [2]. My proposed compromise is to move that function inline at the call site to look like this (in dclass.d):

if (sc.linkage == LINKobjc)
{
    if (global.params.hasObjectiveC)
        objc = true;
    else
        error("Objective-C classes are not supported for this target");
}

Other symbols like ObjcSelector would be moved back to objc.d. If you think it's ok that the objc_ClassDeclaration_semantic_PASSinit_LINKobjc function is inline at the call site I can update the PR to show how it would look like with the rest of the symbols.

[1] https://github.com/dlang/dmd/blob/master/src/objc.d#L143
[2] https://github.com/dlang/dmd/blob/master/src/dclass.d#L500-L501

@WalterBright
Copy link
Member

Thanks for the explanation. I honestly don't see the point of making this change. How does it improve things?

@jacob-carlborg
Copy link
Contributor Author

Thanks for the explanation. I honestly don't see the point of making this change. How does it improve things?

@WalterBright it would remove the awkward functions like objc_ClassDeclaration_semantic_PASSinit_LINKobjc. They're awkward because they should really not be separate functions. They're only called once and doesn't provide any form of abstraction.

@wilzbach
Copy link
Contributor

wilzbach commented Aug 7, 2016

JC: Could we please come to some form of agreement here. I would like to continue with the Objective-C integration but we need to decide how to structure the code.
[...]
JC: Yet another PR that is stalled. @WalterBright you seem to be the only one against this change.
WB: Yes, I am against it, for reasons stated.

@jacob-carlborg did you ever come to an agreement or is this still stalled?

@ibuclaw
Copy link
Member

ibuclaw commented Aug 7, 2016

This is still stalled as far as I know. Which is a shame I think it's in the interest of everyone to fix this interface.

@jacob-carlborg
Copy link
Contributor Author

@wilzbach it's still stalled. Therefore the rest of Objective-C integration is stalled.

@jacob-carlborg jacob-carlborg deleted the objc_refactor branch April 2, 2017 11:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants