mirror of
https://github.com/msojocs/wx-compiler.git
synced 2025-07-19 00:00:04 +08:00
feat: wcsc module
This commit is contained in:
parent
4f1bc9af6d
commit
fd1712480c
3
.github/workflows/release.yml
vendored
3
.github/workflows/release.yml
vendored
@ -66,7 +66,7 @@ jobs:
|
||||
echo "------------------------"
|
||||
ls -l build
|
||||
mkdir -p tmp/build
|
||||
mv build/{wcc,wcsc,wcc_module.node} tmp/build
|
||||
mv build/{wcc,wcsc,wcc_module.node,wcsc_module.node} tmp/build
|
||||
cd tmp/build
|
||||
ls -l
|
||||
|
||||
@ -140,6 +140,7 @@ jobs:
|
||||
cp **build/wcc build
|
||||
cp **build/wcsc build
|
||||
cp **build/wcc_module.node build
|
||||
cp **build/wcsc_module.node build
|
||||
chmod +x build/*
|
||||
ls -l build
|
||||
node -v
|
||||
|
@ -5,6 +5,6 @@ module.exports = {
|
||||
],
|
||||
recursive: true,
|
||||
spec: "./test/spec/**/*.spec.ts",
|
||||
// spec: "test/spec/wcc/module/module.spec.ts",
|
||||
// spec: "test/spec/wcsc/module/module.spec.ts",
|
||||
timeout: 20000,
|
||||
}
|
@ -10,6 +10,8 @@ cmake ..
|
||||
cmake --build . --config Release --target wcc
|
||||
cmake --build . --config Release --target wcsc
|
||||
cmake --build . --config Release --target wcc_module
|
||||
cmake --build . --config Release --target wcsc_module
|
||||
readelf -s ./wcc | grep -oP "GLIBC.*" | sort | uniq
|
||||
readelf -s ./wcsc | grep -oP "GLIBC.*" | sort | uniq
|
||||
readelf -s ./wcc_module.node | grep -oP "GLIBC.*" | sort | uniq
|
||||
readelf -s ./wcc_module.node | grep -oP "GLIBC.*" | sort | uniq
|
||||
readelf -s ./wcsc_module.node | grep -oP "GLIBC.*" | sort | uniq
|
@ -1,5 +1,6 @@
|
||||
#ifndef __FILE_H__
|
||||
#define __FILE_H__
|
||||
#include <string>
|
||||
|
||||
int readFile (const char* fileName, std::string &result);
|
||||
std::string getNextArg(std::string &data, std::string const & lineEndMark);
|
||||
|
@ -94,3 +94,33 @@ set_target_properties(wcc_module PROPERTIES PREFIX "" SUFFIX ".node")
|
||||
# target_link_libraries(wcc_module ${CMAKE_CURRENT_SOURCE_DIR}/lib/nw-v${NW_VERSION}.lib)
|
||||
# target_link_libraries(wcc_module ${CMAKE_CURRENT_SOURCE_DIR}/lib/node-v${NW_VERSION}.lib)
|
||||
|
||||
|
||||
add_library(wcsc_module
|
||||
SHARED
|
||||
./wcsc.cpp
|
||||
./config/wcsc.cc
|
||||
../wcsc/usage.cpp
|
||||
../wxa/wxa.cpp
|
||||
../wxml/common.cpp
|
||||
../wxml/rewrite.cpp
|
||||
../wxml/rpx.cpp
|
||||
../wxss/common.cpp
|
||||
../wxss/token.cpp
|
||||
../wxss/tokenizer.cpp
|
||||
../wxss/x_compiler.cpp
|
||||
../wxss/css_tree_lib/css_tree_lib.cpp
|
||||
../wxss/css_tree_lib/base.cpp
|
||||
../wxss/css_tree_lib/css_syntax_tree.cpp
|
||||
../wxss/css_tree_lib/lexical_checker.cpp
|
||||
../wxss/css_tree_lib/parser.cpp
|
||||
../wxss/css_tree_lib/rule.cpp
|
||||
../wxss/css_tree_lib/transit_table.cpp
|
||||
../utils/bittest.cpp
|
||||
../utils/json.cpp
|
||||
../utils/string_utils.cpp
|
||||
../utils/file.cpp
|
||||
)
|
||||
set_target_properties(wcsc_module PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
# DV8_COMPRESS_POINTERS: 缺少会导致IsString崩溃
|
||||
target_compile_options(wcsc_module PRIVATE "-DNODE_GYP_MODULE_NAME=binding" "-DUSING_UV_SHARED=1" "-DUSING_V8_SHARED=1" "-DV8_DEPRECATION_WARNINGS=1" "-DV8_DEPRECATION_WARNINGS" "-DV8_REVERSE_JSARGS" "-D_GLIBCXX_USE_CXX11_ABI=1" "-D_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS" "-D_LARGEFILE_SOURCE" "-D_FILE_OFFSET_BITS=64" "-DV8_COMPRESS_POINTERS" "-DV8_31BIT_SMIS_ON_64BIT_ARCH" "-D__STDC_FORMAT_MACROS" "-DOPENSSL_NO_PINSHARED" "-DOPENSSL_THREADS" "-DOPENSSL_NO_ASM" "-DBUILDING_NODE_EXTENSION")
|
||||
set_target_properties(wcsc_module PROPERTIES PREFIX "" SUFFIX ".node")
|
||||
|
@ -0,0 +1,179 @@
|
||||
#include "../include/wcsc.hh"
|
||||
#include "v8.h"
|
||||
|
||||
namespace wcsc_options
|
||||
{
|
||||
using v8::Local;
|
||||
using v8::String;
|
||||
using v8::Value;
|
||||
|
||||
bool get_boolean_property(v8::Isolate *isolate, v8::Local<v8::Object> &src, const char *property_name, bool &out_value)
|
||||
{
|
||||
v8::Local<v8::String> key = v8::String::NewFromUtf8(isolate, property_name, v8::NewStringType::kNormal).ToLocalChecked();
|
||||
v8::Local<v8::Value> value;
|
||||
v8::Local<v8::Context> context = isolate->GetCurrentContext();
|
||||
|
||||
if (!src->Get(context, key).ToLocal(&value))
|
||||
{
|
||||
isolate->ThrowException(v8::String::NewFromUtf8(isolate, ("Failed to get '" + std::string(property_name) + "' property").c_str(), v8::NewStringType::kNormal).ToLocalChecked());
|
||||
return false;
|
||||
}
|
||||
if (!value->IsBoolean())
|
||||
{
|
||||
isolate->ThrowException(v8::String::NewFromUtf8(isolate, ("The '" + std::string(property_name) + "' property must be a boolean").c_str(), v8::NewStringType::kNormal).ToLocalChecked());
|
||||
return false;
|
||||
}
|
||||
out_value = value->BooleanValue(isolate);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool get_string_property(v8::Isolate *isolate, v8::Local<v8::Object> &src, const char *property_name, std::string &out_value)
|
||||
{
|
||||
v8::Local<v8::String> key = v8::String::NewFromUtf8(isolate, property_name, v8::NewStringType::kNormal).ToLocalChecked();
|
||||
v8::Local<v8::Value> value;
|
||||
v8::Local<v8::Context> context = isolate->GetCurrentContext();
|
||||
|
||||
if (!src->Get(context, key).ToLocal(&value))
|
||||
{
|
||||
isolate->ThrowException(v8::String::NewFromUtf8(isolate, ("Failed to get '" + std::string(property_name) + "' property").c_str(), v8::NewStringType::kNormal).ToLocalChecked());
|
||||
return false;
|
||||
}
|
||||
if (!value->IsString())
|
||||
{
|
||||
isolate->ThrowException(v8::String::NewFromUtf8(isolate, ("The '" + std::string(property_name) + "' property must be a string").c_str(), v8::NewStringType::kNormal).ToLocalChecked());
|
||||
return false;
|
||||
}
|
||||
v8::String::Utf8Value utf8Value(isolate, value);
|
||||
std::string str(*utf8Value, utf8Value.length());
|
||||
out_value = str;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool get_integer_property(v8::Isolate *isolate, v8::Local<v8::Object> &src, const char *property_name, int &out_value)
|
||||
{
|
||||
v8::Local<v8::String> key = v8::String::NewFromUtf8(isolate, property_name, v8::NewStringType::kNormal).ToLocalChecked();
|
||||
v8::Local<v8::Value> value;
|
||||
v8::Local<v8::Context> context = isolate->GetCurrentContext();
|
||||
|
||||
if (!src->Get(context, key).ToLocal(&value))
|
||||
{
|
||||
isolate->ThrowException(v8::String::NewFromUtf8(isolate, ("Failed to get '" + std::string(property_name) + "' property").c_str(), v8::NewStringType::kNormal).ToLocalChecked());
|
||||
return false;
|
||||
}
|
||||
if (!value->IsInt32())
|
||||
{
|
||||
isolate->ThrowException(v8::String::NewFromUtf8(isolate, ("The '" + std::string(property_name) + "' property must be a int32").c_str(), v8::NewStringType::kNormal).ToLocalChecked());
|
||||
return false;
|
||||
}
|
||||
out_value = value->Int32Value(isolate->GetCurrentContext()).ToChecked();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool get_vector_string_property(v8::Isolate *isolate, v8::Local<v8::Object> &src, const char *property_name, std::vector<std::string> &out_value)
|
||||
{
|
||||
v8::Local<v8::String> key = v8::String::NewFromUtf8(isolate, property_name, v8::NewStringType::kNormal).ToLocalChecked();
|
||||
v8::Local<v8::Value> value;
|
||||
v8::Local<v8::Context> context = isolate->GetCurrentContext();
|
||||
|
||||
if (!src->Get(context, key).ToLocal(&value))
|
||||
{
|
||||
isolate->ThrowException(v8::String::NewFromUtf8(isolate, ("Failed to get '" + std::string(property_name) + "' property").c_str(), v8::NewStringType::kNormal).ToLocalChecked());
|
||||
return false;
|
||||
}
|
||||
if (!value->IsArray())
|
||||
{
|
||||
isolate->ThrowException(v8::String::NewFromUtf8(isolate, ("The '" + std::string(property_name) + "' property must be a array").c_str(), v8::NewStringType::kNormal).ToLocalChecked());
|
||||
return false;
|
||||
}
|
||||
auto arr = value.As<v8::Array>();
|
||||
for (int i=0; i < arr->Length(); i++)
|
||||
{
|
||||
v8::Local<v8::Value> v;
|
||||
if (!arr->Get(context, i).ToLocal(&v))
|
||||
{
|
||||
isolate->ThrowException(v8::String::NewFromUtf8(isolate, ("Failed to get '" + std::string(property_name) + "' property").c_str(), v8::NewStringType::kNormal).ToLocalChecked());
|
||||
return false;
|
||||
}
|
||||
if (!v->IsString())
|
||||
{
|
||||
isolate->ThrowException(v8::String::NewFromUtf8(isolate, ("The '" + std::string(property_name) + std::string("[") + std::to_string(i) +"]' property must be a string").c_str(), v8::NewStringType::kNormal).ToLocalChecked());
|
||||
return false;
|
||||
}
|
||||
v8::String::Utf8Value utf8Value(isolate, v);
|
||||
std::string str(*utf8Value, utf8Value.length());
|
||||
out_value.emplace_back(str);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool get_map_string_property(v8::Isolate *isolate, v8::Local<v8::Object> &src, const char *property_name, std::map<std::string, std::string> &out_value)
|
||||
{
|
||||
v8::Local<v8::String> key = v8::String::NewFromUtf8(isolate, property_name, v8::NewStringType::kNormal).ToLocalChecked();
|
||||
v8::Local<v8::Value> value;
|
||||
v8::Local<v8::Context> context = isolate->GetCurrentContext();
|
||||
|
||||
if (!src->Get(context, key).ToLocal(&value))
|
||||
{
|
||||
isolate->ThrowException(v8::String::NewFromUtf8(isolate, ("Failed to get '" + std::string(property_name) + "' property").c_str(), v8::NewStringType::kNormal).ToLocalChecked());
|
||||
return false;
|
||||
}
|
||||
if (!value->IsObject())
|
||||
{
|
||||
isolate->ThrowException(v8::String::NewFromUtf8(isolate, ("The '" + std::string(property_name) + "' property must be a object").c_str(), v8::NewStringType::kNormal).ToLocalChecked());
|
||||
return false;
|
||||
}
|
||||
auto obj = value.As<v8::Object>();
|
||||
auto keys = obj->GetPropertyNames(context).ToLocalChecked();
|
||||
|
||||
for (int i = 0; i < keys->Length(); i++)
|
||||
{
|
||||
// key
|
||||
v8::Local<v8::Value> k;
|
||||
if (!keys->Get(context, i).ToLocal(&k))
|
||||
{
|
||||
isolate->ThrowException(v8::String::NewFromUtf8(isolate, ("Failed to get '" + std::string(property_name) + "' property").c_str(), v8::NewStringType::kNormal).ToLocalChecked());
|
||||
return false;
|
||||
}
|
||||
if (!k->IsString())
|
||||
{
|
||||
isolate->ThrowException(v8::String::NewFromUtf8(isolate, ("The '" + std::string(property_name) + std::string("[") + std::to_string(i) +"]' property must be a string").c_str(), v8::NewStringType::kNormal).ToLocalChecked());
|
||||
return false;
|
||||
}
|
||||
|
||||
// value
|
||||
v8::Local<v8::Value> v;
|
||||
if (!obj->Get(context, k).ToLocal(&v))
|
||||
{
|
||||
isolate->ThrowException(v8::String::NewFromUtf8(isolate, ("Failed to get '" + std::string(property_name) + "' property").c_str(), v8::NewStringType::kNormal).ToLocalChecked());
|
||||
return false;
|
||||
}
|
||||
if (!v->IsString())
|
||||
{
|
||||
isolate->ThrowException(v8::String::NewFromUtf8(isolate, ("The '" + std::string(property_name) + std::string("[") + std::to_string(i) +"]' property must be a string").c_str(), v8::NewStringType::kNormal).ToLocalChecked());
|
||||
return false;
|
||||
}
|
||||
v8::String::Utf8Value utf8Value(isolate, k);
|
||||
std::string kr(*utf8Value, utf8Value.length());
|
||||
v8::String::Utf8Value utf8Value2(isolate, v);
|
||||
std::string vr(*utf8Value2, utf8Value2.length());
|
||||
out_value.emplace(kr, vr);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parse_wcsc_options(v8::Isolate *isolate, v8::Local<v8::Object> &src, WCSCOptions *result)
|
||||
{
|
||||
Local<v8::Context> context = isolate->GetCurrentContext();
|
||||
bool ret = get_boolean_property(isolate, src, "debug", result->debug) &&
|
||||
get_boolean_property(isolate, src, "lazyload", result->lazyload) &&
|
||||
get_string_property(isolate, src, "cwd", result->cwd) &&
|
||||
get_string_property(isolate, src, "classPrefix", result->classPrefix) &&
|
||||
get_integer_property(isolate, src, "pageCount", result->pageCount) &&
|
||||
get_vector_string_property(isolate, src, "files", result->files) &&
|
||||
get_vector_string_property(isolate, src, "contents", result->contents) &&
|
||||
get_map_string_property(isolate, src, "replaceContent", result->replaceContent);
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
24
src/module/include/wcsc.hh
Normal file
24
src/module/include/wcsc.hh
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef __WCC_HH__
|
||||
#define __WCC_HH__
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <node.h>
|
||||
|
||||
struct WCSCOptions
|
||||
{
|
||||
std::vector<std::string> files;
|
||||
std::vector<std::string> contents;
|
||||
std::map<std::string, std::string> replaceContent;
|
||||
int pageCount = 0;
|
||||
std::string cwd;
|
||||
bool debug = false;
|
||||
std::string classPrefix;
|
||||
bool lazyload;
|
||||
};
|
||||
|
||||
namespace wcsc_options
|
||||
{
|
||||
bool parse_wcsc_options(v8::Isolate *isolate, v8::Local<v8::Object> &src, WCSCOptions *result);
|
||||
}
|
||||
#endif
|
191
src/module/wcsc.cpp
Normal file
191
src/module/wcsc.cpp
Normal file
@ -0,0 +1,191 @@
|
||||
// hello.cc
|
||||
#include "./include/wcsc.hh"
|
||||
#include "../include/file.h"
|
||||
#include "../include/string_utils.h"
|
||||
#include "../include/wxss.h"
|
||||
#include "../include/wxml.h"
|
||||
#include "v8.h"
|
||||
#include <algorithm>
|
||||
#include <node.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace wx_compiler {
|
||||
|
||||
using v8::Function;
|
||||
using v8::FunctionCallbackInfo;
|
||||
using v8::FunctionTemplate;
|
||||
using v8::Isolate;
|
||||
using v8::Local;
|
||||
using v8::NewStringType;
|
||||
using v8::Object;
|
||||
using v8::String;
|
||||
using v8::Value;
|
||||
|
||||
using std::map;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
int compile(Isolate *isolate, WCSCOptions &options, Local<Value> &result,
|
||||
std::string &errMsg) {
|
||||
/**
|
||||
* 文件内容map filename -> fileContent
|
||||
*/
|
||||
std::map<std::string, std::string> v77;
|
||||
for (int i=0; i<options.files.size(); i++) {
|
||||
v77[options.files[i]] = options.contents[i];
|
||||
}
|
||||
std::string v76 = "./app.wxss";
|
||||
|
||||
if (options.lazyload) {
|
||||
// 懒加载
|
||||
|
||||
std::string v96;
|
||||
|
||||
std::string v94, v75;
|
||||
WXSS::XCompiler lt(v77, options.debug, v75);
|
||||
// lt.offset_136.erase()
|
||||
// lt.offset_136.erase()
|
||||
|
||||
v96.assign(lt.offset_8);
|
||||
std::map<std::string, std::string> v92;
|
||||
if (!lt.offset_0) {
|
||||
std::vector<std::string> v72;
|
||||
for (int i=0; i<options.pageCount; i++) {
|
||||
v72.push_back(options.files[i]);
|
||||
}
|
||||
int ret = lt.GetCommHead(v72, v94, true, v76);
|
||||
if (ret) {
|
||||
fprintf(stderr, "ERR: GetCommHead ret %d", ret);
|
||||
}
|
||||
for (int i = 0; i < v72.size(); i++) {
|
||||
std::string v98;
|
||||
std::string cur = v72[i];
|
||||
std::string v101 = WXML::Rewrite::ToStringCode(cur);
|
||||
ret = lt.GetPageCss(v101, v98, 0);
|
||||
if (ret) {
|
||||
fprintf(stderr, "INFO: GetPageCss fail ret %d", ret);
|
||||
}
|
||||
v92.emplace(cur, v98);
|
||||
}
|
||||
v8::Local<v8::Object> pageWxss = v8::Object::New(isolate);
|
||||
for (auto func : v92) {
|
||||
pageWxss
|
||||
->Set(isolate->GetCurrentContext(),
|
||||
String::NewFromUtf8(isolate, func.first.c_str(),
|
||||
v8::NewStringType::kNormal)
|
||||
.ToLocalChecked(),
|
||||
String::NewFromUtf8(isolate, func.second.c_str(),
|
||||
v8::NewStringType::kNormal)
|
||||
.ToLocalChecked())
|
||||
.Check();
|
||||
}
|
||||
|
||||
v8::Local<v8::Object> object_instance = v8::Object::New(isolate);
|
||||
auto _ = object_instance->Set(isolate->GetCurrentContext(),
|
||||
String::NewFromUtf8(isolate, "common",
|
||||
v8::NewStringType::kNormal)
|
||||
.ToLocalChecked(),
|
||||
String::NewFromUtf8(isolate, v94.c_str(),
|
||||
v8::NewStringType::kNormal).ToLocalChecked());
|
||||
_ = object_instance->Set(isolate->GetCurrentContext(),
|
||||
String::NewFromUtf8(isolate,
|
||||
"pageWxss",
|
||||
v8::NewStringType::kNormal)
|
||||
.ToLocalChecked(),
|
||||
pageWxss);
|
||||
result = object_instance;
|
||||
|
||||
if (ret) {
|
||||
fprintf(stderr, "ERR: %s\nerror file count: %d\n", "", 0);
|
||||
return 1;
|
||||
}
|
||||
// main - 25 - 9
|
||||
return 0;
|
||||
}
|
||||
std::string ret = "ERR: wxss GetCompiledResult: " + v96 + ", error file count: " + std::to_string(lt.offset_4) + ", ret " + std::to_string(lt.offset_0);
|
||||
auto r = String::NewFromUtf8(isolate, ret.c_str(),
|
||||
v8::NewStringType::kNormal)
|
||||
.ToLocalChecked();
|
||||
fprintf(stderr,
|
||||
"ERR: wxss GetCompiledResult: %s, error file count: %d, ret %d",
|
||||
v96.data(), lt.offset_4, lt.offset_0);
|
||||
return 1;
|
||||
} else {
|
||||
// 普通
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void wcc(const FunctionCallbackInfo<Value> &args) {
|
||||
Isolate *isolate = args.GetIsolate();
|
||||
v8::HandleScope scope(isolate); // Ensure we have a proper handle scope.
|
||||
|
||||
// Check if the first argument is an object.
|
||||
if (args.Length() < 1 || !args[0]->IsObject()) {
|
||||
isolate->ThrowException(String::NewFromUtf8(isolate,
|
||||
"Argument must be an object",
|
||||
NewStringType::kNormal)
|
||||
.ToLocalChecked());
|
||||
return;
|
||||
}
|
||||
|
||||
// Cast the first argument to an Object.
|
||||
Local<v8::Context> context = isolate->GetCurrentContext();
|
||||
Local<Object> obj = args[0]->ToObject(context).ToLocalChecked();
|
||||
|
||||
WCSCOptions options;
|
||||
if (!wcsc_options::parse_wcsc_options(isolate, obj, &options)) {
|
||||
// 选项解析失败
|
||||
return;
|
||||
}
|
||||
|
||||
Local<Value> result;
|
||||
std::string errMsg;
|
||||
int code = compile(isolate, options, result, errMsg);
|
||||
|
||||
// Convert the "msg" property to a C++ string and return it.
|
||||
if (code) {
|
||||
// error
|
||||
args.GetReturnValue().Set(
|
||||
String::NewFromUtf8(isolate, errMsg.c_str(), NewStringType::kNormal)
|
||||
.ToLocalChecked());
|
||||
} else {
|
||||
// ok
|
||||
args.GetReturnValue().Set(result);
|
||||
}
|
||||
}
|
||||
|
||||
void Initialize(Local<Object> exports, Local<Object> module) {
|
||||
|
||||
Isolate *isolate = exports->GetIsolate();
|
||||
auto context = isolate->GetCurrentContext();
|
||||
|
||||
std::string versionInfo;
|
||||
// TODO
|
||||
// WXML::Compiler::GetVersionInfo(versionInfo, "global");
|
||||
|
||||
// Set the module.exports to be a function
|
||||
Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, wcc);
|
||||
Local<Function> fn = tpl->GetFunction(context).ToLocalChecked();
|
||||
|
||||
// Set the 'version' property on the function
|
||||
fn->Set(context,
|
||||
String::NewFromUtf8(isolate, "version", NewStringType::kNormal)
|
||||
.ToLocalChecked(),
|
||||
String::NewFromUtf8(isolate, versionInfo.c_str(),
|
||||
NewStringType::kNormal)
|
||||
.ToLocalChecked())
|
||||
.Check();
|
||||
|
||||
module
|
||||
->Set(context,
|
||||
String::NewFromUtf8(isolate, "exports", NewStringType::kNormal)
|
||||
.ToLocalChecked(),
|
||||
fn)
|
||||
.Check();
|
||||
}
|
||||
|
||||
NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)
|
||||
|
||||
} // namespace wx_compiler
|
28
src/wcsc.cpp
28
src/wcsc.cpp
@ -1,5 +1,3 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "./include/usage.h"
|
||||
@ -57,7 +55,7 @@ int main(int argc, const char **argv) {
|
||||
std::vector<std::string> v66;
|
||||
std::string v75, v83;
|
||||
int v29 = 0;
|
||||
bool v30 = false;
|
||||
bool hasPageCount = false;
|
||||
bool v31 = false;
|
||||
bool v32 = false;
|
||||
bool v34 = false;
|
||||
@ -75,8 +73,8 @@ int main(int argc, const char **argv) {
|
||||
v66.emplace_back(v69[i]);
|
||||
continue;
|
||||
}
|
||||
v75 = i;
|
||||
v56 = false;
|
||||
// v75 = i;
|
||||
continue;
|
||||
}
|
||||
switch(cur[1])
|
||||
@ -96,12 +94,14 @@ int main(int argc, const char **argv) {
|
||||
{
|
||||
if (cur[2] == 't')
|
||||
{
|
||||
// print tree
|
||||
v56 = false;
|
||||
v34 = true;
|
||||
continue;
|
||||
}
|
||||
if (cur[2] == 'd')
|
||||
{
|
||||
// 'someclass { font-size: 18px }'
|
||||
if (v69.size() > i + 1)
|
||||
{
|
||||
i++;
|
||||
@ -136,6 +136,7 @@ int main(int argc, const char **argv) {
|
||||
case 'd':
|
||||
if (cur[2] == 'b')
|
||||
{
|
||||
// add debug attr
|
||||
v56 = false;
|
||||
v37 = true;
|
||||
continue;
|
||||
@ -144,6 +145,7 @@ int main(int argc, const char **argv) {
|
||||
case 'j':
|
||||
if (cur[2] == 's')
|
||||
{
|
||||
// js formate output
|
||||
v56 = false;
|
||||
v31 = true;
|
||||
continue;
|
||||
@ -152,6 +154,7 @@ int main(int argc, const char **argv) {
|
||||
case 'c':
|
||||
if (cur[2] == 'p')
|
||||
{
|
||||
// add class prefix
|
||||
v56 = true;
|
||||
continue;
|
||||
}
|
||||
@ -159,7 +162,8 @@ int main(int argc, const char **argv) {
|
||||
default:
|
||||
if (cur[1] == 'p' && cur[2] == 'c')
|
||||
{
|
||||
v30 = true;
|
||||
// page wxss files count
|
||||
hasPageCount = true;
|
||||
v29 = atoi(v69[i + 1].data());
|
||||
i++;
|
||||
v56 = false;
|
||||
@ -208,17 +212,17 @@ int main(int argc, const char **argv) {
|
||||
}
|
||||
|
||||
// main - 25
|
||||
std::string v88, v90;
|
||||
std::string v88, errMsg;
|
||||
std::vector<std::string> v72;
|
||||
if (!v30)
|
||||
if (!hasPageCount)
|
||||
{
|
||||
if (!v36)
|
||||
{
|
||||
int v25;
|
||||
v25 = WXSS::LintAndParseCSSList(v77, v66[0], v88, v90, 0, v31, v37, v34, v75);
|
||||
v25 = WXSS::LintAndParseCSSList(v77, v66[0], v88, errMsg, 0, v31, v37, v34, v75);
|
||||
if (v25)
|
||||
{
|
||||
fprintf(stderr, "ERR: %s\nerror file count: %d\n", v90.data(), 0);
|
||||
fprintf(stderr, "ERR: %s\nerror file count: %d\n", errMsg.data(), 0);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@ -264,7 +268,7 @@ int main(int argc, const char **argv) {
|
||||
|
||||
if (ret)
|
||||
{
|
||||
fprintf(stderr, "ERR: %s\nerror file count: %d\n", v90.data(), 0);
|
||||
fprintf(stderr, "ERR: %s\nerror file count: %d\n", errMsg.data(), 0);
|
||||
return 1;
|
||||
}
|
||||
fprintf(f, "%s", v101.data());
|
||||
@ -293,11 +297,11 @@ int main(int argc, const char **argv) {
|
||||
{
|
||||
goto LABEL_102;
|
||||
}
|
||||
int v25 = WXSS::NewLintAndParseCSSList(v77, v72, v88, v90, 0, v37, v75, v76);
|
||||
int v25 = WXSS::NewLintAndParseCSSList(v77, v72, v88, errMsg, 0, v37, v75, v76);
|
||||
|
||||
if (v25)
|
||||
{
|
||||
fprintf(stderr, "ERR: %s\nerror file count: %d\n", v90.data(), 0);
|
||||
fprintf(stderr, "ERR: %s\nerror file count: %d\n", errMsg.data(), 0);
|
||||
return 1;
|
||||
}
|
||||
fprintf(f, "%s", v88.data());
|
||||
|
@ -28,7 +28,7 @@ namespace WXSS
|
||||
std::map<std::string,std::string> const& a1,
|
||||
std::string& a2,
|
||||
std::string& a3,
|
||||
std::string& a4,
|
||||
std::string& errMsg,
|
||||
int a5,
|
||||
bool a6,
|
||||
bool a7,
|
||||
@ -36,7 +36,7 @@ namespace WXSS
|
||||
std::string const& a9)
|
||||
{
|
||||
WXSS::XCompiler v12(a1, a7, a9);
|
||||
a4.assign(v12.offset_8);
|
||||
errMsg.assign(v12.offset_8);
|
||||
int ret = v12.offset_0;
|
||||
if (!v12.offset_0)
|
||||
{
|
||||
|
@ -13,12 +13,12 @@ namespace WXSS
|
||||
{
|
||||
}
|
||||
|
||||
int Parser::Parse(std::string const& a2, std::string const& a3, std::string& a4, std::string const& a5)
|
||||
int Parser::Parse(std::string const& a2, std::string const& a3, std::string& errMsg, std::string const& a5)
|
||||
{
|
||||
// Parse - 0
|
||||
WXSS::Tokenizer v125(a2.data(), a3);
|
||||
std::vector<WXSS::Token> v118;
|
||||
int ret = v125.GetTokens(v118, a4, -1);
|
||||
int ret = v125.GetTokens(v118, errMsg, -1);
|
||||
if (ret)
|
||||
{
|
||||
return ret;
|
||||
@ -155,7 +155,7 @@ namespace WXSS
|
||||
}
|
||||
v135 << v41;
|
||||
v135 << "`";
|
||||
a4 = v135.str();
|
||||
errMsg = v135.str();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -164,7 +164,7 @@ namespace WXSS
|
||||
v135 << ":";
|
||||
v135 << cur.offset_24;
|
||||
v135 << "): unexpected end of input or bad input";
|
||||
a4 = v135.str();
|
||||
errMsg = v135.str();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@ -190,14 +190,14 @@ namespace WXSS
|
||||
{
|
||||
if (this->offset_48.begin() == this->offset_48.end())
|
||||
{
|
||||
a4 = "interal error: 1001";
|
||||
errMsg = "interal error: 1001";
|
||||
return 1001;
|
||||
}
|
||||
auto v44 = this->offset_48.back();
|
||||
this->offset_48.pop_back();
|
||||
if (this->offset_48.begin() == this->offset_48.end())
|
||||
{
|
||||
a4 = "interal error: 1002";
|
||||
errMsg = "interal error: 1002";
|
||||
return 1002;
|
||||
}
|
||||
auto v45 = this->offset_48.back();
|
||||
@ -219,7 +219,7 @@ namespace WXSS
|
||||
{
|
||||
if (this->offset_48.begin() == this->offset_48.end())
|
||||
{
|
||||
a4 = "interal error: 1003";
|
||||
errMsg = "interal error: 1003";
|
||||
return 1003;
|
||||
}
|
||||
auto v47 = this->offset_48.back();
|
||||
@ -283,7 +283,7 @@ namespace WXSS
|
||||
}
|
||||
}
|
||||
v135 << v63 << "`";
|
||||
a4 = v135.str();
|
||||
errMsg = v135.str();
|
||||
return -1;
|
||||
}
|
||||
this->offset_8.pop_back();
|
||||
@ -304,7 +304,7 @@ namespace WXSS
|
||||
// Parse - 25
|
||||
if (this->offset_48.begin() == this->offset_48.end())
|
||||
{
|
||||
a4 = "interal error: 1004";
|
||||
errMsg = "interal error: 1004";
|
||||
return 1004;
|
||||
}
|
||||
else
|
||||
|
@ -5,13 +5,10 @@ import * as fs from 'fs'
|
||||
const NW_VERSION = '0.55.0'
|
||||
|
||||
const wcscNative = (optionsPath: string, projectPath: string, outputPath: string | undefined = undefined): Promise<string> => {
|
||||
if(!fs.existsSync(projectPath))
|
||||
{
|
||||
throw new Error('projectPath not exists.')
|
||||
}
|
||||
|
||||
const nodeExec = spawn(
|
||||
path.resolve(__dirname, `../../../cache/nwjs-sdk-v${NW_VERSION}-linux-x64/nw`),
|
||||
[ 'wcsc.js', optionsPath ],
|
||||
path.resolve(__dirname, `../../cache/nwjs-sdk-v${NW_VERSION}-linux-x64/nw`),
|
||||
[ path.resolve(__dirname, './nwjs/compiler.js'), 'wcsc', optionsPath ],
|
||||
{
|
||||
cwd: projectPath,
|
||||
env: {
|
||||
@ -36,7 +33,9 @@ const wcscNative = (optionsPath: string, projectPath: string, outputPath: string
|
||||
|
||||
if (0 === n) {
|
||||
let result = Buffer.concat(spwanData).toString();
|
||||
// result = JSON.parse(result);
|
||||
result = result.split('---------------result------------------\n')[1]
|
||||
if (result[0] === '{')
|
||||
result = JSON.parse(result);
|
||||
resolve(result);
|
||||
} else {
|
||||
// process.stderr.write(Buffer.concat(errData).toString());
|
||||
|
@ -39,7 +39,7 @@ const HTTP = {
|
||||
{
|
||||
console.log('error:', ret)
|
||||
}
|
||||
if (compilerOptions.lazyloadConfig)
|
||||
if (compilerOptions.lazyloadConfig || compilerOptions.lazyload)
|
||||
{
|
||||
resolve(JSON.parse(ret))
|
||||
}
|
||||
|
1
test/runner/types.d.ts
vendored
1
test/runner/types.d.ts
vendored
@ -8,5 +8,6 @@ export interface CompilerOptions {
|
||||
wxmlCompileConfigSplit: string
|
||||
replaceContent: Record<string, string>
|
||||
cwd: string
|
||||
lazyload: boolean
|
||||
lazyloadConfig: string
|
||||
}
|
499
test/spec/wcsc/module/data/1720324528222-wcsc-options.json
Normal file
499
test/spec/wcsc/module/data/1720324528222-wcsc-options.json
Normal file
File diff suppressed because one or more lines are too long
62
test/spec/wcsc/module/module.spec.ts
Normal file
62
test/spec/wcsc/module/module.spec.ts
Normal file
@ -0,0 +1,62 @@
|
||||
|
||||
import assert from 'assert';
|
||||
import { describe } from "mocha";
|
||||
import path from 'path';
|
||||
import linux from '../../../runner/module-linux'
|
||||
import windows from '../../../runner/module-windows'
|
||||
import * as fs from 'fs'
|
||||
|
||||
windows.start()
|
||||
describe("wcsc - module", function () {
|
||||
this.afterAll(() => {
|
||||
windows.close()
|
||||
})
|
||||
describe("linux output should deep equal with wine", function () {
|
||||
// afterEach(function(){
|
||||
// if(this.currentTest.state === 'failed'){
|
||||
// console.error('failed', this.currentTest)
|
||||
// }
|
||||
// })
|
||||
it("初次加载1", async function () {
|
||||
const p = path.resolve(__dirname, './data/1720324528222-wcsc-options.json')
|
||||
const storagePath = path.resolve(
|
||||
__dirname,
|
||||
`miniprogram-demo/${this.test?.title}`
|
||||
);
|
||||
try {
|
||||
fs.mkdirSync(storagePath, { recursive: true });
|
||||
} catch (error) {}
|
||||
|
||||
const w = await windows.wcsc(p);
|
||||
console.log('windows:', typeof w)
|
||||
const n = await linux.wcsc(p, '');
|
||||
console.log('linux:', typeof n)
|
||||
|
||||
assert.equal(typeof n, typeof w);
|
||||
if (typeof w == 'string')
|
||||
{
|
||||
fs.writeFileSync(
|
||||
`${storagePath}/wine-output.json`,
|
||||
w
|
||||
);
|
||||
fs.writeFileSync(
|
||||
`${storagePath}/node-output.json`,
|
||||
n as string
|
||||
);
|
||||
assert.equal(n, w);
|
||||
}
|
||||
else
|
||||
{
|
||||
fs.writeFileSync(
|
||||
`${storagePath}/wine-output.json`,
|
||||
JSON.stringify(w, null, 4)
|
||||
);
|
||||
fs.writeFileSync(
|
||||
`${storagePath}/node-output.json`,
|
||||
JSON.stringify(n, null, 4)
|
||||
);
|
||||
assert.deepEqual(n, w);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
@ -172064,7 +172064,7 @@ int __cdecl main(int argc, const char **argv, const char **envp)
|
||||
v11 = 6 * v9;
|
||||
v12 = &v60[6 * v9];
|
||||
v13 = *v12;
|
||||
if ( *(_BYTE *)*v12 != 45 )
|
||||
if ( *(_BYTE *)*v12 != 45 ) // '-'
|
||||
{
|
||||
v39 = &v60[6 * v9];
|
||||
if ( !v10 )
|
||||
|
Loading…
x
Reference in New Issue
Block a user