Skip to content

Commit

Permalink
[gbc] Fully qualify names in cpp apply overloads.
Browse files Browse the repository at this point in the history
Fixes #202, "gbc cpp generates ambiguous
references when a struct and enum val share a name"

Closes #204
  • Loading branch information
Ted Stein committed Jul 14, 2016
1 parent c6d33de commit d1efb60
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 98 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ different versioning scheme, following the Haskell community's
* Validate default value of type aliases
* Generated types will used `= default` move constructors if possible. This
results in many generated types having `noexcept` move constructors.
* Fix a bug where, if a Bond namespace contained a struct and an enum value with
the same name, generated C++ would contain ambiguous references.
[Issue #202](https://github.com/Microsoft/bond/issues/202)

### C++ ###

Expand Down
27 changes: 15 additions & 12 deletions compiler/src/Language/Bond/Codegen/Cpp/ApplyOverloads.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Prelude
import Data.Text.Lazy (Text)
import Text.Shakespeare.Text
import Language.Bond.Syntax.Types
import Language.Bond.Codegen.TypeMapping
import Language.Bond.Codegen.Util

-- | Protocol data type is used to specify what protocols the @Apply@ function
Expand All @@ -22,20 +23,22 @@ data Protocol =


-- Apply overloads
applyOverloads :: [Protocol] -> Text -> Text -> Declaration -> Text
applyOverloads protocols attr body Struct {..} | null declParams = [lt|
applyOverloads :: [Protocol] -> MappingContext -> Text -> Text -> Declaration -> Text
applyOverloads protocols cpp attr body s@Struct {..} | null declParams = [lt|
//
// Overloads of Apply function with common transforms for #{declName}.
// These overloads will be selected using argument dependent lookup
// before bond::Apply function templates.
//
#{attr}bool Apply(const bond::To<#{declName}>& transform,
const bond::bonded<#{declName}>& value)#{body}
#{attr}bool Apply(const bond::To< #{qualifiedName}>& transform,
const bond::bonded< #{qualifiedName}>& value)#{body}

#{attr}bool Apply(const bond::InitSchemaDef& transform,
const #{declName}& value)#{body}
const #{qualifiedName}& value)#{body}
#{newlineSep 1 applyOverloads' protocols}|]
where
qualifiedName = getDeclTypeName cpp s

applyOverloads' p = [lt|#{deserialization p}
#{serialization serializer p}
#{serialization marshaler p}|]
Expand All @@ -44,22 +47,22 @@ applyOverloads protocols attr body Struct {..} | null declParams = [lt|
marshaler = "Marshaler" :: String

deserialization Protocol {..} = [lt|
#{attr}bool Apply(const bond::To<#{declName}>& transform,
const bond::bonded<#{declName}, #{protocolReader}&>& value)#{body}
#{attr}bool Apply(const bond::To< #{qualifiedName}>& transform,
const bond::bonded< #{qualifiedName}, #{protocolReader}&>& value)#{body}

#{attr}bool Apply(const bond::To<#{declName}>& transform,
#{attr}bool Apply(const bond::To< #{qualifiedName}>& transform,
const bond::bonded<void, #{protocolReader}&>& value)#{body}|]

serialization transform Protocol {..} = [lt|
#{attr}bool Apply(const bond::#{transform}<#{protocolWriter} >& transform,
const #{declName}& value)#{body}
const #{qualifiedName}& value)#{body}

#{attr}bool Apply(const bond::#{transform}<#{protocolWriter} >& transform,
const bond::bonded<#{declName}>& value)#{body}
const bond::bonded< #{qualifiedName}>& value)#{body}
#{newlineSep 1 (transcoding transform) protocols}|]
where
transcoding transform' Protocol {protocolReader = fromReader} = [lt|
#{attr}bool Apply(const bond::#{transform'}<#{protocolWriter} >& transform,
const bond::bonded<#{declName}, #{fromReader}&>& value)#{body}|]
const bond::bonded< #{qualifiedName}, #{fromReader}&>& value)#{body}|]

applyOverloads _ _ _ _ = mempty
applyOverloads _ _ _ _ _ = mempty
2 changes: 1 addition & 1 deletion compiler/src/Language/Bond/Codegen/Cpp/Apply_cpp.hs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ apply_cpp protocols cpp file _imports declarations = ("_apply.cpp", [lt|
#include "#{file}_reflection.h"

#{CPP.openNamespace cpp}
#{newlineSepEnd 1 (applyOverloads protocols attr body) declarations}
#{newlineSepEnd 1 (applyOverloads protocols cpp attr body) declarations}
#{CPP.closeNamespace cpp}
|])
where
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/Language/Bond/Codegen/Cpp/Apply_h.hs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ apply_h protocols attribute cpp file imports declarations = ("_apply.h", [lt|
#{newlineSep 0 includeImport imports}

#{CPP.openNamespace cpp}
#{newlineSepEnd 1 (applyOverloads protocols attr semi) declarations}
#{newlineSepEnd 1 (applyOverloads protocols cpp attr semi) declarations}
#{CPP.closeNamespace cpp}
|])
where
Expand Down
84 changes: 42 additions & 42 deletions compiler/tests/generated/apply/basic_types_apply.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,230 +10,230 @@ namespace tests
// These overloads will be selected using argument dependent lookup
// before bond::Apply function templates.
//
bool Apply(const bond::To<BasicTypes>& transform,
const bond::bonded<BasicTypes>& value)
bool Apply(const bond::To< ::tests::BasicTypes>& transform,
const bond::bonded< ::tests::BasicTypes>& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::InitSchemaDef& transform,
const BasicTypes& value)
const ::tests::BasicTypes& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::To<BasicTypes>& transform,
const bond::bonded<BasicTypes, bond::CompactBinaryReader<bond::InputBuffer>&>& value)
bool Apply(const bond::To< ::tests::BasicTypes>& transform,
const bond::bonded< ::tests::BasicTypes, bond::CompactBinaryReader<bond::InputBuffer>&>& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::To<BasicTypes>& transform,
bool Apply(const bond::To< ::tests::BasicTypes>& transform,
const bond::bonded<void, bond::CompactBinaryReader<bond::InputBuffer>&>& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::Serializer<bond::CompactBinaryWriter<bond::OutputBuffer> >& transform,
const BasicTypes& value)
const ::tests::BasicTypes& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::Serializer<bond::CompactBinaryWriter<bond::OutputBuffer> >& transform,
const bond::bonded<BasicTypes>& value)
const bond::bonded< ::tests::BasicTypes>& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::Serializer<bond::CompactBinaryWriter<bond::OutputBuffer> >& transform,
const bond::bonded<BasicTypes, bond::CompactBinaryReader<bond::InputBuffer>&>& value)
const bond::bonded< ::tests::BasicTypes, bond::CompactBinaryReader<bond::InputBuffer>&>& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::Serializer<bond::CompactBinaryWriter<bond::OutputBuffer> >& transform,
const bond::bonded<BasicTypes, bond::FastBinaryReader<bond::InputBuffer>&>& value)
const bond::bonded< ::tests::BasicTypes, bond::FastBinaryReader<bond::InputBuffer>&>& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::Serializer<bond::CompactBinaryWriter<bond::OutputBuffer> >& transform,
const bond::bonded<BasicTypes, bond::SimpleBinaryReader<bond::InputBuffer>&>& value)
const bond::bonded< ::tests::BasicTypes, bond::SimpleBinaryReader<bond::InputBuffer>&>& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::Marshaler<bond::CompactBinaryWriter<bond::OutputBuffer> >& transform,
const BasicTypes& value)
const ::tests::BasicTypes& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::Marshaler<bond::CompactBinaryWriter<bond::OutputBuffer> >& transform,
const bond::bonded<BasicTypes>& value)
const bond::bonded< ::tests::BasicTypes>& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::Marshaler<bond::CompactBinaryWriter<bond::OutputBuffer> >& transform,
const bond::bonded<BasicTypes, bond::CompactBinaryReader<bond::InputBuffer>&>& value)
const bond::bonded< ::tests::BasicTypes, bond::CompactBinaryReader<bond::InputBuffer>&>& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::Marshaler<bond::CompactBinaryWriter<bond::OutputBuffer> >& transform,
const bond::bonded<BasicTypes, bond::FastBinaryReader<bond::InputBuffer>&>& value)
const bond::bonded< ::tests::BasicTypes, bond::FastBinaryReader<bond::InputBuffer>&>& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::Marshaler<bond::CompactBinaryWriter<bond::OutputBuffer> >& transform,
const bond::bonded<BasicTypes, bond::SimpleBinaryReader<bond::InputBuffer>&>& value)
const bond::bonded< ::tests::BasicTypes, bond::SimpleBinaryReader<bond::InputBuffer>&>& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::To<BasicTypes>& transform,
const bond::bonded<BasicTypes, bond::FastBinaryReader<bond::InputBuffer>&>& value)
bool Apply(const bond::To< ::tests::BasicTypes>& transform,
const bond::bonded< ::tests::BasicTypes, bond::FastBinaryReader<bond::InputBuffer>&>& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::To<BasicTypes>& transform,
bool Apply(const bond::To< ::tests::BasicTypes>& transform,
const bond::bonded<void, bond::FastBinaryReader<bond::InputBuffer>&>& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::Serializer<bond::FastBinaryWriter<bond::OutputBuffer> >& transform,
const BasicTypes& value)
const ::tests::BasicTypes& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::Serializer<bond::FastBinaryWriter<bond::OutputBuffer> >& transform,
const bond::bonded<BasicTypes>& value)
const bond::bonded< ::tests::BasicTypes>& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::Serializer<bond::FastBinaryWriter<bond::OutputBuffer> >& transform,
const bond::bonded<BasicTypes, bond::CompactBinaryReader<bond::InputBuffer>&>& value)
const bond::bonded< ::tests::BasicTypes, bond::CompactBinaryReader<bond::InputBuffer>&>& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::Serializer<bond::FastBinaryWriter<bond::OutputBuffer> >& transform,
const bond::bonded<BasicTypes, bond::FastBinaryReader<bond::InputBuffer>&>& value)
const bond::bonded< ::tests::BasicTypes, bond::FastBinaryReader<bond::InputBuffer>&>& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::Serializer<bond::FastBinaryWriter<bond::OutputBuffer> >& transform,
const bond::bonded<BasicTypes, bond::SimpleBinaryReader<bond::InputBuffer>&>& value)
const bond::bonded< ::tests::BasicTypes, bond::SimpleBinaryReader<bond::InputBuffer>&>& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::Marshaler<bond::FastBinaryWriter<bond::OutputBuffer> >& transform,
const BasicTypes& value)
const ::tests::BasicTypes& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::Marshaler<bond::FastBinaryWriter<bond::OutputBuffer> >& transform,
const bond::bonded<BasicTypes>& value)
const bond::bonded< ::tests::BasicTypes>& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::Marshaler<bond::FastBinaryWriter<bond::OutputBuffer> >& transform,
const bond::bonded<BasicTypes, bond::CompactBinaryReader<bond::InputBuffer>&>& value)
const bond::bonded< ::tests::BasicTypes, bond::CompactBinaryReader<bond::InputBuffer>&>& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::Marshaler<bond::FastBinaryWriter<bond::OutputBuffer> >& transform,
const bond::bonded<BasicTypes, bond::FastBinaryReader<bond::InputBuffer>&>& value)
const bond::bonded< ::tests::BasicTypes, bond::FastBinaryReader<bond::InputBuffer>&>& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::Marshaler<bond::FastBinaryWriter<bond::OutputBuffer> >& transform,
const bond::bonded<BasicTypes, bond::SimpleBinaryReader<bond::InputBuffer>&>& value)
const bond::bonded< ::tests::BasicTypes, bond::SimpleBinaryReader<bond::InputBuffer>&>& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::To<BasicTypes>& transform,
const bond::bonded<BasicTypes, bond::SimpleBinaryReader<bond::InputBuffer>&>& value)
bool Apply(const bond::To< ::tests::BasicTypes>& transform,
const bond::bonded< ::tests::BasicTypes, bond::SimpleBinaryReader<bond::InputBuffer>&>& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::To<BasicTypes>& transform,
bool Apply(const bond::To< ::tests::BasicTypes>& transform,
const bond::bonded<void, bond::SimpleBinaryReader<bond::InputBuffer>&>& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::Serializer<bond::SimpleBinaryWriter<bond::OutputBuffer> >& transform,
const BasicTypes& value)
const ::tests::BasicTypes& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::Serializer<bond::SimpleBinaryWriter<bond::OutputBuffer> >& transform,
const bond::bonded<BasicTypes>& value)
const bond::bonded< ::tests::BasicTypes>& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::Serializer<bond::SimpleBinaryWriter<bond::OutputBuffer> >& transform,
const bond::bonded<BasicTypes, bond::CompactBinaryReader<bond::InputBuffer>&>& value)
const bond::bonded< ::tests::BasicTypes, bond::CompactBinaryReader<bond::InputBuffer>&>& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::Serializer<bond::SimpleBinaryWriter<bond::OutputBuffer> >& transform,
const bond::bonded<BasicTypes, bond::FastBinaryReader<bond::InputBuffer>&>& value)
const bond::bonded< ::tests::BasicTypes, bond::FastBinaryReader<bond::InputBuffer>&>& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::Serializer<bond::SimpleBinaryWriter<bond::OutputBuffer> >& transform,
const bond::bonded<BasicTypes, bond::SimpleBinaryReader<bond::InputBuffer>&>& value)
const bond::bonded< ::tests::BasicTypes, bond::SimpleBinaryReader<bond::InputBuffer>&>& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::Marshaler<bond::SimpleBinaryWriter<bond::OutputBuffer> >& transform,
const BasicTypes& value)
const ::tests::BasicTypes& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::Marshaler<bond::SimpleBinaryWriter<bond::OutputBuffer> >& transform,
const bond::bonded<BasicTypes>& value)
const bond::bonded< ::tests::BasicTypes>& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::Marshaler<bond::SimpleBinaryWriter<bond::OutputBuffer> >& transform,
const bond::bonded<BasicTypes, bond::CompactBinaryReader<bond::InputBuffer>&>& value)
const bond::bonded< ::tests::BasicTypes, bond::CompactBinaryReader<bond::InputBuffer>&>& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::Marshaler<bond::SimpleBinaryWriter<bond::OutputBuffer> >& transform,
const bond::bonded<BasicTypes, bond::FastBinaryReader<bond::InputBuffer>&>& value)
const bond::bonded< ::tests::BasicTypes, bond::FastBinaryReader<bond::InputBuffer>&>& value)
{
return bond::Apply<>(transform, value);
}

bool Apply(const bond::Marshaler<bond::SimpleBinaryWriter<bond::OutputBuffer> >& transform,
const bond::bonded<BasicTypes, bond::SimpleBinaryReader<bond::InputBuffer>&>& value)
const bond::bonded< ::tests::BasicTypes, bond::SimpleBinaryReader<bond::InputBuffer>&>& value)
{
return bond::Apply<>(transform, value);
}
Expand Down
Loading

0 comments on commit d1efb60

Please sign in to comment.