aboutsummaryrefslogtreecommitdiffstats
path: root/slang_rs_reflect_utils.h
blob: 1cbc09891d853fa289b457ef1514172d8816ee53 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
 * 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