-
Notifications
You must be signed in to change notification settings - Fork 285
[TG-1190] Parse generic information of outer classes #1616
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -110,6 +110,12 @@ class java_generic_parametert:public reference_typet | |
| return type_variables().front(); | ||
| } | ||
|
|
||
| type_variablet &type_variable_ref() | ||
| { | ||
| PRECONDITION(!type_variables().empty()); | ||
| return const_cast<type_variablet &>(type_variables().front()); | ||
| } | ||
|
|
||
| private: | ||
| typedef std::vector<type_variablet> type_variablest; | ||
| const type_variablest &type_variables() const | ||
|
|
@@ -313,6 +319,65 @@ inline const typet &java_generic_class_type_bound(size_t index, const typet &t) | |
| return gen_type.subtype(); | ||
| } | ||
|
|
||
| /// Type to hold a Java class that is implicitly generic, e.g., an inner | ||
| /// class of a generic outer class or a derived class of a generic base | ||
| /// class. Extends the java class type. | ||
| class java_implicitly_generic_class_typet : public java_class_typet | ||
| { | ||
| public: | ||
| typedef std::vector<java_generic_parametert> implicit_generic_typest; | ||
|
|
||
| explicit java_implicitly_generic_class_typet( | ||
| const java_class_typet &class_type, | ||
| const implicit_generic_typest &generic_types) | ||
| : java_class_typet(class_type) | ||
| { | ||
| set(ID_C_java_implicitly_generic_class_type, true); | ||
| for(const auto &type : generic_types) | ||
| { | ||
| implicit_generic_types().push_back(type); | ||
| } | ||
| } | ||
|
|
||
| const implicit_generic_typest &implicit_generic_types() const | ||
| { | ||
| return ( | ||
|
||
| const implicit_generic_typest | ||
| &)(find(ID_implicit_generic_types).get_sub()); | ||
| } | ||
|
|
||
| implicit_generic_typest &implicit_generic_types() | ||
| { | ||
| return ( | ||
| implicit_generic_typest &)(add(ID_implicit_generic_types).get_sub()); | ||
| } | ||
| }; | ||
|
|
||
| /// \param type: the type to check | ||
| /// \return true if type is a implicitly generic java class type | ||
| inline bool is_java_implicitly_generic_class_type(const typet &type) | ||
|
||
| { | ||
| return type.get_bool(ID_C_java_implicitly_generic_class_type); | ||
| } | ||
|
|
||
| /// \param type: the type to check | ||
| /// \return cast of type to java_generics_class_typet | ||
| inline const java_implicitly_generic_class_typet & | ||
| to_java_implicitly_generic_class_type(const java_class_typet &type) | ||
| { | ||
| PRECONDITION(is_java_implicitly_generic_class_type(type)); | ||
| return static_cast<const java_implicitly_generic_class_typet &>(type); | ||
| } | ||
|
|
||
| /// \param type: source type | ||
| /// \return cast of type into a java class type with generics | ||
| inline java_implicitly_generic_class_typet & | ||
| to_java_implicitly_generic_class_type(java_class_typet &type) | ||
| { | ||
| PRECONDITION(is_java_implicitly_generic_class_type(type)); | ||
| return static_cast<java_implicitly_generic_class_typet &>(type); | ||
| } | ||
|
|
||
| /// An exception that is raised for unsupported class signature. | ||
| /// Currently we do not parse multiple bounds. | ||
| class unsupported_java_class_signature_exceptiont:public std::logic_error | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| class GenericClassWithInnerClasses<T> | ||
| { | ||
| class Inner { | ||
| T t1; | ||
| Generic<T> t2; | ||
|
|
||
| class InnerInner { | ||
| T tt1; | ||
| Generic<Generic<T>> tt2; | ||
| } | ||
| } | ||
|
|
||
| class GenericInner<U> { | ||
| T gt1; | ||
| GenericTwoParam<T,U> gt2; | ||
|
|
||
| class GenericInnerInner<V>{ | ||
|
|
||
| } | ||
| } | ||
|
|
||
| static class StaticInner<U>{ | ||
| U st; | ||
| } | ||
|
|
||
| Inner f1; | ||
| Inner.InnerInner f2; | ||
| GenericInner<Integer> f3; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this need to be called? Are you trying to achieve something in particular? Normally you wouldn't want to pass a base class object to the derived class constructor, and call the superclass' constructor like this, to my understanding. If you leave it be, without calling it, the superclass' default constructor should be called automatically, which I'm assuming should do some sensible initialisation.
Another problem this can create is that you can pass a subclass of
java_class_typetto this constructor and it will essentially clobber internal state that doesn't match thejava_class_typetwhich can cause some very nasty bugs in the future.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After further discussion, this will stay as it is as it's not causing the nasty bug mentioned above.