zeroc-ice 3.8.1 → 3.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. checksums.yaml +4 -4
  2. data/dist/IceRuby/Operation.cpp +22 -6
  3. data/dist/ice/cpp/include/Ice/Config.h +2 -2
  4. data/dist/ice/cpp/include/Ice/LocalExceptions.h +21 -0
  5. data/dist/ice/cpp/include/Ice/OutputStream.h +7 -5
  6. data/dist/ice/cpp/include/generated/Ice/BuiltinSequences.h +2 -2
  7. data/dist/ice/cpp/include/generated/Ice/Context.h +2 -2
  8. data/dist/ice/cpp/include/generated/Ice/EndpointTypes.h +2 -2
  9. data/dist/ice/cpp/include/generated/Ice/Identity.h +2 -2
  10. data/dist/ice/cpp/include/generated/Ice/Locator.h +9 -11
  11. data/dist/ice/cpp/include/generated/Ice/LocatorRegistry.h +2 -2
  12. data/dist/ice/cpp/include/generated/Ice/Metrics.h +7 -7
  13. data/dist/ice/cpp/include/generated/Ice/OperationMode.h +2 -2
  14. data/dist/ice/cpp/include/generated/Ice/Process.h +2 -2
  15. data/dist/ice/cpp/include/generated/Ice/PropertiesAdmin.h +2 -2
  16. data/dist/ice/cpp/include/generated/Ice/PropertyDict.h +2 -2
  17. data/dist/ice/cpp/include/generated/Ice/RemoteLogger.h +2 -2
  18. data/dist/ice/cpp/include/generated/Ice/ReplyStatus.h +8 -4
  19. data/dist/ice/cpp/include/generated/Ice/Router.h +7 -7
  20. data/dist/ice/cpp/include/generated/Ice/SliceChecksumDict.h +2 -2
  21. data/dist/ice/cpp/include/generated/Ice/Version.h +2 -2
  22. data/dist/ice/cpp/include/generated/IceDiscovery/Lookup.h +2 -2
  23. data/dist/ice/cpp/include/generated/IceLocatorDiscovery/Lookup.h +2 -2
  24. data/dist/ice/cpp/src/Ice/CollocatedRequestHandler.cpp +5 -3
  25. data/dist/ice/cpp/src/Ice/ConnectionI.cpp +27 -9
  26. data/dist/ice/cpp/src/Ice/ConnectionI.h +1 -1
  27. data/dist/ice/cpp/src/Ice/FileUtil.cpp +3 -67
  28. data/dist/ice/cpp/src/Ice/FileUtil.h +0 -3
  29. data/dist/ice/cpp/src/Ice/IPEndpointI.cpp +4 -0
  30. data/dist/ice/cpp/src/Ice/IncomingRequest.cpp +1 -1
  31. data/dist/ice/cpp/src/Ice/InputStream.cpp +28 -15
  32. data/dist/ice/cpp/src/Ice/LocalExceptions.cpp +6 -0
  33. data/dist/ice/cpp/src/Ice/OutgoingAsync.cpp +1 -1
  34. data/dist/ice/cpp/src/Ice/OutgoingResponse.cpp +127 -127
  35. data/dist/ice/cpp/src/Ice/OutgoingResponseInternal.h +21 -0
  36. data/dist/ice/cpp/src/Ice/OutputStream.cpp +46 -61
  37. data/dist/ice/cpp/src/Ice/PropertyNames.cpp +2 -1
  38. data/dist/ice/cpp/src/Ice/ProxyFunctions.cpp +4 -4
  39. data/dist/ice/cpp/src/Ice/Reference.cpp +15 -15
  40. data/dist/ice/cpp/src/Ice/ReferenceFactory.cpp +16 -13
  41. data/dist/ice/cpp/src/Ice/ResourceConfig.h +2 -2
  42. data/dist/ice/cpp/src/Ice/SSL/OpenSSLEngine.cpp +12 -11
  43. data/dist/ice/cpp/src/Ice/SSL/OpenSSLEngine.h +1 -2
  44. data/dist/ice/cpp/src/Ice/SSL/SSLEndpointI.cpp +1 -1
  45. data/dist/ice/cpp/src/Ice/SSL/SSLEngine.h +1 -4
  46. data/dist/ice/cpp/src/Ice/SSL/SchannelEngine.cpp +50 -43
  47. data/dist/ice/cpp/src/Ice/SSL/SchannelEngine.h +1 -5
  48. data/dist/ice/cpp/src/Ice/SSL/SchannelTransceiverI.cpp +9 -0
  49. data/dist/ice/cpp/src/Ice/SSL/SecureTransportEngine.cpp +107 -14
  50. data/dist/ice/cpp/src/Ice/SSL/SecureTransportEngine.h +7 -2
  51. data/dist/ice/cpp/src/Ice/TcpEndpointI.cpp +2 -2
  52. data/dist/ice/cpp/src/Ice/UdpEndpointI.cpp +2 -2
  53. data/dist/ice/cpp/src/Ice/WSAcceptor.cpp +8 -3
  54. data/dist/ice/cpp/src/Ice/WSAcceptor.h +5 -1
  55. data/dist/ice/cpp/src/Ice/WSEndpoint.cpp +45 -2
  56. data/dist/ice/cpp/src/Ice/WSTransceiver.cpp +118 -7
  57. data/dist/ice/cpp/src/Ice/WSTransceiver.h +12 -1
  58. data/dist/ice/cpp/src/Ice/generated/BuiltinSequences.cpp +2 -2
  59. data/dist/ice/cpp/src/Ice/generated/Context.cpp +2 -2
  60. data/dist/ice/cpp/src/Ice/generated/EndpointTypes.cpp +2 -2
  61. data/dist/ice/cpp/src/Ice/generated/Identity.cpp +2 -2
  62. data/dist/ice/cpp/src/Ice/generated/Locator.cpp +2 -2
  63. data/dist/ice/cpp/src/Ice/generated/LocatorRegistry.cpp +2 -2
  64. data/dist/ice/cpp/src/Ice/generated/Metrics.cpp +2 -2
  65. data/dist/ice/cpp/src/Ice/generated/OperationMode.cpp +2 -2
  66. data/dist/ice/cpp/src/Ice/generated/Process.cpp +2 -2
  67. data/dist/ice/cpp/src/Ice/generated/PropertiesAdmin.cpp +2 -2
  68. data/dist/ice/cpp/src/Ice/generated/PropertyDict.cpp +2 -2
  69. data/dist/ice/cpp/src/Ice/generated/RemoteLogger.cpp +2 -2
  70. data/dist/ice/cpp/src/Ice/generated/ReplyStatus.cpp +4 -2
  71. data/dist/ice/cpp/src/Ice/generated/Router.cpp +2 -2
  72. data/dist/ice/cpp/src/Ice/generated/SliceChecksumDict.cpp +2 -2
  73. data/dist/ice/cpp/src/Ice/generated/Version.cpp +2 -2
  74. data/dist/ice/cpp/src/IceDiscovery/generated/Lookup.cpp +2 -2
  75. data/dist/ice/cpp/src/IceLocatorDiscovery/generated/Lookup.cpp +2 -2
  76. data/dist/ice/cpp/src/Slice/DocCommentParser.cpp +6 -6
  77. data/dist/ice/cpp/src/Slice/DocCommentParser.h +4 -2
  78. data/dist/ice/cpp/src/Slice/MetadataValidation.cpp +24 -5
  79. data/dist/ice/cpp/src/Slice/MetadataValidation.h +3 -2
  80. data/dist/ice/cpp/src/Slice/Parser.cpp +117 -77
  81. data/dist/ice/cpp/src/Slice/Parser.h +19 -4
  82. data/dist/ice/cpp/src/Slice/Preprocessor.cpp +75 -19
  83. data/dist/ice/cpp/src/Slice/Preprocessor.h +0 -1
  84. data/dist/ice/cpp/src/Slice/SliceUtil.cpp +6 -58
  85. data/dist/ice/cpp/src/Slice/Util.h +0 -3
  86. data/dist/ice/cpp/src/slice2rb/RubyUtil.cpp +10 -8
  87. data/dist/ice/cpp/src/slice2rb/RubyUtil.h +10 -13
  88. data/dist/ice/slice/Ice/Identity.ice +3 -0
  89. data/dist/ice/slice/Ice/Locator.ice +6 -5
  90. data/dist/ice/slice/Ice/LocatorRegistry.ice +3 -0
  91. data/dist/ice/slice/Ice/Metrics.ice +1 -1
  92. data/dist/ice/slice/Ice/OperationMode.ice +8 -0
  93. data/dist/ice/slice/Ice/Process.ice +3 -0
  94. data/dist/ice/slice/Ice/ReplyStatus.ice +13 -0
  95. data/dist/lib/Glacier2/Metrics.rb +1 -1
  96. data/dist/lib/Glacier2/PermissionsVerifier.rb +3 -3
  97. data/dist/lib/Glacier2/Router.rb +8 -8
  98. data/dist/lib/Glacier2/SSLInfo.rb +1 -1
  99. data/dist/lib/Glacier2/Session.rb +15 -15
  100. data/dist/lib/Ice/BuiltinSequences.rb +1 -1
  101. data/dist/lib/Ice/Context.rb +1 -1
  102. data/dist/lib/Ice/EndpointTypes.rb +1 -1
  103. data/dist/lib/Ice/Identity.rb +1 -1
  104. data/dist/lib/Ice/LocalExceptions.rb +3 -0
  105. data/dist/lib/Ice/Locator.rb +5 -5
  106. data/dist/lib/Ice/LocatorRegistry.rb +4 -4
  107. data/dist/lib/Ice/Metrics.rb +7 -7
  108. data/dist/lib/Ice/OperationMode.rb +1 -1
  109. data/dist/lib/Ice/Process.rb +3 -3
  110. data/dist/lib/Ice/PropertiesAdmin.rb +4 -4
  111. data/dist/lib/Ice/PropertyDict.rb +1 -1
  112. data/dist/lib/Ice/ProxyFunctions.rb +8 -4
  113. data/dist/lib/Ice/RemoteLogger.rb +6 -6
  114. data/dist/lib/Ice/ReplyStatus.rb +3 -2
  115. data/dist/lib/Ice/Router.rb +5 -5
  116. data/dist/lib/Ice/SliceChecksumDict.rb +1 -1
  117. data/dist/lib/Ice/Version.rb +1 -1
  118. data/dist/lib/IceBox/ServiceManager.rb +8 -8
  119. data/dist/lib/IceGrid/Admin.rb +83 -83
  120. data/dist/lib/IceGrid/Descriptor.rb +1 -1
  121. data/dist/lib/IceGrid/Exception.rb +1 -1
  122. data/dist/lib/IceGrid/FileParser.rb +2 -2
  123. data/dist/lib/IceGrid/Registry.rb +13 -13
  124. data/dist/lib/IceGrid/Session.rb +6 -6
  125. data/dist/lib/IceGrid/UserAccountMapper.rb +2 -2
  126. data/dist/lib/IceStorm/IceStorm.rb +16 -16
  127. data/dist/lib/IceStorm/Metrics.rb +1 -1
  128. data/ice.gemspec +1 -1
  129. metadata +2 -1
@@ -60,9 +60,9 @@ DocCommentFormatter::formatCode(const string& rawText)
60
60
  }
61
61
 
62
62
  string
63
- DocCommentFormatter::formatParamRef(const string& param)
63
+ DocCommentFormatter::formatParamRef(const string& paramName, const ParameterPtr&)
64
64
  {
65
- return formatCode(param);
65
+ return formatCode(paramName);
66
66
  }
67
67
 
68
68
  string
@@ -397,19 +397,19 @@ namespace
397
397
  // Extract the parameter's name and check if matches an operation parameter.
398
398
  // If it does, make sure to use the mapped name instead of the Slice name.
399
399
  string parameterName = line.substr(nameStart, nameEnd - nameStart);
400
+ ParameterPtr parameterPtr = nullptr;
400
401
  if (auto operationTarget = dynamic_pointer_cast<Operation>(p))
401
402
  {
402
- bool doesParameterExist = false;
403
403
  for (const auto& param : operationTarget->parameters())
404
404
  {
405
405
  if (param->name() == parameterName)
406
406
  {
407
407
  parameterName = param->mappedName();
408
- doesParameterExist = true;
408
+ parameterPtr = param;
409
409
  break;
410
410
  }
411
411
  }
412
- if (!doesParameterExist)
412
+ if (parameterPtr == nullptr)
413
413
  {
414
414
  string opName = operationTarget->name();
415
415
  string msg = "No parameter named '" + parameterName + "' exists on operation '" + opName + "'";
@@ -422,7 +422,7 @@ namespace
422
422
  }
423
423
 
424
424
  // Format the parameter's name and insert it in-place of the original '@p name'.
425
- const string formattedParamName = formatter.formatParamRef(parameterName);
425
+ const string formattedParamName = formatter.formatParamRef(parameterName, parameterPtr);
426
426
  line.erase(pos, nameEnd - pos);
427
427
  line.insert(pos, formattedParamName);
428
428
 
@@ -27,12 +27,14 @@ namespace Slice
27
27
  [[nodiscard]] virtual std::string formatCode(const std::string& rawText);
28
28
 
29
29
  /// This function is called by the doc-comment parser to map '@p' tags into each language's syntax.
30
- /// @param param The mapped name of the parameter that is being referenced.
30
+ /// @param paramName If @p paramPtr is non-null, this is the mapped name of the parameter being referenced.
31
+ /// Otherwise, this is the identifier after '@p', taken verbatim from the doc-comment.
32
+ /// @param paramPtr A pointer to the parameter that is being referenced, or `nullptr` if it doesn't exist.
31
33
  /// @return A properly formatted parameters reference in the target language. The doc-comment parser will
32
34
  /// replace the entire "@p <rawParamName>" string with the returned value.
33
35
  //
34
36
  // By default we just emit the parameter's name in code formatting.
35
- [[nodiscard]] virtual std::string formatParamRef(const std::string& param);
37
+ [[nodiscard]] virtual std::string formatParamRef(const std::string& paramName, const ParameterPtr& paramPtr);
36
38
 
37
39
  /// This function is called by the doc-comment parser to map doc-links ('{@link <rawLink>}') into each
38
40
  /// language's syntax.
@@ -67,7 +67,7 @@ Slice::misappliedMetadataMessage(const MetadataPtr& metadata, const SyntaxTreeBa
67
67
  }
68
68
 
69
69
  void
70
- Slice::validateMetadata(const UnitPtr& p, string_view prefix, map<string, MetadataInfo> knownMetadata)
70
+ Slice::validateMetadata(const UnitPtr& unit, string_view prefix, map<string, MetadataInfo> knownMetadata)
71
71
  {
72
72
  // We want to perform all the metadata validation in the same pass, to keep all the diagnostics in order.
73
73
  // So, we add all the language-agnostic metadata validation into the provided list.
@@ -126,6 +126,25 @@ Slice::validateMetadata(const UnitPtr& p, string_view prefix, map<string, Metada
126
126
  };
127
127
  knownMetadata.emplace("marshaled-result", std::move(marshaledResultInfo));
128
128
 
129
+ // "oneway"
130
+ MetadataInfo onewayInfo = {
131
+ .validOn = {typeid(Operation)},
132
+ .acceptedArgumentKind = MetadataArgumentKind::NoArguments,
133
+ .extraValidation = [](const MetadataPtr&, const SyntaxTreeBasePtr& q) -> optional<string>
134
+ {
135
+ if (auto op = dynamic_pointer_cast<Operation>(q))
136
+ {
137
+ if (op->returnsData())
138
+ {
139
+ return "'oneway' metadata cannot be applied to an operation that has a return type, out parameters,"
140
+ " or an exception specification";
141
+ }
142
+ }
143
+ return nullopt;
144
+ },
145
+ };
146
+ knownMetadata.emplace("oneway", std::move(onewayInfo));
147
+
129
148
  // "suppress-warning"
130
149
  MetadataInfo suppressWarningInfo = {
131
150
  .validOn = {typeid(Unit)},
@@ -137,7 +156,7 @@ Slice::validateMetadata(const UnitPtr& p, string_view prefix, map<string, Metada
137
156
 
138
157
  // Then we pass this list off the internal visitor, which performs the heavy lifting.
139
158
  auto visitor = MetadataVisitor(prefix, std::move(knownMetadata));
140
- p->visit(&visitor);
159
+ unit->visit(&visitor);
141
160
  }
142
161
 
143
162
  MetadataVisitor::MetadataVisitor(string_view language, map<string, MetadataInfo> knownMetadata)
@@ -148,11 +167,11 @@ MetadataVisitor::MetadataVisitor(string_view language, map<string, MetadataInfo>
148
167
  }
149
168
 
150
169
  bool
151
- MetadataVisitor::visitUnitStart(const UnitPtr& p)
170
+ MetadataVisitor::visitUnitStart(const UnitPtr& unit)
152
171
  {
153
- DefinitionContextPtr dc = p->findDefinitionContext(p->topLevelFile());
172
+ DefinitionContextPtr dc = unit->findDefinitionContext(unit->topLevelFile());
154
173
  assert(dc);
155
- dc->setMetadata(validate(dc->getMetadata(), p));
174
+ dc->setMetadata(validate(dc->getMetadata(), unit));
156
175
  return true;
157
176
  }
158
177
 
@@ -95,12 +95,13 @@ namespace Slice
95
95
  std::string misappliedMetadataMessage(const MetadataPtr& metadata, const SyntaxTreeBasePtr& p);
96
96
 
97
97
  /// Validates all the metadata in the provided Unit against a map of known metadata.
98
- /// @param p The unit who's metadata should be validated.
98
+ /// @param unit The unit whose metadata should be validated.
99
99
  /// @param prefix Which language's metadata should be validated. Any metadata that starts with a different
100
100
  /// language prefix than this one will be ignored. Note that metadata without any language prefix
101
101
  /// (i.e. parser metadata) is always checked.
102
102
  /// @param knownMetadata A map containing the directives that should be validated, and information describing
103
103
  /// the various constraints and conditions that should be upheld for it and its arguments.
104
- void validateMetadata(const UnitPtr& p, std::string_view prefix, std::map<std::string, MetadataInfo> knownMetadata);
104
+ void
105
+ validateMetadata(const UnitPtr& unit, std::string_view prefix, std::map<std::string, MetadataInfo> knownMetadata);
105
106
  }
106
107
  #endif
@@ -48,7 +48,7 @@ namespace
48
48
  DataMemberList filterOrderedOptionalDataMembers(const DataMemberList& members)
49
49
  {
50
50
  DataMemberList result;
51
- copy_if(members.begin(), members.end(), back_inserter(result), [](const auto& p) { return p->optional(); });
51
+ copy_if(members.begin(), members.end(), back_inserter(result), [](const auto& p) { return p->isOptional(); });
52
52
  result.sort(compareTag<DataMemberPtr>);
53
53
  return result;
54
54
  }
@@ -111,6 +111,58 @@ namespace
111
111
  }
112
112
  return true;
113
113
  }
114
+
115
+ /// Checks an identifier for illegal syntax and reports any errors that are present.
116
+ bool reportIllegalSuffixOrUnderscore(const string& identifier)
117
+ {
118
+ // check whether the identifier is scoped
119
+ size_t scopeIndex = identifier.rfind("::");
120
+ bool isScoped = scopeIndex != string::npos;
121
+ string name;
122
+ if (isScoped)
123
+ {
124
+ name = identifier.substr(scopeIndex + 2); // Only check the unscoped identifier for syntax
125
+ }
126
+ else
127
+ {
128
+ name = identifier;
129
+ }
130
+
131
+ assert(!name.empty());
132
+ bool isValid = true;
133
+
134
+ // check the identifier for reserved suffixes
135
+ static const string suffixBlacklist[] = {"Helper", "Holder", "Prx", "Ptr"};
136
+ for (const auto& i : suffixBlacklist)
137
+ {
138
+ if (name.find(i, name.size() - i.size()) != string::npos)
139
+ {
140
+ currentUnit->error("illegal identifier '" + name + "': '" + i + "' suffix is reserved");
141
+ isValid = false;
142
+ break;
143
+ }
144
+ }
145
+
146
+ // check the identifier for illegal underscores
147
+ size_t index = name.find('_');
148
+ if (index == 0)
149
+ {
150
+ currentUnit->error("illegal leading underscore in identifier '" + name + "'");
151
+ isValid = false;
152
+ }
153
+ else if (name.rfind('_') == (name.size() - 1))
154
+ {
155
+ currentUnit->error("illegal trailing underscore in identifier '" + name + "'");
156
+ isValid = false;
157
+ }
158
+ else if (name.find("__") != string::npos)
159
+ {
160
+ currentUnit->error("illegal double underscore in identifier '" + name + "'");
161
+ isValid = false;
162
+ }
163
+
164
+ return isValid;
165
+ }
114
166
  }
115
167
 
116
168
  namespace Slice
@@ -563,7 +615,7 @@ Slice::Builtin::kindAsString() const
563
615
  return builtinTable[_kind];
564
616
  }
565
617
 
566
- optional<Slice::Builtin::Kind>
618
+ optional<Builtin::Kind>
567
619
  Slice::Builtin::kindFromString(string_view str)
568
620
  {
569
621
  // Object is an alias for Value that we don't put in the builtinTable.
@@ -749,7 +801,7 @@ Slice::Contained::getMetadataArgs(string_view directive) const
749
801
  return nullopt;
750
802
  }
751
803
 
752
- std::optional<FormatType>
804
+ optional<FormatType>
753
805
  Slice::Contained::parseFormatMetadata() const
754
806
  {
755
807
  if (auto metadata = getMetadataArgs("format"))
@@ -1595,9 +1647,9 @@ Slice::Container::lookupInterfaceDef(const string& identifier, bool emitErrors)
1595
1647
  TypePtr resolvedType = lookupType(identifier);
1596
1648
  if (resolvedType)
1597
1649
  {
1598
- if (auto interface = dynamic_pointer_cast<InterfaceDecl>(resolvedType))
1650
+ if (auto interfaceDecl = dynamic_pointer_cast<InterfaceDecl>(resolvedType))
1599
1651
  {
1600
- if (InterfaceDefPtr def = interface->definition())
1652
+ if (InterfaceDefPtr def = interfaceDecl->definition())
1601
1653
  {
1602
1654
  return def;
1603
1655
  }
@@ -2147,13 +2199,13 @@ Slice::Module::getTopLevelModule() const
2147
2199
  return parent->getTopLevelModule();
2148
2200
  }
2149
2201
  // Reaching here means that this module is at the top-level! We return it.
2150
- return dynamic_pointer_cast<Module>(const_pointer_cast<Container>(shared_from_this()));
2202
+ return static_pointer_cast<Module>(const_pointer_cast<Container>(shared_from_this()));
2151
2203
  }
2152
2204
 
2153
2205
  void
2154
2206
  Slice::Module::visit(ParserVisitor* visitor)
2155
2207
  {
2156
- auto self = dynamic_pointer_cast<Module>(shared_from_this());
2208
+ auto self = static_pointer_cast<Module>(shared_from_this());
2157
2209
  if (visitor->visitModuleStart(self))
2158
2210
  {
2159
2211
  visitContents(visitor);
@@ -2310,7 +2362,7 @@ Slice::ClassDef::createDataMember(
2310
2362
  // Validate the tag.
2311
2363
  for (const auto& q : dataMembers())
2312
2364
  {
2313
- if (q->optional() && tag == q->tag())
2365
+ if (q->isOptional() && tag == q->tag())
2314
2366
  {
2315
2367
  unit()->error("tag for optional data member '" + name + "' is already in use");
2316
2368
  break;
@@ -2428,7 +2480,7 @@ Slice::ClassDef::kindOf() const
2428
2480
  void
2429
2481
  Slice::ClassDef::visit(ParserVisitor* visitor)
2430
2482
  {
2431
- auto self = dynamic_pointer_cast<ClassDef>(shared_from_this());
2483
+ auto self = static_pointer_cast<ClassDef>(shared_from_this());
2432
2484
  if (visitor->visitClassDefStart(self))
2433
2485
  {
2434
2486
  visitContents(visitor);
@@ -2615,7 +2667,7 @@ Slice::InterfaceDecl::addPartition(
2615
2667
  // list of lists, with each member list containing the operation
2616
2668
  // names defined by the interfaces in each partition.
2617
2669
  //
2618
- Slice::InterfaceDecl::StringPartitionList
2670
+ InterfaceDecl::StringPartitionList
2619
2671
  Slice::InterfaceDecl::toStringPartitionList(const GraphPartitionList& partitions)
2620
2672
  {
2621
2673
  StringPartitionList spl;
@@ -2738,8 +2790,9 @@ Slice::InterfaceDef::createOperation(
2738
2790
  break;
2739
2791
  }
2740
2792
  }
2741
- // Check the operations of the Object pseudo-interface.
2742
- if (!checkBaseOperationNames(name, {"ice_id", "ice_ids", "ice_ping", "ice_isA"}))
2793
+
2794
+ // Check the operations of the Object pseudo-interface unless we're generating code for Object itself.
2795
+ if (scoped() != "::Ice::Object" && !checkBaseOperationNames(name, {"ice_id", "ice_ids", "ice_ping", "ice_isA"}))
2743
2796
  {
2744
2797
  hasConflictingIdentifier = true;
2745
2798
  }
@@ -2827,6 +2880,24 @@ Slice::InterfaceDef::operations() const
2827
2880
 
2828
2881
  OperationList
2829
2882
  Slice::InterfaceDef::allOperations() const
2883
+ {
2884
+ OperationList result = allInheritedOperations();
2885
+
2886
+ for (const auto& q : operations())
2887
+ {
2888
+ if (none_of(
2889
+ result.begin(),
2890
+ result.end(),
2891
+ [name = q->name()](const auto& other) { return other->name() == name; }))
2892
+ {
2893
+ result.push_back(q);
2894
+ }
2895
+ }
2896
+ return result;
2897
+ }
2898
+
2899
+ OperationList
2900
+ Slice::InterfaceDef::allInheritedOperations() const
2830
2901
  {
2831
2902
  OperationList result;
2832
2903
  for (const auto& p : _bases)
@@ -2842,17 +2913,6 @@ Slice::InterfaceDef::allOperations() const
2842
2913
  }
2843
2914
  }
2844
2915
  }
2845
-
2846
- for (const auto& q : operations())
2847
- {
2848
- if (none_of(
2849
- result.begin(),
2850
- result.end(),
2851
- [name = q->name()](const auto& other) { return other->name() == name; }))
2852
- {
2853
- result.push_back(q);
2854
- }
2855
- }
2856
2916
  return result;
2857
2917
  }
2858
2918
 
@@ -2865,7 +2925,7 @@ Slice::InterfaceDef::kindOf() const
2865
2925
  void
2866
2926
  Slice::InterfaceDef::visit(ParserVisitor* visitor)
2867
2927
  {
2868
- auto self = dynamic_pointer_cast<InterfaceDef>(shared_from_this());
2928
+ auto self = static_pointer_cast<InterfaceDef>(shared_from_this());
2869
2929
  if (visitor->visitInterfaceDefStart(self))
2870
2930
  {
2871
2931
  visitContents(visitor);
@@ -2915,7 +2975,7 @@ Slice::InterfaceDef::InterfaceDef(const ContainerPtr& container, const string& n
2915
2975
  // ----------------------------------------------------------------------
2916
2976
 
2917
2977
  InterfaceDefPtr
2918
- Slice::Operation::interface() const
2978
+ Slice::Operation::parentInterface() const
2919
2979
  {
2920
2980
  return dynamic_pointer_cast<InterfaceDef>(_container);
2921
2981
  }
@@ -2947,7 +3007,7 @@ Slice::Operation::mode() const
2947
3007
  bool
2948
3008
  Slice::Operation::hasMarshaledResult() const
2949
3009
  {
2950
- InterfaceDefPtr intf = interface();
3010
+ InterfaceDefPtr intf = parentInterface();
2951
3011
  assert(intf);
2952
3012
  if (intf->hasMetadata("marshaled-result") || hasMetadata("marshaled-result"))
2953
3013
  {
@@ -2996,7 +3056,7 @@ Slice::Operation::createParameter(const string& name, const TypePtr& type, bool
2996
3056
  {
2997
3057
  for (const auto& param : parameters())
2998
3058
  {
2999
- if (param->optional() && param->tag() == tag)
3059
+ if (param->isOptional() && param->tag() == tag)
3000
3060
  {
3001
3061
  unit()->error(msg);
3002
3062
  break;
@@ -3028,12 +3088,11 @@ ParameterList
3028
3088
  Slice::Operation::inParameters() const
3029
3089
  {
3030
3090
  ParameterList result;
3031
- for (const auto& p : _contents)
3091
+ for (const auto& p : parameters())
3032
3092
  {
3033
- ParameterPtr q = dynamic_pointer_cast<Parameter>(p);
3034
- if (q && !q->isOutParam())
3093
+ if (!p->isOutParam())
3035
3094
  {
3036
- result.push_back(q);
3095
+ result.push_back(p);
3037
3096
  }
3038
3097
  }
3039
3098
  return result;
@@ -3046,7 +3105,7 @@ Slice::Operation::sortedInParameters() const
3046
3105
  ParameterList required, optional;
3047
3106
  for (const auto& param : inParameters())
3048
3107
  {
3049
- if (param->optional())
3108
+ if (param->isOptional())
3050
3109
  {
3051
3110
  optional.push_back(param);
3052
3111
  }
@@ -3068,12 +3127,11 @@ ParameterList
3068
3127
  Slice::Operation::outParameters() const
3069
3128
  {
3070
3129
  ParameterList result;
3071
- for (const auto& p : _contents)
3130
+ for (const auto& p : parameters())
3072
3131
  {
3073
- ParameterPtr q = dynamic_pointer_cast<Parameter>(p);
3074
- if (q && q->isOutParam())
3132
+ if (p->isOutParam())
3075
3133
  {
3076
- result.push_back(q);
3134
+ result.push_back(p);
3077
3135
  }
3078
3136
  }
3079
3137
  return result;
@@ -3122,7 +3180,7 @@ Slice::Operation::sortedReturnAndOutParameters(const string& returnName)
3122
3180
  // First sort each parameter into either 'required' or 'optional'.
3123
3181
  for (auto i = required.begin(); i != required.end();)
3124
3182
  {
3125
- if ((*i)->optional())
3183
+ if ((*i)->isOptional())
3126
3184
  {
3127
3185
  optional.push_back(*i);
3128
3186
  i = required.erase(i);
@@ -3193,9 +3251,9 @@ Slice::Operation::setExceptionList(const ExceptionList& exceptions)
3193
3251
  bool
3194
3252
  Slice::Operation::sendsClasses() const
3195
3253
  {
3196
- for (const auto& i : parameters())
3254
+ for (const auto& i : inParameters())
3197
3255
  {
3198
- if (!i->isOutParam() && i->type()->usesClasses())
3256
+ if (i->type()->usesClasses())
3199
3257
  {
3200
3258
  return true;
3201
3259
  }
@@ -3212,9 +3270,9 @@ Slice::Operation::returnsClasses() const
3212
3270
  return true;
3213
3271
  }
3214
3272
 
3215
- for (const auto& i : parameters())
3273
+ for (const auto& i : outParameters())
3216
3274
  {
3217
- if (i->isOutParam() && i->type()->usesClasses())
3275
+ if (i->type()->usesClasses())
3218
3276
  {
3219
3277
  return true;
3220
3278
  }
@@ -3225,25 +3283,7 @@ Slice::Operation::returnsClasses() const
3225
3283
  bool
3226
3284
  Slice::Operation::returnsData() const
3227
3285
  {
3228
- TypePtr t = returnType();
3229
- if (t)
3230
- {
3231
- return true;
3232
- }
3233
-
3234
- for (const auto& i : parameters())
3235
- {
3236
- if (i->isOutParam())
3237
- {
3238
- return true;
3239
- }
3240
- }
3241
-
3242
- if (!throws().empty())
3243
- {
3244
- return true;
3245
- }
3246
- return false;
3286
+ return returnsAnyValues() || !throws().empty();
3247
3287
  }
3248
3288
 
3249
3289
  bool
@@ -3270,7 +3310,7 @@ Slice::Operation::sendsOptionals() const
3270
3310
  {
3271
3311
  for (const auto& i : inParameters())
3272
3312
  {
3273
- if (i->optional())
3313
+ if (i->isOptional())
3274
3314
  {
3275
3315
  return true;
3276
3316
  }
@@ -3283,7 +3323,7 @@ Slice::Operation::receivesOptionals() const
3283
3323
  {
3284
3324
  for (const auto& i : outParameters())
3285
3325
  {
3286
- if (i->optional())
3326
+ if (i->isOptional())
3287
3327
  {
3288
3328
  return true;
3289
3329
  }
@@ -3291,10 +3331,10 @@ Slice::Operation::receivesOptionals() const
3291
3331
  return returnIsOptional();
3292
3332
  }
3293
3333
 
3294
- std::optional<FormatType>
3334
+ optional<FormatType>
3295
3335
  Slice::Operation::format() const
3296
3336
  {
3297
- std::optional<FormatType> format = parseFormatMetadata();
3337
+ optional<FormatType> format = parseFormatMetadata();
3298
3338
  if (!format)
3299
3339
  {
3300
3340
  ContainedPtr cont = dynamic_pointer_cast<Contained>(container());
@@ -3313,7 +3353,7 @@ Slice::Operation::kindOf() const
3313
3353
  void
3314
3354
  Slice::Operation::visit(ParserVisitor* visitor)
3315
3355
  {
3316
- visitor->visitOperation(dynamic_pointer_cast<Operation>(shared_from_this()));
3356
+ visitor->visitOperation(static_pointer_cast<Operation>(shared_from_this()));
3317
3357
  }
3318
3358
 
3319
3359
  void
@@ -3419,7 +3459,7 @@ Slice::Exception::createDataMember(
3419
3459
  // Validate the tag.
3420
3460
  for (const auto& q : dataMembers())
3421
3461
  {
3422
- if (q->optional() && tag == q->tag())
3462
+ if (q->isOptional() && tag == q->tag())
3423
3463
  {
3424
3464
  unit()->error("tag for optional data member '" + name + "' is already in use");
3425
3465
  break;
@@ -3549,7 +3589,7 @@ Slice::Exception::kindOf() const
3549
3589
  void
3550
3590
  Slice::Exception::visit(ParserVisitor* visitor)
3551
3591
  {
3552
- auto self = dynamic_pointer_cast<Exception>(shared_from_this());
3592
+ auto self = static_pointer_cast<Exception>(shared_from_this());
3553
3593
  if (visitor->visitExceptionStart(self))
3554
3594
  {
3555
3595
  visitContents(visitor);
@@ -3704,7 +3744,7 @@ Slice::Struct::kindOf() const
3704
3744
  void
3705
3745
  Slice::Struct::visit(ParserVisitor* visitor)
3706
3746
  {
3707
- auto self = dynamic_pointer_cast<Struct>(shared_from_this());
3747
+ auto self = static_pointer_cast<Struct>(shared_from_this());
3708
3748
  if (visitor->visitStructStart(self))
3709
3749
  {
3710
3750
  visitContents(visitor);
@@ -4038,7 +4078,7 @@ Slice::Enum::kindOf() const
4038
4078
  void
4039
4079
  Slice::Enum::visit(ParserVisitor* visitor)
4040
4080
  {
4041
- visitor->visitEnum(dynamic_pointer_cast<Enum>(shared_from_this()));
4081
+ visitor->visitEnum(static_pointer_cast<Enum>(shared_from_this()));
4042
4082
  }
4043
4083
 
4044
4084
  void
@@ -4179,7 +4219,7 @@ Slice::Parameter::setIsOutParam()
4179
4219
  }
4180
4220
 
4181
4221
  bool
4182
- Slice::Parameter::optional() const
4222
+ Slice::Parameter::isOptional() const
4183
4223
  {
4184
4224
  return _optional;
4185
4225
  }
@@ -4226,7 +4266,7 @@ Slice::DataMember::type() const
4226
4266
  }
4227
4267
 
4228
4268
  bool
4229
- Slice::DataMember::optional() const
4269
+ Slice::DataMember::isOptional() const
4230
4270
  {
4231
4271
  return _optional;
4232
4272
  }
@@ -4268,7 +4308,7 @@ Slice::DataMember::DataMember(
4268
4308
  bool isOptional,
4269
4309
  int32_t tag,
4270
4310
  SyntaxTreeBasePtr defaultValueType,
4271
- std::optional<string> defaultValueString)
4311
+ optional<string> defaultValueString)
4272
4312
  : Contained(container, name),
4273
4313
  _type(std::move(type)),
4274
4314
  _optional(isOptional),
@@ -4403,7 +4443,7 @@ Slice::Unit::currentLine() const
4403
4443
  }
4404
4444
 
4405
4445
  int
4406
- Slice::Unit::setCurrentFile(std::string currentFile, int lineNumber)
4446
+ Slice::Unit::setCurrentFile(string currentFile, int lineNumber)
4407
4447
  {
4408
4448
  assert(!currentFile.empty());
4409
4449
 
@@ -4689,12 +4729,12 @@ Slice::Unit::findContents(const string& scopedName) const
4689
4729
  }
4690
4730
 
4691
4731
  void
4692
- Slice::Unit::addTypeId(int32_t compactId, const std::string& typeId)
4732
+ Slice::Unit::addTypeId(int32_t compactId, const string& typeId)
4693
4733
  {
4694
4734
  _typeIds.insert(make_pair(compactId, typeId));
4695
4735
  }
4696
4736
 
4697
- std::string
4737
+ string
4698
4738
  Slice::Unit::getTypeId(int32_t compactId) const
4699
4739
  {
4700
4740
  auto p = _typeIds.find(compactId);
@@ -4784,7 +4824,7 @@ Slice::Unit::destroy()
4784
4824
  void
4785
4825
  Slice::Unit::visit(ParserVisitor* visitor)
4786
4826
  {
4787
- auto self = dynamic_pointer_cast<Unit>(shared_from_this());
4827
+ auto self = static_pointer_cast<Unit>(shared_from_this());
4788
4828
  if (visitor->visitUnitStart(self))
4789
4829
  {
4790
4830
  visitContents(visitor);
@@ -4813,7 +4853,7 @@ Slice::Unit::createBuiltin(Builtin::Kind kind)
4813
4853
  {
4814
4854
  return p->second;
4815
4855
  }
4816
- auto builtin = make_shared<Builtin>(dynamic_pointer_cast<Unit>(shared_from_this()), kind);
4856
+ auto builtin = make_shared<Builtin>(static_pointer_cast<Unit>(shared_from_this()), kind);
4817
4857
  _builtins.insert(make_pair(kind, builtin));
4818
4858
  return builtin;
4819
4859
  }
@@ -692,8 +692,15 @@ namespace Slice
692
692
  Idempotent = 2
693
693
  };
694
694
 
695
- Operation(const ContainerPtr&, const std::string&, TypePtr, bool, std::int32_t, Mode);
696
- [[nodiscard]] InterfaceDefPtr interface() const;
695
+ Operation(
696
+ const ContainerPtr& container,
697
+ const std::string& name,
698
+ TypePtr returnType,
699
+ bool returnIsOptional,
700
+ std::int32_t returnTag,
701
+ Mode mode);
702
+
703
+ [[nodiscard]] InterfaceDefPtr parentInterface() const;
697
704
  [[nodiscard]] TypePtr returnType() const;
698
705
  [[nodiscard]] bool returnIsOptional() const;
699
706
  [[nodiscard]] std::int32_t returnTag() const;
@@ -740,12 +747,19 @@ namespace Slice
740
747
 
741
748
  [[nodiscard]] ExceptionList throws() const;
742
749
  void setExceptionList(const ExceptionList& exceptions);
750
+
751
+ /// Returns true if this operation uses class types in any of its in parameters.
743
752
  [[nodiscard]] bool sendsClasses() const;
753
+
754
+ /// Returns true if this operation uses class types in its return type, or any of its out parameters.
744
755
  [[nodiscard]] bool returnsClasses() const;
756
+
757
+ /// Returns true if this operation has any out parameters, a non-void return type, or can throw any exceptions.
745
758
  [[nodiscard]] bool returnsData() const;
746
759
 
747
760
  /// Returns true if this operation has any out parameters or a non-void return type.
748
761
  [[nodiscard]] bool returnsAnyValues() const;
762
+
749
763
  /// Returns true if this operation's output parameters, plus any non-void return type, is greater than 1.
750
764
  [[nodiscard]] bool returnsMultipleValues() const;
751
765
 
@@ -792,6 +806,7 @@ namespace Slice
792
806
  [[nodiscard]] InterfaceList allBases() const;
793
807
  [[nodiscard]] OperationList operations() const;
794
808
  [[nodiscard]] OperationList allOperations() const;
809
+ [[nodiscard]] OperationList allInheritedOperations() const;
795
810
  [[nodiscard]] std::string kindOf() const final;
796
811
  void visit(ParserVisitor* visitor) final;
797
812
 
@@ -1019,7 +1034,7 @@ namespace Slice
1019
1034
  [[nodiscard]] TypePtr type() const;
1020
1035
  [[nodiscard]] bool isOutParam() const;
1021
1036
  void setIsOutParam();
1022
- [[nodiscard]] bool optional() const;
1037
+ [[nodiscard]] bool isOptional() const;
1023
1038
  [[nodiscard]] std::int32_t tag() const;
1024
1039
  [[nodiscard]] std::string kindOf() const final;
1025
1040
 
@@ -1048,7 +1063,7 @@ namespace Slice
1048
1063
  SyntaxTreeBasePtr defaultValueType,
1049
1064
  std::optional<std::string> defaultValueString);
1050
1065
  [[nodiscard]] TypePtr type() const;
1051
- [[nodiscard]] bool optional() const;
1066
+ [[nodiscard]] bool isOptional() const;
1052
1067
  [[nodiscard]] std::int32_t tag() const;
1053
1068
 
1054
1069
  // defaultValue() and defaultValueType() are either both null (no default value) or both non-null.