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 "------------------------"
|
echo "------------------------"
|
||||||
ls -l build
|
ls -l build
|
||||||
mkdir -p tmp/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
|
cd tmp/build
|
||||||
ls -l
|
ls -l
|
||||||
|
|
||||||
@ -140,6 +140,7 @@ jobs:
|
|||||||
cp **build/wcc build
|
cp **build/wcc build
|
||||||
cp **build/wcsc build
|
cp **build/wcsc build
|
||||||
cp **build/wcc_module.node build
|
cp **build/wcc_module.node build
|
||||||
|
cp **build/wcsc_module.node build
|
||||||
chmod +x build/*
|
chmod +x build/*
|
||||||
ls -l build
|
ls -l build
|
||||||
node -v
|
node -v
|
||||||
|
@ -5,6 +5,6 @@ module.exports = {
|
|||||||
],
|
],
|
||||||
recursive: true,
|
recursive: true,
|
||||||
spec: "./test/spec/**/*.spec.ts",
|
spec: "./test/spec/**/*.spec.ts",
|
||||||
// spec: "test/spec/wcc/module/module.spec.ts",
|
// spec: "test/spec/wcsc/module/module.spec.ts",
|
||||||
timeout: 20000,
|
timeout: 20000,
|
||||||
}
|
}
|
@ -10,6 +10,8 @@ cmake ..
|
|||||||
cmake --build . --config Release --target wcc
|
cmake --build . --config Release --target wcc
|
||||||
cmake --build . --config Release --target wcsc
|
cmake --build . --config Release --target wcsc
|
||||||
cmake --build . --config Release --target wcc_module
|
cmake --build . --config Release --target wcc_module
|
||||||
|
cmake --build . --config Release --target wcsc_module
|
||||||
readelf -s ./wcc | grep -oP "GLIBC.*" | sort | uniq
|
readelf -s ./wcc | grep -oP "GLIBC.*" | sort | uniq
|
||||||
readelf -s ./wcsc | 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__
|
#ifndef __FILE_H__
|
||||||
#define __FILE_H__
|
#define __FILE_H__
|
||||||
|
#include <string>
|
||||||
|
|
||||||
int readFile (const char* fileName, std::string &result);
|
int readFile (const char* fileName, std::string &result);
|
||||||
std::string getNextArg(std::string &data, std::string const & lineEndMark);
|
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/nw-v${NW_VERSION}.lib)
|
||||||
# target_link_libraries(wcc_module ${CMAKE_CURRENT_SOURCE_DIR}/lib/node-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 <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include "./include/usage.h"
|
#include "./include/usage.h"
|
||||||
@ -57,7 +55,7 @@ int main(int argc, const char **argv) {
|
|||||||
std::vector<std::string> v66;
|
std::vector<std::string> v66;
|
||||||
std::string v75, v83;
|
std::string v75, v83;
|
||||||
int v29 = 0;
|
int v29 = 0;
|
||||||
bool v30 = false;
|
bool hasPageCount = false;
|
||||||
bool v31 = false;
|
bool v31 = false;
|
||||||
bool v32 = false;
|
bool v32 = false;
|
||||||
bool v34 = false;
|
bool v34 = false;
|
||||||
@ -75,8 +73,8 @@ int main(int argc, const char **argv) {
|
|||||||
v66.emplace_back(v69[i]);
|
v66.emplace_back(v69[i]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
v75 = i;
|
|
||||||
v56 = false;
|
v56 = false;
|
||||||
|
// v75 = i;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
switch(cur[1])
|
switch(cur[1])
|
||||||
@ -96,12 +94,14 @@ int main(int argc, const char **argv) {
|
|||||||
{
|
{
|
||||||
if (cur[2] == 't')
|
if (cur[2] == 't')
|
||||||
{
|
{
|
||||||
|
// print tree
|
||||||
v56 = false;
|
v56 = false;
|
||||||
v34 = true;
|
v34 = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (cur[2] == 'd')
|
if (cur[2] == 'd')
|
||||||
{
|
{
|
||||||
|
// 'someclass { font-size: 18px }'
|
||||||
if (v69.size() > i + 1)
|
if (v69.size() > i + 1)
|
||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
@ -136,6 +136,7 @@ int main(int argc, const char **argv) {
|
|||||||
case 'd':
|
case 'd':
|
||||||
if (cur[2] == 'b')
|
if (cur[2] == 'b')
|
||||||
{
|
{
|
||||||
|
// add debug attr
|
||||||
v56 = false;
|
v56 = false;
|
||||||
v37 = true;
|
v37 = true;
|
||||||
continue;
|
continue;
|
||||||
@ -144,6 +145,7 @@ int main(int argc, const char **argv) {
|
|||||||
case 'j':
|
case 'j':
|
||||||
if (cur[2] == 's')
|
if (cur[2] == 's')
|
||||||
{
|
{
|
||||||
|
// js formate output
|
||||||
v56 = false;
|
v56 = false;
|
||||||
v31 = true;
|
v31 = true;
|
||||||
continue;
|
continue;
|
||||||
@ -152,6 +154,7 @@ int main(int argc, const char **argv) {
|
|||||||
case 'c':
|
case 'c':
|
||||||
if (cur[2] == 'p')
|
if (cur[2] == 'p')
|
||||||
{
|
{
|
||||||
|
// add class prefix
|
||||||
v56 = true;
|
v56 = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -159,7 +162,8 @@ int main(int argc, const char **argv) {
|
|||||||
default:
|
default:
|
||||||
if (cur[1] == 'p' && cur[2] == 'c')
|
if (cur[1] == 'p' && cur[2] == 'c')
|
||||||
{
|
{
|
||||||
v30 = true;
|
// page wxss files count
|
||||||
|
hasPageCount = true;
|
||||||
v29 = atoi(v69[i + 1].data());
|
v29 = atoi(v69[i + 1].data());
|
||||||
i++;
|
i++;
|
||||||
v56 = false;
|
v56 = false;
|
||||||
@ -208,17 +212,17 @@ int main(int argc, const char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// main - 25
|
// main - 25
|
||||||
std::string v88, v90;
|
std::string v88, errMsg;
|
||||||
std::vector<std::string> v72;
|
std::vector<std::string> v72;
|
||||||
if (!v30)
|
if (!hasPageCount)
|
||||||
{
|
{
|
||||||
if (!v36)
|
if (!v36)
|
||||||
{
|
{
|
||||||
int v25;
|
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)
|
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 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -264,7 +268,7 @@ int main(int argc, const char **argv) {
|
|||||||
|
|
||||||
if (ret)
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
fprintf(f, "%s", v101.data());
|
fprintf(f, "%s", v101.data());
|
||||||
@ -293,11 +297,11 @@ int main(int argc, const char **argv) {
|
|||||||
{
|
{
|
||||||
goto LABEL_102;
|
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)
|
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 1;
|
||||||
}
|
}
|
||||||
fprintf(f, "%s", v88.data());
|
fprintf(f, "%s", v88.data());
|
||||||
|
@ -28,7 +28,7 @@ namespace WXSS
|
|||||||
std::map<std::string,std::string> const& a1,
|
std::map<std::string,std::string> const& a1,
|
||||||
std::string& a2,
|
std::string& a2,
|
||||||
std::string& a3,
|
std::string& a3,
|
||||||
std::string& a4,
|
std::string& errMsg,
|
||||||
int a5,
|
int a5,
|
||||||
bool a6,
|
bool a6,
|
||||||
bool a7,
|
bool a7,
|
||||||
@ -36,7 +36,7 @@ namespace WXSS
|
|||||||
std::string const& a9)
|
std::string const& a9)
|
||||||
{
|
{
|
||||||
WXSS::XCompiler v12(a1, a7, a9);
|
WXSS::XCompiler v12(a1, a7, a9);
|
||||||
a4.assign(v12.offset_8);
|
errMsg.assign(v12.offset_8);
|
||||||
int ret = v12.offset_0;
|
int ret = v12.offset_0;
|
||||||
if (!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
|
// Parse - 0
|
||||||
WXSS::Tokenizer v125(a2.data(), a3);
|
WXSS::Tokenizer v125(a2.data(), a3);
|
||||||
std::vector<WXSS::Token> v118;
|
std::vector<WXSS::Token> v118;
|
||||||
int ret = v125.GetTokens(v118, a4, -1);
|
int ret = v125.GetTokens(v118, errMsg, -1);
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
return ret;
|
return ret;
|
||||||
@ -155,7 +155,7 @@ namespace WXSS
|
|||||||
}
|
}
|
||||||
v135 << v41;
|
v135 << v41;
|
||||||
v135 << "`";
|
v135 << "`";
|
||||||
a4 = v135.str();
|
errMsg = v135.str();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -164,7 +164,7 @@ namespace WXSS
|
|||||||
v135 << ":";
|
v135 << ":";
|
||||||
v135 << cur.offset_24;
|
v135 << cur.offset_24;
|
||||||
v135 << "): unexpected end of input or bad input";
|
v135 << "): unexpected end of input or bad input";
|
||||||
a4 = v135.str();
|
errMsg = v135.str();
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -190,14 +190,14 @@ namespace WXSS
|
|||||||
{
|
{
|
||||||
if (this->offset_48.begin() == this->offset_48.end())
|
if (this->offset_48.begin() == this->offset_48.end())
|
||||||
{
|
{
|
||||||
a4 = "interal error: 1001";
|
errMsg = "interal error: 1001";
|
||||||
return 1001;
|
return 1001;
|
||||||
}
|
}
|
||||||
auto v44 = this->offset_48.back();
|
auto v44 = this->offset_48.back();
|
||||||
this->offset_48.pop_back();
|
this->offset_48.pop_back();
|
||||||
if (this->offset_48.begin() == this->offset_48.end())
|
if (this->offset_48.begin() == this->offset_48.end())
|
||||||
{
|
{
|
||||||
a4 = "interal error: 1002";
|
errMsg = "interal error: 1002";
|
||||||
return 1002;
|
return 1002;
|
||||||
}
|
}
|
||||||
auto v45 = this->offset_48.back();
|
auto v45 = this->offset_48.back();
|
||||||
@ -219,7 +219,7 @@ namespace WXSS
|
|||||||
{
|
{
|
||||||
if (this->offset_48.begin() == this->offset_48.end())
|
if (this->offset_48.begin() == this->offset_48.end())
|
||||||
{
|
{
|
||||||
a4 = "interal error: 1003";
|
errMsg = "interal error: 1003";
|
||||||
return 1003;
|
return 1003;
|
||||||
}
|
}
|
||||||
auto v47 = this->offset_48.back();
|
auto v47 = this->offset_48.back();
|
||||||
@ -283,7 +283,7 @@ namespace WXSS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
v135 << v63 << "`";
|
v135 << v63 << "`";
|
||||||
a4 = v135.str();
|
errMsg = v135.str();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
this->offset_8.pop_back();
|
this->offset_8.pop_back();
|
||||||
@ -304,7 +304,7 @@ namespace WXSS
|
|||||||
// Parse - 25
|
// Parse - 25
|
||||||
if (this->offset_48.begin() == this->offset_48.end())
|
if (this->offset_48.begin() == this->offset_48.end())
|
||||||
{
|
{
|
||||||
a4 = "interal error: 1004";
|
errMsg = "interal error: 1004";
|
||||||
return 1004;
|
return 1004;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -5,13 +5,10 @@ import * as fs from 'fs'
|
|||||||
const NW_VERSION = '0.55.0'
|
const NW_VERSION = '0.55.0'
|
||||||
|
|
||||||
const wcscNative = (optionsPath: string, projectPath: string, outputPath: string | undefined = undefined): Promise<string> => {
|
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(
|
const nodeExec = spawn(
|
||||||
path.resolve(__dirname, `../../../cache/nwjs-sdk-v${NW_VERSION}-linux-x64/nw`),
|
path.resolve(__dirname, `../../cache/nwjs-sdk-v${NW_VERSION}-linux-x64/nw`),
|
||||||
[ 'wcsc.js', optionsPath ],
|
[ path.resolve(__dirname, './nwjs/compiler.js'), 'wcsc', optionsPath ],
|
||||||
{
|
{
|
||||||
cwd: projectPath,
|
cwd: projectPath,
|
||||||
env: {
|
env: {
|
||||||
@ -36,7 +33,9 @@ const wcscNative = (optionsPath: string, projectPath: string, outputPath: string
|
|||||||
|
|
||||||
if (0 === n) {
|
if (0 === n) {
|
||||||
let result = Buffer.concat(spwanData).toString();
|
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);
|
resolve(result);
|
||||||
} else {
|
} else {
|
||||||
// process.stderr.write(Buffer.concat(errData).toString());
|
// process.stderr.write(Buffer.concat(errData).toString());
|
||||||
|
@ -39,7 +39,7 @@ const HTTP = {
|
|||||||
{
|
{
|
||||||
console.log('error:', ret)
|
console.log('error:', ret)
|
||||||
}
|
}
|
||||||
if (compilerOptions.lazyloadConfig)
|
if (compilerOptions.lazyloadConfig || compilerOptions.lazyload)
|
||||||
{
|
{
|
||||||
resolve(JSON.parse(ret))
|
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
|
wxmlCompileConfigSplit: string
|
||||||
replaceContent: Record<string, string>
|
replaceContent: Record<string, string>
|
||||||
cwd: string
|
cwd: string
|
||||||
|
lazyload: boolean
|
||||||
lazyloadConfig: string
|
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;
|
v11 = 6 * v9;
|
||||||
v12 = &v60[6 * v9];
|
v12 = &v60[6 * v9];
|
||||||
v13 = *v12;
|
v13 = *v12;
|
||||||
if ( *(_BYTE *)*v12 != 45 )
|
if ( *(_BYTE *)*v12 != 45 ) // '-'
|
||||||
{
|
{
|
||||||
v39 = &v60[6 * v9];
|
v39 = &v60[6 * v9];
|
||||||
if ( !v10 )
|
if ( !v10 )
|
||||||
|
Loading…
x
Reference in New Issue
Block a user