Skip to content

Commit

Permalink
Merge pull request #1863 from weyk/mod_prop
Browse files Browse the repository at this point in the history
「$」「.」の動作ロジックの変更
  • Loading branch information
kujirahand authored Dec 14, 2024
2 parents 678e1ed + 7c7a1a2 commit 006e476
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 6 deletions.
19 changes: 15 additions & 4 deletions core/src/nako_gen.mts
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,8 @@ export class NakoGen {
// 定数を埋め込む
code += '__self.constPools = ' + JSON.stringify(this.constPools) + ';\n'
code += '__self.constPoolsTemplate = ' + JSON.stringify(this.constPoolsTemplate) + ';\n'
//
code += '__self.__propAccessor = [];\n'
// なでしこの関数定義を行う
let nakoFuncCode = ''
this.nakoFuncList.forEach((value, key) => {
Expand Down Expand Up @@ -1855,8 +1857,10 @@ export class NakoGen {
}
}
// プロパティへの代入式を作る
code += `if (typeof ${nameJs}.__setProp === 'function') { ${nameJs}.__setProp('${propTop}', ${value}, __self); } `
code += `else { ${nameJs}['${propTop}'] = ${value} };`
code += `if (typeof ${nameJs}.__setProp === 'function') { ${nameJs}.__setProp('${propTop}', ${value}, __self); } else {`
code += `__self.__checkPropAccessor('set', ${nameJs});`
code += `if (typeof ${nameJs}.__setProp === 'function') { ${nameJs}.__setProp('${propTop}', ${value}, __self); } else {`
code += `${nameJs}['${propTop}'] = ${value} }};`
return ';' + this.convLineno(node, false) + code + '\n'
}
// プロパティへの参照 (#1793)
Expand All @@ -1872,7 +1876,10 @@ export class NakoGen {
const propKey = propList[0].value
const code_call = `${name}.__getProp('${propKey}', __self)`
const code_prop = `${name}['${propKey}']`
const code_if = `if (${name}.__getProp) { return ${code_call} } else { return ${code_prop} }`
const code_checkAccessor = `__self.__checkPropAccessor('get', ${name});\n` +
`if (typeof ${name}.__getProp === 'function') { return ${code_call} }\n` +
`return ${code_prop}\n`
const code_if = `if (${name}.__getProp) { return ${code_call} } else { ${code_checkAccessor} }`
code = `( (()=>{ ${code_if} })() )`
} else {
const arrs = []
Expand All @@ -1886,7 +1893,10 @@ export class NakoGen {
const arrStr = '[' + arrs.join(',') + ']'
const code_call = `${name}.__getProp(${arrStr}, __self)`
const code_prop = `${name}${keyStr}`
const code_if = `if (${name}.__getProp) { return ${code_call} } else { return ${code_prop} }`
const code_checkAccessor = `__self.__checkPropAccessor('get', ${name});\n` +
`if (${name}.__getProp) { return ${code_call} }\n` +
`return ${code_prop}\n`
const code_if = `if (${name}.__getProp) { return ${code_call} } else { ${code_checkAccessor} }`
code = `( (()=>{ ${code_if} })() )`
}
return code
Expand Down Expand Up @@ -2027,6 +2037,7 @@ self.__varslist = [self.newVariables(), self.newVariables(), self.newVariables()
self.__v0 = self.__varslist[0]
self.initFuncList = []
self.clearFuncList = []
self.__propAccessor = []
// --- jsInit ---
__jsInit__
// --- Copy module functions ---
Expand Down
2 changes: 2 additions & 0 deletions core/src/plugin_api.mts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ export interface NakoSystem {
__parseFloatOrBigint(v: NakoValue): number | bigint;
__evalJS(code: string, sys?: NakoSystem): NakoValue;
__evalSafe(code: string): NakoValue;
__registPropAccessor(f: Function, getProp: (prop: string|string[], sys: NakoSystem) => any, setProp: (prop: string|string[], value: object, sys: NakoSystem) => any):void;
__checkPropAccessor(mode: 'get'|'set', obj: any):void;
josiList: string[];
reservedWords: string[];
// 実際には存在するが利用が非推奨なメソッドやプロパティ
Expand Down
28 changes: 28 additions & 0 deletions core/src/plugin_system.mts
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,34 @@ export default {
return null
}
}
// Propアクセス支援
sys.__registPropAccessor = (f: Function, getProp: (prop: string|string[], sys: NakoSystem) => any, setProp: (prop: string|string[], value: object, sys: NakoSystem) => any, sys?: NakoSystem) => {
system.__propAccessor.push(
{
target: f,
getProp,
setProp
}
)
}
sys.__checkPropAccessor = (mode: 'get'|'set', obj: any):void => {
if ((mode === 'get' && obj.__getProp === undefined) || (mode === 'set' && obj.__setProp === undefined)) {
for (let i = 0; i < system.__propAccessor.length; i++) {
const accs = system.__propAccessor[i]
if (accs.target[Symbol.hasInstance](obj)) {
if (accs.getProp) {
obj.__getProp = accs.getProp
} else { obj.__getProp = null }
if (accs.setProp) {
obj.__setProp = accs.setProp
} else { obj.__setProp = null }
return
}
}
obj.__getProp = obj.__setProp = null
}
}

}
},
'!クリア': {
Expand Down
13 changes: 12 additions & 1 deletion src/plugin_browser.mts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @fileOverview ブラウザプラグイン
*/
import { NakoValue, NakoCallback, NakoCallbackEvent } from '../core/src/plugin_api.mjs'
import { NakoValue, NakoCallback, NakoCallbackEvent, NakoSystem } from '../core/src/plugin_api.mjs'
import { NakoBrowsesrSystem, IBrowserDocument, IBrowserWindow, IBrowserLocation } from './plugin_browser_api.mjs'

import PartBrowserColor from './plugin_browser_color.mjs'
Expand Down Expand Up @@ -214,6 +214,17 @@ const PluginBrowser = {
}
}
}
// Elementのクラスに対してDOMに動的プロパティの取得と設定を適用するよう登録する
if (sys.__registPropAccessor && globalThis.Element) {
sys.__registPropAccessor(Element,
function (prop: string|string[], sys: NakoSystem):any { // @ts-ignore
return sys.__exec('DOM設定取得', [this as Element, prop, sys as NakoBrowsesrSystem])
},
function (prop: string|string[], value: object, sys: NakoSystem):any { // @ts-ignore
sys.__exec('DOM設定変更', [this as Element, prop, value, sys as NakoBrowsesrSystem])
}
)
}
// DOM取得のために使う
sys.__query = (dom: object|string, commandName: string, isGetFunc: boolean) => {
// get element
Expand Down
5 changes: 4 additions & 1 deletion test/node/plugin_node_stdin_test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import assert from 'assert'
import path from 'path'
import fs from 'fs'
import { execSync, spawnSync } from 'child_process'
import os from 'node:os'

// __dirname のために
import url from 'url'
Expand All @@ -11,14 +12,16 @@ const debug = false
const __filename = url.fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)

const execOption = os.platform() === 'win32' ? { shell: 'powershell.exe' } : undefined

// PATH
const cnako3 = path.join(__dirname, '../../src/cnako3.mjs')

// eslint-disable-next-line no-undef
describe('plugin_node_stdin_test(cnako)', () => {
const cmp = (code, exRes, stdinStr) => {
const cmd = `echo "${stdinStr}" | node ${cnako3} -e "${code}"`
const result = execSync(cmd).toString().trimEnd()
const result = execSync(cmd, execOption).toString().trimEnd()
if (debug) {
console.log('code=' + code)
console.log('result=' + result)
Expand Down

0 comments on commit 006e476

Please sign in to comment.