/*
* Copyright 2010, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_REFLECT_UTILS_H_ // NOLINT
#define _FRAMEWORKS_COMPILE_SLANG_SLANG_REFLECT_UTILS_H_
#include <fstream>
#include <string>
namespace slang {
// BitCode storage type
enum BitCodeStorageType { BCST_APK_RESOURCE, BCST_JAVA_CODE, BCST_CPP_CODE };
class RSSlangReflectUtils {
public:
// Encode a binary bitcode file into a Java source file.
// rsFileName: the original .rs file name (with or without path).
// bc32FileName: path of the 32-bit bitcode file
// bc64FileName: path of the 64-bit bitcode file
// reflectPath: where to output the generated Java file, no package name in
// it.
// packageName: the package of the output Java file.
// verbose: whether or not to print out additional info about compilation.
// bcStorage: where to emit bitcode to (resource file or embedded).
struct BitCodeAccessorContext {
const char *rsFileName;
const char *bc32FileName;
const char *bc64FileName;
const char *reflectPath;
const char *packageName;
const std::string *licenseNote;
bool verbose;
BitCodeStorageType bcStorage;
};
// Return the stem of the file name, i.e., remove the dir and the extension.
// Eg, foo.ext -> foo
// foo.bar.ext -> foo.bar
// ./path/foo.ext -> foo
static std::string GetFileNameStem(const char *fileName);
// Compute a Java source file path from a given prefixPath and its package.
// Eg, given prefixPath=./foo/bar and packageName=com.x.y, then it returns
// ./foo/bar/com/x/y
static std::string ComputePackagedPath(const char *prefixPath,
const char *packageName);
// Compute Java class name from a .rs file name.
// Any non-alnum, non-underscore characters will be discarded.
// E.g. with rsFileName=./foo/bar/my-Renderscript_file.rs it returns
// "myRenderscript_file".
// rsFileName: the input .rs file name (with or without path).
static std::string JavaClassNameFromRSFileName(const char *rsFileName);
// Compute a bitcode file name (no extension) from a .rs file name.
// Because the bitcode file name may be used as Resource ID in the generated
// class (something like R.raw.<bitcode_filename>), Any non-alnum,
// non-underscore character will be discarded.
// The difference from JavaClassNameFromRSFileName() is that the result is
// converted to lowercase.
// E.g. with rsFileName=./foo/bar/my-Renderscript_file.rs it returns
// "myrenderscript_file"
// rsFileName: the input .rs file name (with or without path).
static std::string BCFileNameFromRSFileName(const char *rsFileName);
// Compute the bitcode-containing class name from a .rs filename.
// Any non-alnum, non-underscore characters will be discarded.
// E.g. with rsFileName=./foo/bar/my-Renderscript_file.rs it returns
// "myRenderscript_fileBitCode".
// rsFileName: the input .rs file name (with or without path).
static std::string JavaBitcodeClassNameFromRSFileName(const char *rsFileName);
// Generate the bit code accessor Java source file.
static bool GenerateJavaBitCodeAccessor(const BitCodeAccessorContext &context);
};
// Joins two sections of a path, inserting a separator if needed.
// E.g. JoinPath("foo/bar", "baz/a.java") returns "foo/bar/baz/a.java",
// JoinPath("foo", "/bar/baz") returns "foo/bar/baz", and
// JoinPath("foo/", "/bar") returns "foo/bar".
std::string JoinPath(const std::string &path1, const std::string &path2);
/* Compute a safe root name from a .rs file name. Any non-alphanumeric,
* non-underscore characters will be discarded.
* E.g. RootNameFromRSFileName("./foo/bar/my-Renderscript_file.rs") returns
* "myRenderscript_file".
*/
std::string RootNameFromRSFileName(const std::string &rsFileName);
/* This class is used to generate one source file. There will be one instance
* for each generated file.
*/
class GeneratedFile : public std::ofstream {
public:
/* Starts the file by:
* - creating the parent directories (if needed),
* - opening the stream,
* - writing out the license,
* - writing a message that this file has been auto-generated.
* If optionalLicense is nullptr, a default license is used.
*/
bool startFile(const std::string &outPath, const std::string &outFileName,
const std::string &sourceFileName,
const std::string *optionalLicense, bool isJava, bool verbose);
void closeFile();
void increaseIndent(); // Increases the new line indentation by 4.
void decreaseIndent(); // Decreases the new line indentation by 4.
void comment(const std::string& s); // Outputs a multiline comment.
// Starts a control block. This works both for Java and C++.
void startBlock() {
*this << " {\n";
increaseIndent();
}
// Ends a control block.
void endBlock(bool addSemicolon = false) {
decreaseIndent();
indent() << "}" << (addSemicolon ? ";" : "") << "\n\n";
}
/* Indents the line. By returning *this, we can use like this:
* mOut.ident() << "a = b;\n";
*/
std::ofstream &indent() {
*this << mIndent;
return *this;
}
private:
std::string mIndent; // The correct spacing at the beginning of each line.
};
} // namespace slang
#endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_REFLECT_UTILS_H_ NOLINT