mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
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:
31
include/swift/APINotes/APINotesYAMLConverter.h
Normal file
31
include/swift/APINotes/APINotesYAMLConverter.h
Normal 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
|
||||
146
lib/APINotes/APINotesYAMLConverter.cpp
Normal file
146
lib/APINotes/APINotesYAMLConverter.cpp
Normal 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
|
||||
@@ -1,4 +1,5 @@
|
||||
add_swift_library(swiftAPINotes
|
||||
APINotesYAMLConverter.cpp
|
||||
APINotesWriter.cpp
|
||||
APINotesReader.cpp
|
||||
)
|
||||
|
||||
9
test/APIAnnotation/Inputs/UIKit.yaml
Normal file
9
test/APIAnnotation/Inputs/UIKit.yaml
Normal file
@@ -0,0 +1,9 @@
|
||||
FrameworkName: UIKit
|
||||
FrameworkAvailability: iOS
|
||||
FrameworkClasses:
|
||||
- ClassName: UIFont
|
||||
Methods:
|
||||
- Selector: "fontWithName:size:"
|
||||
Properties:
|
||||
- Name: familyName
|
||||
- Name: fontName
|
||||
2
test/APIAnnotation/yaml-reader-test.swift
Normal file
2
test/APIAnnotation/yaml-reader-test.swift
Normal 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
|
||||
@@ -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
|
||||
|
||||
87
tools/driver/api_notes.cpp
Normal file
87
tools/driver/api_notes.cpp
Normal 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;
|
||||
}
|
||||
|
||||
@@ -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]);
|
||||
|
||||
Reference in New Issue
Block a user