Add a skeleton for API Notes YAML-to-binary conversion

Parses a YAML file (but not the final/full format yet).

Adds an entry to the driver for the apinotes "tool". We want the tool
to be visible to the user so it has to go to the driver.

Very limited testing as of now.

Swift SVN r20137
This commit is contained in:
Anna Zaks
2014-07-18 03:39:03 +00:00
parent 3a90aaf8a3
commit 7fab0c91e2
8 changed files with 283 additions and 0 deletions

View File

@@ -0,0 +1,31 @@
//===--- APINotesYAMLConverter.h - Side Car YAML format reader --*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file reads sidecar data specified in YAML format.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_API_NOTES_YAML_CONVERTER_H
#define SWIFT_API_NOTES_YAML_CONVERTER_H
#include "llvm/ADT/StringRef.h"
namespace swift {
namespace api_notes {
/// Converts side car from YAML format into binary format.
void buildSidecarFromYAML(llvm::StringRef fromFileName,
llvm::StringRef toFileName);
} // end namespace api_notes
} // end namespace swift
#endif // LLVM_SWIFT_API_NOTES_YAML_CONVERTER_H

View File

@@ -0,0 +1,146 @@
//===--- APINotesYAMLConverter.cpp - Side Car YAML format reader *- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file reads sidecar data specified in YAML format.
//
//===----------------------------------------------------------------------===//
#include "swift/APINotes/APINotesYAMLConverter.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/YAMLParser.h"
#include "llvm/Support/YAMLTraits.h"
using llvm::StringRef;
enum class APIAvailability {
OSX,
IOS,
None,
};
struct Method {
StringRef Selector;
};
struct Property {
StringRef Name;
};
typedef std::vector<Method> MethodsSeq;
LLVM_YAML_IS_SEQUENCE_VECTOR(Method);
typedef std::vector<Property> PropertiesSeq;
LLVM_YAML_IS_SEQUENCE_VECTOR(Property);
struct Class {
StringRef Name;
bool AuditedForNullability;
APIAvailability Availability;
StringRef AvailabilityMsg;
MethodsSeq Methods;
PropertiesSeq Properties;
};
typedef std::vector<Class> ClassesSeq;
LLVM_YAML_IS_SEQUENCE_VECTOR(Class);
struct Framework {
StringRef Name;
StringRef Availability;
StringRef AvailabilityMsg;
ClassesSeq Classes;
};
// Define a sequence of frameworks.
typedef std::vector<Framework> FrameworksSeq;
LLVM_YAML_IS_SEQUENCE_VECTOR(Framework);
namespace llvm {
namespace yaml {
template <>
struct ScalarEnumerationTraits<APIAvailability> {
static void enumeration(IO &io, APIAvailability &value) {
io.enumCase(value, "OSX", APIAvailability::OSX);
io.enumCase(value, "iOS", APIAvailability::IOS);
io.enumCase(value, "none", APIAvailability::None);
}
};
template <>
struct MappingTraits<Property> {
static void mapping(IO &io, Property& p) {
io.mapRequired("Name", p.Name);
}
};
template <>
struct MappingTraits<Method> {
static void mapping(IO &io, Method& m) {
io.mapRequired("Selector", m.Selector);
}
};
template <>
struct MappingTraits<Class> {
static void mapping(IO &io, Class& c) {
io.mapRequired("ClassName", c.Name);
io.mapOptional("AuditedForNullability", c.AuditedForNullability);
io.mapOptional("Availability", c.Availability);
io.mapOptional("AvailabilityMessage", c.AvailabilityMsg);
io.mapOptional("Methods", c.Methods);
io.mapOptional("Properties", c.Properties);
}
};
template <>
struct MappingTraits<Framework> {
static void mapping(IO &io, Framework& f) {
io.mapRequired("FrameworkName", f.Name);
io.mapOptional("FrameworkAvailability", f.Availability);
io.mapOptional("AvailabilityMsg", f.AvailabilityMsg);
io.mapRequired("FrameworkClasses", f.Classes);
}
};
}
}
using llvm::yaml::Input;
namespace swift {
namespace api_notes {
void buildSidecarFromYAML(StringRef fromFileName, StringRef toFileName) {
using ::llvm::ErrorOr;
using ::llvm::MemoryBuffer;
ErrorOr<std::unique_ptr<MemoryBuffer>> FileBufOrErr =
MemoryBuffer::getFile(fromFileName);
if (std::error_code EC = FileBufOrErr.getError()) {
llvm::errs() << "\n Could not open input file: " + EC.message() << '\n';
return;
}
Framework f;
Input yin(FileBufOrErr.get()->getBuffer());
yin >> f;
llvm::outs() << f.Name;
if (std::error_code ec = yin.error()) {
llvm::errs() << "\n Could not parse the input file: " << ec.message() << '\n';
return;
}
}
} // end namespace api_notes
} // end namespace swift

View File

@@ -1,4 +1,5 @@
add_swift_library(swiftAPINotes
APINotesYAMLConverter.cpp
APINotesWriter.cpp
APINotesReader.cpp
)

View File

@@ -0,0 +1,9 @@
FrameworkName: UIKit
FrameworkAvailability: iOS
FrameworkClasses:
- ClassName: UIFont
Methods:
- Selector: "fontWithName:size:"
Properties:
- Name: familyName
- Name: fontName

View File

@@ -0,0 +1,2 @@
// RUN: %swift_driver_plain -apinotes -yaml-to-binary %S/Inputs/UIKit.yaml -o %t-ObjectiveC.apinotes | FileCheck %s
// CHECK: UIKit

View File

@@ -1,5 +1,6 @@
add_swift_executable(swift
driver.cpp
api_notes.cpp
frontend_main.cpp
DEPENDS swiftDriver swiftIRGen swiftSIL swiftSILGen swiftSILPasses swiftImmediate
swiftSerialization swiftFrontend swiftClangImporter swiftIDE

View File

@@ -0,0 +1,87 @@
//===-- api_notes_converter.cpp - Swift Compiler Frontend ----------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This is the YAML to binary converter for API notes.
///
//===----------------------------------------------------------------------===//
#include "swift/APINotes/APINotesYAMLConverter.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringMap.h"
enum class ActionType {
None,
YAMLToBinary,
};
using namespace llvm;
// Mark all our options with this category, everything else (except for -version
// and -help) will be hidden.
static cl::OptionCategory APINotesCategory("API Notes options");
static cl::opt<ActionType>
Action(cl::desc("Mode:"), cl::init(ActionType::None),
cl::values(
clEnumValN(ActionType::YAMLToBinary,
"yaml-to-binary", "Convert YAML to binary format"),
clEnumValEnd),
cl::cat(APINotesCategory));
static cl::opt<std::string>
InputFilename(cl::Positional, cl::desc("<input file>"),
cl::Required, cl::cat(APINotesCategory));
static cl::opt<std::string>
OutputFilename("o", cl::desc("Output file name"), cl::cat(APINotesCategory));
int apinotes_main(ArrayRef<const char *> Args) {
// Hide unrelated options.
StringMap<cl::Option*> Options;
cl::getRegisteredOptions(Options);
for (StringMap<cl::Option *>::iterator I = Options.begin(),
E = Options.end();
I != E; ++I) {
if (I->second->Category != &APINotesCategory &&
I->first() != "help" && I->first() != "version")
I->second->setHiddenFlag(cl::ReallyHidden);
}
cl::ParseCommandLineOptions(Args.size(),
Args.data(),
"Swift API Notes Tool\n");
if (Action == ActionType::None) {
errs() << "action required\n";
cl::PrintHelpMessage();
return 1;
}
if (Action == ActionType::YAMLToBinary) {
if (OutputFilename.empty()) {
errs() << "output file required\n";
cl::PrintHelpMessage();
return 1;
}
swift::api_notes::buildSidecarFromYAML(InputFilename,
OutputFilename);
return 0;
}
return 1;
}

View File

@@ -44,6 +44,8 @@ std::string getExecutablePath(const char *FirstArg) {
extern int frontend_main(ArrayRef<const char *> Args, const char *Argv0,
void *MainAddr);
extern int apinotes_main(ArrayRef<const char *> Args);
int main(int argc_, const char **argv_) {
// Print a stack trace if we signal out.
llvm::sys::PrintStackTraceOnErrorSignal();
@@ -69,6 +71,10 @@ int main(int argc_, const char **argv_) {
argv.data()+argv.size()),
argv[0], (void *)(intptr_t)getExecutablePath);
}
if (FirstArg == "-apinotes") {
return apinotes_main(llvm::makeArrayRef(argv.data()+1,
argv.data()+argv.size()));
}
}
std::string Path = getExecutablePath(argv[0]);