-
Notifications
You must be signed in to change notification settings - Fork 593
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
Fix Instabilities and Unnecessary Sorting in the Generated Code #3315
Changes from 5 commits
bcf95eb
9ade3bd
8f0a440
91faa63
156b3fe
9af91c3
cbc0efc
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 |
---|---|---|
|
@@ -3053,7 +3053,6 @@ Slice::InterfaceDef::allBases() const | |
{ | ||
InterfaceList result = _bases; | ||
result.sort(containedCompare); | ||
result.unique(containedEqual); | ||
for (const auto& p : _bases) | ||
{ | ||
result.merge(p->allBases(), containedCompare); | ||
|
@@ -3584,7 +3583,6 @@ Slice::Exception::createDataMember( | |
checkIdentifier(name); // Don't return here -- we create the data member anyway. | ||
|
||
// Check whether any bases have defined a member with the same name already. | ||
ExceptionList bl = allBases(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dead variable. |
||
for (const auto& q : allBases()) | ||
{ | ||
ContainedList contents; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -561,8 +561,6 @@ Gen::TypesVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p) | |
} | ||
|
||
ExceptionList throws = op->throws(); | ||
throws.sort(); | ||
throws.unique(); | ||
Comment on lines
-564
to
-565
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We no longer sort our exception specifications, because there's no point to calling |
||
if (throws.size() == 1) | ||
{ | ||
out << " throws " << getUnqualified(throws.front(), scope); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -216,15 +216,10 @@ namespace | |
} | ||
else | ||
{ | ||
throws.sort(); | ||
throws.unique(); | ||
|
||
// | ||
// Arrange exceptions into most-derived to least-derived order. If we don't | ||
// do this, a base exception handler can appear before a derived exception | ||
// handler, causing compiler warnings and resulting in the base exception | ||
// being marshaled instead of the derived exception. | ||
// | ||
throws.sort(Slice::DerivedToBaseCompare()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note that in the languages, we do still sort them by derived-to-base. We do this in all compilers except 'ice2slice' (where it's correct not to) and 'slice2php', 'slice2py', and 'slice2rb'. |
||
|
||
C << "[](const " << getUnqualified("::Ice::UserException&", scope) << " ex)"; | ||
|
@@ -233,9 +228,8 @@ namespace | |
C << sb; | ||
C << nl << "ex.ice_throw();"; | ||
C << eb; | ||
// | ||
|
||
// Generate a catch block for each legal user exception. | ||
// | ||
for (const auto& ex : throws) | ||
{ | ||
C << nl << "catch(const " << getUnqualified(fixKwd(ex->scoped()), scope) << "&)"; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -317,26 +317,31 @@ Slice::CsVisitor::writeUnmarshalDataMember( | |
void | ||
Slice::CsVisitor::writeInheritedOperations(const InterfaceDefPtr& p) | ||
{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it would be cleaner to eliminate this helper function (called once) and just call allOperations on the interface in the calling function. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't want to make it too hard to review the changes, but you're right. |
||
InterfaceList bases = p->bases(); | ||
if (!bases.empty()) | ||
OperationList allBaseOps; | ||
for (const auto& base : p->bases()) | ||
{ | ||
OperationList allOps; | ||
for (InterfaceList::const_iterator q = bases.begin(); q != bases.end(); ++q) | ||
{ | ||
OperationList tmp = (*q)->allOperations(); | ||
allOps.splice(allOps.end(), tmp); | ||
} | ||
allOps.sort(); | ||
allOps.unique(); | ||
for (OperationList::const_iterator i = allOps.begin(); i != allOps.end(); ++i) | ||
for (const auto& baseOp : base->allOperations()) | ||
{ | ||
string retS; | ||
vector<string> params, args; | ||
string ns = getNamespace(p); | ||
string name = getDispatchParams(*i, retS, params, args, ns); | ||
_out << sp << nl << "public abstract " << retS << " " << name << spar << params << epar << ';'; | ||
// It's possible to get the same operation name through diamond inheritance. | ||
// But we only want one 'copy' of each operation in our list, to avoid generating duplicate methods. | ||
if (find_if( | ||
allBaseOps.begin(), | ||
allBaseOps.end(), | ||
[name = baseOp->name()](const auto& other) { return other->name() == name; }) == allBaseOps.end()) | ||
{ | ||
allBaseOps.push_back(baseOp); | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Simplified this whole block. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After a review comment from Bernard, I just inlined the simplified version of this function. |
||
} | ||
|
||
for (const auto& op : allBaseOps) | ||
{ | ||
string retS; | ||
vector<string> params, args; | ||
string ns = getNamespace(p); | ||
string name = getDispatchParams(op, retS, params, args, ns); | ||
_out << sp << nl << "public abstract " << retS << " " << name << spar << params << epar << ';'; | ||
} | ||
} | ||
|
||
void | ||
|
@@ -2698,18 +2703,6 @@ Slice::Gen::HelperVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p) | |
|
||
ParameterList outParams = op->outParameters(); | ||
|
||
ExceptionList throws = op->throws(); | ||
throws.sort(); | ||
throws.unique(); | ||
|
||
// | ||
// Arrange exceptions into most-derived to least-derived order. If we don't | ||
// do this, a base exception handler can appear before a derived exception | ||
// handler, causing compiler warnings and resulting in the base exception | ||
// being marshaled instead of the derived exception. | ||
// | ||
throws.sort(Slice::DerivedToBaseCompare()); | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dead code. |
||
string context = getEscapedParamName(op, "context"); | ||
|
||
_out << sp; | ||
|
@@ -2789,21 +2782,14 @@ Slice::Gen::HelperVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p) | |
|
||
string returnTypeS = resultType(op, ns); | ||
|
||
ExceptionList throws = op->throws(); | ||
throws.sort(); | ||
throws.unique(); | ||
|
||
// | ||
// Arrange exceptions into most-derived to least-derived order. If we don't | ||
// do this, a base exception handler can appear before a derived exception | ||
// handler, causing compiler warnings and resulting in the base exception | ||
// being marshaled instead of the derived exception. | ||
// | ||
ExceptionList throws = op->throws(); | ||
throws.sort(Slice::DerivedToBaseCompare()); | ||
|
||
// | ||
// Write the public Async method. | ||
// | ||
_out << sp; | ||
_out << nl << "public global::System.Threading.Tasks.Task"; | ||
if (!returnTypeS.empty()) | ||
|
@@ -2910,12 +2896,10 @@ Slice::Gen::HelperVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p) | |
_out << nl << "throw ex;"; | ||
_out << eb; | ||
|
||
// | ||
// Generate a catch block for each legal user exception. | ||
// | ||
for (ExceptionList::const_iterator i = throws.begin(); i != throws.end(); ++i) | ||
for (const auto& thrown : throws) | ||
{ | ||
_out << nl << "catch(" << getUnqualified(*i, ns) << ")"; | ||
_out << nl << "catch(" << getUnqualified(thrown, ns) << ")"; | ||
_out << sb; | ||
_out << nl << "throw;"; | ||
_out << eb; | ||
|
@@ -3257,7 +3241,6 @@ Slice::Gen::DispatcherVisitor::writeDispatch(const InterfaceDefPtr& p) | |
string scoped = p->scoped(); | ||
string ns = getNamespace(p); | ||
|
||
OperationList ops = p->operations(); | ||
OperationList allOps = p->allOperations(); | ||
if (!allOps.empty()) | ||
{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1302,8 +1302,6 @@ Slice::JavaVisitor::writeDispatch(Output& out, const InterfaceDefPtr& p) | |
const bool amd = p->hasMetadata("amd") || op->hasMetadata("amd"); | ||
|
||
ExceptionList throws = op->throws(); | ||
throws.sort(); | ||
throws.unique(); | ||
|
||
out << sp; | ||
writeServantDocComment(out, op, package, dc, amd); | ||
|
@@ -3956,8 +3954,6 @@ Slice::Gen::ProxyVisitor::ProxyVisitor(const string& dir) : JavaVisitor(dir) {} | |
bool | ||
Slice::Gen::ProxyVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p) | ||
{ | ||
const OperationList ops = p->allOperations(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another dead variable... |
||
|
||
string name = p->name(); | ||
InterfaceList bases = p->bases(); | ||
string package = getPackage(p); | ||
|
@@ -4209,16 +4205,11 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) | |
} | ||
const vector<string> args = getInArgs(p); | ||
|
||
ExceptionList throws = p->throws(); | ||
throws.sort(); | ||
throws.unique(); | ||
|
||
// | ||
// Arrange exceptions into most-derived to least-derived order. If we don't | ||
// do this, a base exception handler can appear before a derived exception | ||
// handler, causing compiler warnings and resulting in the base exception | ||
// being marshaled instead of the derived exception. | ||
// | ||
ExceptionList throws = p->throws(); | ||
throws.sort(Slice::DerivedToBaseCompare()); | ||
|
||
const string contextParamName = getEscapedParamName(p, "context"); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1456,13 +1456,14 @@ Slice::Gen::TypesVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p) | |
} | ||
_out << ","; | ||
|
||
// | ||
// User exceptions. | ||
// | ||
// Arrange exceptions into most-derived to least-derived order. If we don't | ||
// do this, a base exception handler can appear before a derived exception | ||
// handler, causing compiler warnings and resulting in the base exception | ||
// being marshaled instead of the derived exception. | ||
ExceptionList throws = op->throws(); | ||
throws.sort(); | ||
throws.unique(); | ||
throws.sort(Slice::DerivedToBaseCompare()); | ||
|
||
if (throws.empty()) | ||
{ | ||
_out << " "; | ||
|
@@ -2035,7 +2036,6 @@ Slice::Gen::TypeScriptImportVisitor::visitInterfaceDefStart(const InterfaceDefPt | |
} | ||
|
||
// Add imports required for operation parameters and return types. | ||
const OperationList operationList = p->allOperations(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dead. |
||
for (const auto& op : p->allOperations()) | ||
{ | ||
auto ret = dynamic_pointer_cast<Contained>(op->returnType()); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1713,7 +1713,6 @@ CodeVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p) | |
const string scoped = p->scoped(); | ||
const string abs = getAbsolute(p); | ||
InterfaceList bases = p->bases(); | ||
const OperationList allOps = p->allOperations(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dead. |
||
|
||
// | ||
// Generate proxy class. | ||
|
@@ -2198,16 +2197,12 @@ CodeVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p) | |
for (OperationList::const_iterator q = ops.begin(); q != ops.end(); ++q) | ||
{ | ||
OperationPtr op = *q; | ||
ExceptionList exceptions = op->throws(); | ||
exceptions.sort(); | ||
exceptions.unique(); | ||
|
||
// | ||
// Arrange exceptions into most-derived to least-derived order. If we don't | ||
// do this, a base exception handler can appear before a derived exception | ||
// handler, causing compiler warnings and resulting in the base exception | ||
// being marshaled instead of the derived exception. | ||
// | ||
ExceptionList exceptions = op->throws(); | ||
exceptions.sort(Slice::DerivedToBaseCompare()); | ||
|
||
if (!exceptions.empty()) | ||
|
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.
It is illegal to list the same interface multiple times in an inheritance list, so there's no point to calling
unique
on_bases
here.