java - 使用java嵌套#if宏处理

标签 java java.util.scanner emscripten nashorn

我已经创建了一个代码来处理这个文件

https://raw.githubusercontent.com/emscripten-core/emscripten/master/src/library_html5.js

逐行扫描#f#else#endif

达到特定级别它工作正常,之后它会跳过一组行

这是我的代码

static ScriptEngineManager mgr = new ScriptEngineManager();
static ScriptEngine engine = mgr.getEngineByName("JavaScript");
public static void main(String[] args) throws Exception {
    Bindings bindings = engine.createBindings();
    bindings.put("TARGET_NOT_SUPPORTED", true);
    bindings.put("HTML5_SUPPORT_DEFERRING_USER_SENSITIVE_REQUESTS", true);
    bindings.put("MINIMAL_RUNTIME", false);
    bindings.put("EXIT_RUNTIME", false);
    bindings.put("MIN_IE_VERSION", "TARGET_NOT_SUPPORTED");
    bindings.put("USE_PTHREADS", true);
    bindings.put("WASM_BACKEND", true);
    bindings.put("MIN_FIREFOX_VERSION", 64);
    bindings.put("MIN_SAFARI_VERSION", "TARGET_NOT_SUPPORTED");
    bindings.put("ENVIRONMENT_MAY_BE_WORKER", false);
    bindings.put("ENVIRONMENT_MAY_BE_NODE", false);
    bindings.put("ENVIRONMENT_MAY_BE_SHELL", false);
    bindings.put("DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR", true);
    bindings.put("OFFSCREENCANVAS_SUPPORT", true);
    bindings.put("ASSERTIONS", false);
    bindings.put("MIN_CHROME_VERSION", 37);
    bindings.put("MIN_EDGE_VERSION", 13);
    bindings.put("GL_DEBUG", false);
    bindings.put("OFFSCREEN_FRAMEBUFFER", true);
    bindings.put("TRACE_WEBGL_CALLS", true);
    bindings.put("GL_SUPPORT_AUTOMATIC_ENABLE_EXTENSIONS", true);
    bindings.put("GL_SUPPORT_EXPLICIT_SWAP_CONTROL", true);
    bindings.put("MIN_WEBGL_VERSION", 1);
    bindings.put("USE_WEBGPU", true);
    bindings.put("WASM", true);
    bindings.put("GL_EXTENSIONS_IN_PREFIXED_FORMAT", true);
    bindings.put("MAX_WEBGL_VERSION", 3);
    bindings.put("MIN_WEBGL_VERSION", 1);
    bindings.put("FULL_ES2", true);
    bindings.put("GL_ASSERTIONS", false);
    bindings.put("GL_TRACK_ERRORS", true);
    bindings.put("GL_POOL_TEMP_BUFFERS", true);
    bindings.put("LEGACY_GL_EMULATION", false);
    bindings.put("GL_FFP_ONLY", false);
    bindings.put("GL_TESTING", false);
    bindings.put("GL_PREINITIALIZED_CONTEXT", false);
    bindings.put("GL_DISABLE_HALF_FLOAT_EXTENSION_IF_BROKEN", true);
    bindings.put("OFFSCREEN_FRAMEBUFFER_FORBID_VAO_PATH", false);
    bindings.put("WORKAROUND_OLD_WEBGL_UNIFORM_UPLOAD_IGNORED_OFFSET_BUG", true);
    bindings.put("GL_EMULATE_GLES_VERSION_STRING_FORMAT", true);
    bindings.put("WEBGL2_BACKWARDS_COMPATIBILITY_EMULATION", true);
    bindings.put("PTHREAD_POOL_SIZE", 2);
    bindings.put("PTHREADS_PROFILING", false);
    bindings.put("USE_CLOSURE_COMPILER", true);
    bindings.put("LOAD_SOURCE_MAP", false);
    bindings.put("USE_OFFSET_CONVERTER", false);
    bindings.put("PTHREADS_DEBUG", false);
    bindings.put("OFFSCREENCANVASES_TO_PTHREAD", true);
    bindings.put("ALLOW_BLOCKING_ON_MAIN_THREAD", false);
    bindings.put("STACK_OVERFLOW_CHECK", false);
    bindings.put("FULL_ES3", true);
    bindings.put("library_webgl.js", true);
    engine.setBindings(bindings, ScriptContext.GLOBAL_SCOPE);
    engine.eval("var LibraryManager = {\"has\":function(){return true;}}");

    Scanner s = new Scanner(new File("C:\\emsdk-1.39.13\\upstream\\emscripten\\src\\library_html5.js"));
    Integer iflevel = 0;
    Boolean flags[] = new Boolean[] {true,false,false,false,false};
    Integer ln = 0;
    while(s.hasNextLine()) {
        String line = s.nextLine();
        if(line.startsWith("#if")) {
            if(line.indexOf("//")!=-1)
                line = line.substring(0, line.indexOf("//"));
            line = line.substring(4);

            System.out.println(ln.toString() + " " + iflevel.toString() + " #if " + line.toString() + " " + engine.eval(line).toString());

            if(engine.eval(line)!=null && engine.eval(line).toString().equals("true")) {
                iflevel++;
                flags[iflevel] = true;
            }else if(engine.eval(line)!=null && engine.eval(line).toString().equals("false")) {
                iflevel++;
                flags[iflevel] = false;
            }
        }
        else if(line.startsWith("#else")) {
            if(iflevel>=0)
                flags[iflevel] = !flags[iflevel];

            System.out.println(ln.toString() + " " + iflevel.toString() + " " + line.toString() + " ");
        }
        else if(line.startsWith("#endif")) {
            if(iflevel>0){
                flags[iflevel] = false;
                iflevel--;
            }
            if(iflevel<=0) {
                iflevel = 0;
                flags = new Boolean[] {true,false,false,false,false};
            }
            System.out.println(ln.toString() + " " + iflevel.toString() + " " + line.toString() + " ");
        }
        else if(flags[iflevel]==true) {
            while(line.indexOf("{{{")!=-1) {
                line = line.replace("{{{", "");
            }
            while(line.indexOf("}}}")!=-1) {
                line = line.replace("}}}", "");
            }
            System.out.println(line);
            if(iflevel<=0) {
                iflevel = 0;
                flags = new Boolean[] {true,false,false,false,false};
            } 
        }else {
            //println("level " + iflevel + " " + flags[iflevel] + " " + line);
        }
        ln++;
    }
    s.close();

}

问题始于第 2891 行,由于缺少函数声明或打开大括号,生成的代码成为错误的 JavaScript,并导致这种代码

  }, 
if (canvas.GLctxObject) GL.resizeOffscreenFramebuffer(canvas.GLctxObject);

似乎是标志被更改或 iflevel 错误

任何帮助都会很棒! - 输出应该是处理后的 JavaScript 文件,所有条件都有效并且宏已正确删​​除

Java 的原因是这实际上是 Spring Boot 中的 @RequestMapping("/js/**")

最佳答案

我选择了 Handlebars ,原因是 {{#if}}{{else}}{{/if}} 已在该库中处理

我引入了一个名为 ifCond 的助手,它将调用 nashron

然后我将 #if 替换为 {{#ifCond ,将 #else 替换为 {{else}},将#endif替换为{{/if}}

static ScriptEngineManager mgr = new ScriptEngineManager();
static ScriptEngine engine = mgr.getEngineByName("JavaScript");

public static void main(String[] args) throws Exception {

    Bindings bindings = engine.createBindings();
    bindings.put("TARGET_NOT_SUPPORTED", true);
    bindings.put("HTML5_SUPPORT_DEFERRING_USER_SENSITIVE_REQUESTS", true);
    bindings.put("MINIMAL_RUNTIME", false);
    bindings.put("EXIT_RUNTIME", false);
    bindings.put("MIN_IE_VERSION", "TARGET_NOT_SUPPORTED");
    bindings.put("USE_PTHREADS", true);
    bindings.put("WASM_BACKEND", true);
    bindings.put("MIN_FIREFOX_VERSION", 64);
    bindings.put("MIN_SAFARI_VERSION", "TARGET_NOT_SUPPORTED");
    bindings.put("ENVIRONMENT_MAY_BE_WORKER", false);
    bindings.put("ENVIRONMENT_MAY_BE_NODE", false);
    bindings.put("ENVIRONMENT_MAY_BE_SHELL", false);
    bindings.put("DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR", true);
    bindings.put("OFFSCREENCANVAS_SUPPORT", true);
    bindings.put("ASSERTIONS", false);
    bindings.put("MIN_CHROME_VERSION", 37);
    bindings.put("MIN_EDGE_VERSION", 13);
    bindings.put("GL_DEBUG", false);
    bindings.put("OFFSCREEN_FRAMEBUFFER", true);
    bindings.put("TRACE_WEBGL_CALLS", true);
    bindings.put("GL_SUPPORT_AUTOMATIC_ENABLE_EXTENSIONS", true);
    bindings.put("GL_SUPPORT_EXPLICIT_SWAP_CONTROL", true);
    bindings.put("MIN_WEBGL_VERSION", 1);
    bindings.put("USE_WEBGPU", true);
    bindings.put("WASM", true);
    bindings.put("GL_EXTENSIONS_IN_PREFIXED_FORMAT", true);
    bindings.put("MAX_WEBGL_VERSION", 3);
    bindings.put("MIN_WEBGL_VERSION", 1);
    bindings.put("FULL_ES2", true);
    bindings.put("GL_ASSERTIONS", false);
    bindings.put("GL_TRACK_ERRORS", true);
    bindings.put("GL_POOL_TEMP_BUFFERS", true);
    bindings.put("LEGACY_GL_EMULATION", false);
    bindings.put("GL_FFP_ONLY", false);
    bindings.put("GL_TESTING", false);
    bindings.put("GL_PREINITIALIZED_CONTEXT", false);
    bindings.put("GL_DISABLE_HALF_FLOAT_EXTENSION_IF_BROKEN", true);
    bindings.put("OFFSCREEN_FRAMEBUFFER_FORBID_VAO_PATH", false);
    bindings.put("WORKAROUND_OLD_WEBGL_UNIFORM_UPLOAD_IGNORED_OFFSET_BUG", true);
    bindings.put("GL_EMULATE_GLES_VERSION_STRING_FORMAT", true);
    bindings.put("WEBGL2_BACKWARDS_COMPATIBILITY_EMULATION", true);
    bindings.put("PTHREAD_POOL_SIZE", 2);
    bindings.put("PTHREADS_PROFILING", false);
    bindings.put("USE_CLOSURE_COMPILER", true);
    bindings.put("LOAD_SOURCE_MAP", false);
    bindings.put("USE_OFFSET_CONVERTER", false);
    bindings.put("PTHREADS_DEBUG", false);
    bindings.put("OFFSCREENCANVASES_TO_PTHREAD", true);
    bindings.put("ALLOW_BLOCKING_ON_MAIN_THREAD", false);
    bindings.put("STACK_OVERFLOW_CHECK", false);
    bindings.put("ALLOW_MEMORY_GROWTH", false);
    bindings.put("MAXIMUM_MEMORY", -1);
    bindings.put("ABORTING_MALLOC", 0);
    bindings.put("TEST_MEMORY_GROWTH_FAILS", false);
    bindings.put("MEMORYPROFILER", false);
    bindings.put("CAN_ADDRESS_2GB", false);
    bindings.put("EMSCRIPTEN_TRACING", false);
    bindings.put("MEMORY_GROWTH_LINEAR_STEP", -1);
    bindings.put("MEMORY_GROWTH_GEOMETRIC_CAP", 96);
    bindings.put("FAST_UNROLLED_MEMCPY_AND_MEMSET", false);
    bindings.put("DECLARE_ASM_MODULE_EXPORTS", false);
    bindings.put("EMULATE_FUNCTION_POINTER_CASTS", false);
    bindings.put("SUPPORT_LONGJMP", false);
    bindings.put("SUPPORT_ERRNO", false);
    bindings.put("PROXY_POSIX_SOCKETS", 0);
    bindings.put("SOCKET_WEBRTC", false);
    bindings.put("ENVIRONMENT_MAY_BE_WEB", true);
    bindings.put("MAIN_MODULE", 0);
    bindings.put("USE_ASAN", false);
    bindings.put("FULL_ES3", true);
    bindings.put("library_webgl.js", true);
    engine.setBindings(bindings, ScriptContext.GLOBAL_SCOPE);
    engine.eval("var LibraryManager = {\"has\":function(){return true;}}");

    String json = "{\"name\": \"world\"}";
    JsonNode jsonNode = new ObjectMapper().readValue(json, JsonNode.class);
    Handlebars handlebars = new Handlebars();
    handlebars.registerHelper("json", Jackson2Helper.INSTANCE);

    Context context = Context
        .newBuilder(jsonNode)
        .resolver(JsonNodeValueResolver.INSTANCE,
                JavaBeanValueResolver.INSTANCE,
                FieldValueResolver.INSTANCE,
                MapValueResolver.INSTANCE,
                MethodValueResolver.INSTANCE
        )
        .build();

    handlebars.registerHelper("ifCond", new Helper<String>() {

        public Object apply(String context, Options options) throws IOException {
            try {
                return engine.eval(context)!=null && engine.eval(context).toString().equals("true") ? options.fn(this) : options.inverse(this);
            } catch (Exception e) {
                System.err.println("Unable to process: " + context);
                return options.inverse(this);
            }
        }

    });

    Scanner s = new Scanner(new File("C:\\emsdk-1.39.13\\upstream\\emscripten\\src\\library.js"));
    StringBuffer sb = new StringBuffer();
    while(s.hasNextLine()) {
        String line = s.nextLine();
        if(line.startsWith("#if")) {
            if(line.indexOf("//")!=-1)
                line = line.substring(0, line.indexOf("//"));
            line = line.substring(4);
            sb.append("{{#ifCond \"" + line + "\"}}\r\n");
        }else if(line.startsWith("#else")) {
            if(line.indexOf("//")!=-1)
                line = line.substring(0, line.indexOf("//"));
            sb.append("{{" + line.substring(1) + "}}\r\n");
        }else if(line.startsWith("#endif")) {
            if(line.indexOf("//")!=-1)
                line = line.substring(0, line.indexOf("//"));
            sb.append("{{/ifCond}}\r\n");
        }else {
            while(line.indexOf("{{{")!=-1) {
                line = line.replace("{{{", "");
            }
            while(line.indexOf("}}}")!=-1) {
                line = line.replace("}}}", "");
            }
            sb.append(line + "\r\n");
        }
    }
    s.close();

    Template template = handlebars.compileInline(sb.toString());
    System.out.println(template.apply(context));

现在 if 分支问题已经解决了

关于java - 使用java嵌套#if宏处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61441061/

相关文章:

javascript - Emscripten - 编译为 WASM 并在胶水代码中保留原始可调用函数名称

javascript - 使用 asm.js/emscripten/SDL 时如何获取所有关键状态?

java - 找不到媒体类型 = application/json 的 MessageBodyReader - android

Java - 扩展给定对象的任何实例的方法参数

javascript - 如何使用 Emscripten 将 Hello Word 从 Swift 编译为 JavaScript

java - 如何正确输入带撇号的单词?像 "wouldn' t"和 "couldn' t"这样的词被放入 ArrayList 中作为 "wouldn"和 "couldn"

java - 我的代码中线程 "main"java.util.NoSuchElementException 中出现异常?

java - 将对象存储在静态类中的散列中是否安全,使用线程 ID 检索该特定线程的值?

java - 关于解析多个Spring View Resolver的一些问题

java - 如何将非图形用户界面的 Java 程序构建为控制台程序