Home | History | Annotate | Download | only in slang
      1 /*
      2  * Copyright 2010, The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_REFLECT_UTILS_H_ // NOLINT
     18 #define _FRAMEWORKS_COMPILE_SLANG_SLANG_REFLECT_UTILS_H_
     19 
     20 #include <fstream>
     21 #include <string>
     22 
     23 namespace slang {
     24 
     25 // BitCode storage type
     26 enum BitCodeStorageType { BCST_APK_RESOURCE, BCST_JAVA_CODE, BCST_CPP_CODE };
     27 
     28 class RSSlangReflectUtils {
     29 public:
     30   // Encode a binary bitcode file into a Java source file.
     31   // rsFileName: the original .rs file name (with or without path).
     32   // bc32FileName: path of the 32-bit bitcode file
     33   // bc64FileName: path of the 64-bit bitcode file
     34   // reflectPath: where to output the generated Java file, no package name in
     35   // it.
     36   // packageName: the package of the output Java file.
     37   // verbose: whether or not to print out additional info about compilation.
     38   // bcStorage: where to emit bitcode to (resource file or embedded).
     39   struct BitCodeAccessorContext {
     40     const char *rsFileName;
     41     const char *bc32FileName;
     42     const char *bc64FileName;
     43     const char *reflectPath;
     44     const char *packageName;
     45     const std::string *licenseNote;
     46     bool verbose;
     47     BitCodeStorageType bcStorage;
     48   };
     49 
     50   // Return the stem of the file name, i.e., remove the dir and the extension.
     51   // Eg, foo.ext -> foo
     52   //     foo.bar.ext -> foo.bar
     53   //     ./path/foo.ext -> foo
     54   static std::string GetFileNameStem(const char *fileName);
     55 
     56   // Compute a Java source file path from a given prefixPath and its package.
     57   // Eg, given prefixPath=./foo/bar and packageName=com.x.y, then it returns
     58   // ./foo/bar/com/x/y
     59   static std::string ComputePackagedPath(const char *prefixPath,
     60                                          const char *packageName);
     61 
     62   // Compute Java class name from a .rs file name.
     63   // Any non-alnum, non-underscore characters will be discarded.
     64   // E.g. with rsFileName=./foo/bar/my-Renderscript_file.rs it returns
     65   // "myRenderscript_file".
     66   // rsFileName: the input .rs file name (with or without path).
     67   static std::string JavaClassNameFromRSFileName(const char *rsFileName);
     68 
     69   // Compute a bitcode file name (no extension) from a .rs file name.
     70   // Because the bitcode file name may be used as Resource ID in the generated
     71   // class (something like R.raw.<bitcode_filename>), Any non-alnum,
     72   // non-underscore character will be discarded.
     73   // The difference from JavaClassNameFromRSFileName() is that the result is
     74   // converted to lowercase.
     75   // E.g. with rsFileName=./foo/bar/my-Renderscript_file.rs it returns
     76   // "myrenderscript_file"
     77   // rsFileName: the input .rs file name (with or without path).
     78   static std::string BCFileNameFromRSFileName(const char *rsFileName);
     79 
     80   // Compute the bitcode-containing class name from a .rs filename.
     81   // Any non-alnum, non-underscore characters will be discarded.
     82   // E.g. with rsFileName=./foo/bar/my-Renderscript_file.rs it returns
     83   // "myRenderscript_fileBitCode".
     84   // rsFileName: the input .rs file name (with or without path).
     85   static std::string JavaBitcodeClassNameFromRSFileName(const char *rsFileName);
     86 
     87   // Generate the bit code accessor Java source file.
     88   static bool GenerateJavaBitCodeAccessor(const BitCodeAccessorContext &context);
     89 };
     90 
     91 // Joins two sections of a path, inserting a separator if needed.
     92 // E.g. JoinPath("foo/bar", "baz/a.java") returns "foo/bar/baz/a.java",
     93 // JoinPath("foo", "/bar/baz") returns "foo/bar/baz", and
     94 // JoinPath("foo/", "/bar") returns "foo/bar".
     95 std::string JoinPath(const std::string &path1, const std::string &path2);
     96 
     97 /* Compute a safe root name from a .rs file name.  Any non-alphanumeric,
     98  * non-underscore characters will be discarded.
     99  * E.g. RootNameFromRSFileName("./foo/bar/my-Renderscript_file.rs") returns
    100  * "myRenderscript_file".
    101  */
    102 std::string RootNameFromRSFileName(const std::string &rsFileName);
    103 
    104 /* This class is used to generate one source file.  There will be one instance
    105  * for each generated file.
    106  */
    107 class GeneratedFile : public std::ofstream {
    108 public:
    109   /* Starts the file by:
    110    * - creating the parent directories (if needed),
    111    * - opening the stream,
    112    * - writing out the license,
    113    * - writing a message that this file has been auto-generated.
    114    * If optionalLicense is nullptr, a default license is used.
    115    */
    116   bool startFile(const std::string &outPath, const std::string &outFileName,
    117                  const std::string &sourceFileName,
    118                  const std::string *optionalLicense, bool isJava, bool verbose);
    119   void closeFile();
    120 
    121   void increaseIndent(); // Increases the new line indentation by 4.
    122   void decreaseIndent(); // Decreases the new line indentation by 4.
    123   void comment(const std::string& s); // Outputs a multiline comment.
    124 
    125   // Starts a control block.  This works both for Java and C++.
    126   void startBlock() {
    127     *this << " {\n";
    128     increaseIndent();
    129   }
    130 
    131   // Ends a control block.
    132   void endBlock(bool addSemicolon = false) {
    133     decreaseIndent();
    134     indent() << "}" << (addSemicolon ? ";" : "") << "\n\n";
    135   }
    136 
    137   /* Indents the line.  By returning *this, we can use like this:
    138    *  mOut.ident() << "a = b;\n";
    139    */
    140   std::ofstream &indent() {
    141     *this << mIndent;
    142     return *this;
    143   }
    144 
    145 private:
    146   std::string mIndent; // The correct spacing at the beginning of each line.
    147 };
    148 
    149 } // namespace slang
    150 
    151 #endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_REFLECT_UTILS_H_  NOLINT
    152