Add error for unknown API KeyKind

This commit is contained in:
Brent Royal-Gordon
2018-08-16 23:48:59 -07:00
parent fbe05ea817
commit ec87277e56
4 changed files with 133 additions and 99 deletions

View File

@@ -93,6 +93,11 @@ ERROR(attr_only_on_parameters, none,
ERROR(function_type_no_parens,none, ERROR(function_type_no_parens,none,
"single argument function types require parentheses", ()) "single argument function types require parentheses", ())
// FIXME: Used by swift-api-digester. Don't want to set up a separate diagnostics
// file just for one error.
ERROR(sdk_node_unrecognized_key,none,
"unrecognized key '%0' in SDK node", (StringRef))
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// MARK: Circular reference diagnostics // MARK: Circular reference diagnostics
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------

View File

@@ -0,0 +1,7 @@
{
"kind": "Root",
"name": "TopLevel",
"printedName": "TopLevel",
"children": [],
"badKey": ["foo", "bar", "baz"]
}

View File

@@ -0,0 +1,7 @@
// REQUIRES: OS=macosx
// RUN: not %api-digester -deserialize-sdk -input-paths %S/diagnostics.json -o - 2>&1 | %FileCheck %s
// CHECK: diagnostics.json:6:3: error: unrecognized key 'badKey' in SDK node
// Make sure we don't try to output a result:
// CHECK-NOT: "kind": "Root",

View File

@@ -331,10 +331,11 @@ enum class KeyKind {
#include "swift/IDE/DigesterEnums.def" #include "swift/IDE/DigesterEnums.def"
}; };
static KeyKind parseKeyKind(StringRef Content) { static Optional<KeyKind> parseKeyKind(StringRef Content) {
return llvm::StringSwitch<KeyKind>(Content) return llvm::StringSwitch<Optional<KeyKind>>(Content)
#define KEY(NAME) .Case(#NAME, KeyKind::KK_##NAME) #define KEY(NAME) .Case(#NAME, KeyKind::KK_##NAME)
#include "swift/IDE/DigesterEnums.def" #include "swift/IDE/DigesterEnums.def"
.Default(None)
; ;
} }
@@ -1043,113 +1044,127 @@ SDKNode* SDKNode::constructSDKNode(SDKContext &Ctx,
static auto getAsInt = [&](llvm::yaml::Node *N) -> int { static auto getAsInt = [&](llvm::yaml::Node *N) -> int {
return std::stoi(cast<llvm::yaml::ScalarNode>(N)->getRawValue()); return std::stoi(cast<llvm::yaml::ScalarNode>(N)->getRawValue());
}; };
static auto convertRange = [](llvm::SMRange Range) -> SourceRange {
return SourceRange(SourceLoc(Range.Start), SourceLoc(Range.End));
};
SDKNodeKind Kind; SDKNodeKind Kind;
SDKNodeInitInfo Info(Ctx); SDKNodeInitInfo Info(Ctx);
NodeVector Children; NodeVector Children;
for (auto &Pair : *Node) { for (auto &Pair : *Node) {
switch(parseKeyKind(GetScalarString(Pair.getKey()))) { auto keyString = GetScalarString(Pair.getKey());
case KeyKind::KK_kind: if (auto keyKind = parseKeyKind(keyString)) {
Kind = parseSDKNodeKind(GetScalarString(Pair.getValue())); switch(*keyKind) {
break; case KeyKind::KK_kind:
case KeyKind::KK_name: Kind = parseSDKNodeKind(GetScalarString(Pair.getValue()));
Info.Name = GetScalarString(Pair.getValue()); break;
break; case KeyKind::KK_name:
case KeyKind::KK_selfIndex: Info.Name = GetScalarString(Pair.getValue());
Info.SelfIndex = getAsInt(Pair.getValue()); break;
break; case KeyKind::KK_selfIndex:
case KeyKind::KK_usr: Info.SelfIndex = getAsInt(Pair.getValue());
Info.USR = GetScalarString(Pair.getValue()); break;
break; case KeyKind::KK_usr:
Info.USR = GetScalarString(Pair.getValue());
break;
case KeyKind::KK_location: case KeyKind::KK_location:
Info.Location = GetScalarString(Pair.getValue()); Info.Location = GetScalarString(Pair.getValue());
break; break;
case KeyKind::KK_children: case KeyKind::KK_children:
for (auto &Mapping : *cast<llvm::yaml::SequenceNode>(Pair.getValue())) { for (auto &Mapping : *cast<llvm::yaml::SequenceNode>(Pair.getValue())) {
Children.push_back(constructSDKNode(Ctx, Children.push_back(constructSDKNode(Ctx,
cast<llvm::yaml::MappingNode>(&Mapping))); cast<llvm::yaml::MappingNode>(&Mapping)));
}
break;
case KeyKind::KK_conformingProtocols: {
assert(Info.ConformingProtocols.empty());
for (auto &Name : *cast<llvm::yaml::SequenceNode>(Pair.getValue())) {
Info.ConformingProtocols.push_back(GetScalarString(&Name));
}
break;
} }
break; case KeyKind::KK_enumRawTypeName: {
case KeyKind::KK_conformingProtocols: { assert(Info.DKind == DeclKind::Enum);
assert(Info.ConformingProtocols.empty()); Info.EnumRawTypeName = GetScalarString(Pair.getValue());
for (auto &Name : *cast<llvm::yaml::SequenceNode>(Pair.getValue())) { break;
Info.ConformingProtocols.push_back(GetScalarString(&Name));
} }
break; case KeyKind::KK_printedName:
} Info.PrintedName = GetScalarString(Pair.getValue());
case KeyKind::KK_enumRawTypeName: { break;
assert(Info.DKind == DeclKind::Enum); case KeyKind::KK_moduleName:
Info.EnumRawTypeName = GetScalarString(Pair.getValue()); Info.ModuleName = GetScalarString(Pair.getValue());
break; break;
} case KeyKind::KK_superclassUsr:
case KeyKind::KK_printedName: Info.SuperclassUsr = GetScalarString(Pair.getValue());
Info.PrintedName = GetScalarString(Pair.getValue()); break;
break; case KeyKind::KK_genericSig:
case KeyKind::KK_moduleName: Info.GenericSig = GetScalarString(Pair.getValue());
Info.ModuleName = GetScalarString(Pair.getValue()); break;
break; case KeyKind::KK_throwing:
case KeyKind::KK_superclassUsr: Info.IsThrowing = true;
Info.SuperclassUsr = GetScalarString(Pair.getValue()); break;
break; case KeyKind::KK_mutating:
case KeyKind::KK_genericSig: Info.IsMutating = true;
Info.GenericSig = GetScalarString(Pair.getValue()); break;
break; case KeyKind::KK_hasDefaultArg:
case KeyKind::KK_throwing: Info.TypeInfo.hasDefaultArgument = true;
Info.IsThrowing = true; break;
break; case KeyKind::KK_static:
case KeyKind::KK_mutating: Info.IsStatic = true;
Info.IsMutating = true; break;
break; case KeyKind::KK_deprecated:
case KeyKind::KK_hasDefaultArg: Info.IsDeprecated = true;
Info.TypeInfo.hasDefaultArgument = true; break;
break; case KeyKind::KK_ownership:
case KeyKind::KK_static: Info.ReferenceOwnership =
Info.IsStatic = true; swift::ReferenceOwnership(getAsInt(Pair.getValue()));
break; assert(Info.ReferenceOwnership != swift::ReferenceOwnership::Strong &&
case KeyKind::KK_deprecated: "Strong is implied.");
Info.IsDeprecated = true; break;
break;
case KeyKind::KK_ownership:
Info.ReferenceOwnership =
swift::ReferenceOwnership(getAsInt(Pair.getValue()));
assert(Info.ReferenceOwnership != swift::ReferenceOwnership::Strong &&
"Strong is implied.");
break;
case KeyKind::KK_typeAttributes: { case KeyKind::KK_typeAttributes: {
auto *Seq = cast<llvm::yaml::SequenceNode>(Pair.getValue()); auto *Seq = cast<llvm::yaml::SequenceNode>(Pair.getValue());
std::transform(Seq->begin(), Seq->end(), std::transform(Seq->begin(), Seq->end(),
std::back_inserter(Info.TypeAttrs), std::back_inserter(Info.TypeAttrs),
[](llvm::yaml::Node &N) { [](llvm::yaml::Node &N) {
auto Result = llvm::StringSwitch<TypeAttrKind>(GetScalarString(&N)) auto Result = llvm::StringSwitch<TypeAttrKind>(GetScalarString(&N))
#define TYPE_ATTR(X) .Case(#X, TypeAttrKind::TAK_##X) #define TYPE_ATTR(X) .Case(#X, TypeAttrKind::TAK_##X)
#include "swift/AST/Attr.def" #include "swift/AST/Attr.def"
.Default(TypeAttrKind::TAK_Count); .Default(TypeAttrKind::TAK_Count);
assert(Result != TypeAttrKind::TAK_Count); assert(Result != TypeAttrKind::TAK_Count);
return Result; return Result;
}); });
break; break;
}
case KeyKind::KK_declAttributes: {
auto *Seq = cast<llvm::yaml::SequenceNode>(Pair.getValue());
std::transform(Seq->begin(), Seq->end(), std::back_inserter(Info.DeclAttrs),
[](llvm::yaml::Node &N) {
auto Result = llvm::StringSwitch<DeclAttrKind>(GetScalarString(&N))
#define DECL_ATTR(_, NAME, ...) .Case(#NAME, DeclAttrKind::DAK_##NAME)
#include "swift/AST/Attr.def"
.Default(DeclAttrKind::DAK_Count);
assert(Result != DeclAttrKind::DAK_Count);
return Result;
});
break;
}
case KeyKind::KK_declKind:
Info.DKind = llvm::StringSwitch<DeclKind>(GetScalarString(Pair.getValue()))
#define DECL(X, PARENT) .Case(#X, DeclKind::X)
#include "swift/AST/DeclNodes.def"
;
break;
}
} }
case KeyKind::KK_declAttributes: { else {
auto *Seq = cast<llvm::yaml::SequenceNode>(Pair.getValue()); auto range = convertRange(Pair.getKey()->getSourceRange());
std::transform(Seq->begin(), Seq->end(), std::back_inserter(Info.DeclAttrs), Ctx.getDiags().diagnose(range.Start, diag::sdk_node_unrecognized_key,
[](llvm::yaml::Node &N) { keyString)
auto Result = llvm::StringSwitch<DeclAttrKind>(GetScalarString(&N)) .highlight(range);
#define DECL_ATTR(_, NAME, ...) .Case(#NAME, DeclAttrKind::DAK_##NAME) Pair.skip();
#include "swift/AST/Attr.def"
.Default(DeclAttrKind::DAK_Count);
assert(Result != DeclAttrKind::DAK_Count);
return Result;
});
break;
}
case KeyKind::KK_declKind:
Info.DKind = llvm::StringSwitch<DeclKind>(GetScalarString(Pair.getValue()))
#define DECL(X, PARENT) .Case(#X, DeclKind::X)
#include "swift/AST/DeclNodes.def"
;
break;
} }
}; };
SDKNode *Result = Info.createSDKNode(Kind); SDKNode *Result = Info.createSDKNode(Kind);