91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Typescript類型檢查原理之Override如何實現

發布時間:2022-04-19 16:14:05 來源:億速云 閱讀:318 作者:iii 欄目:移動開發

這篇文章主要介紹了Typescript類型檢查原理之Override如何實現的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇Typescript類型檢查原理之Override如何實現文章都會有所收獲,下面我們一起來看看吧。

override 修飾符是干嘛的

首先,我們來看下這個修飾符的作用:被 override 標示的方法必須得在父類中存在,否則會報錯。

class Animal {   getName() { return ''; } } class Dog extends Animal {   override bak() {     return 'wang';   }   override getName() {     return 'wang';   } }

上面這段代碼會報錯:This member cannot have an 'override' modifier because it is not  declared in the base class  'Animal'.就是說重寫的放在父類不存在,這樣能避免父類重構的時候把一些子類需要重寫的方法給去掉。

Typescript類型檢查原理之Override如何實現

如何實現 override 修飾符的類型檢查

其實所有的修飾符,包括 override、public、static 等,在 parse 成 AST 后都是作為一個屬性存在的,這個 override  也是,我們通過 astexplorer.net 來查看一下。

Typescript類型檢查原理之Override如何實現

可以看到 override 屬性為 true。這樣我們就可以通過這個屬性把該 class 的所有的需要 override 的 ClassMethod  過濾出來。

然后還可以拿到 superClass 的名字,從作用域中找到對應的聲明,然后遍歷 AST 找到它所聲明的所有 ClassMethod。

兩者對比一下,所有不在父類中的 ClassMethod 都需要報錯。

代碼實現

我們基于 babel 來做 parser 和分析,寫一個插件來做 override 的類型檢查。

開啟語法 typescript 插件來解析 ts 語法。

const { transformFromAstSync } = require('@babel/core'); const  parser = require('@babel/parser');  const ast = parser.parse(sourceCode, {     sourceType: 'unambiguous',     plugins: ['typescript'] });  const { code } = transformFromAstSync(ast, sourceCode, {     plugins: [overrideCheckerPlugin] });

插件要處理的是 ClassDeclaration,我們先搭一個基本的結構:

const { declare } = require('@babel/helper-plugin-utils');  const overrideCheckerPlugin = declare((api, options, dirname) => {     api.assertVersion(7);      return {         pre(file) {             file.set('errors', []);         },         visitor: {             ClassDeclaration(path, state) {                 const semanticErrors = state.file.get('errors');                 //...                 state.file.set('errors', semanticErrors);             }         },         post(file) {             console.log(file.get('errors'));         }     } });

具體的檢查邏輯是拿到父類的所有方法名,拿到當前類的所有 override 方法名,然后做下過濾。

我們首先要拿到父類的 ast,通過名字從作用域中查找。

const superClass = path.node.superClass; if (superClass) {     const superClassPath = path.scope.getBinding(superClass.name).path; }

然后封裝一個方法來拿父類方法名,通過 path.traverse 來遍歷 ast,把收集到的方法名存到 state 中。

function getAllClassMethodNames(classDeclarationNodePath) {     const state = {         allSuperMethodNames: []     }     classDeclarationNodePath.traverse({         ClassMethod(path) {             state.allSuperMethodNames.push(path.get('key').toString())         }     });     return state.allSuperMethodNames; }

這樣就拿到了所有父類方法名。

之后需要拿到當前類的所有方法名并過濾出 override 為 true 且不在父類中的進行報錯。

const superClass = path.node.superClass; if (superClass) {     const superClassPath = path.scope.getBinding(superClass.name).path;     const allMethodNames = getAllClassMethodNames(superClassPath);      path.traverse({         ClassMethod(path) {             if (path.node.override){                 const methodName = path.get('key').toString();                 const superClassName = superClassPath.get('id').toString();                 if (!allMethodNames.includes(methodName)) {                     // 報錯                                                     }             }         }     }); }

報錯的部分使用 code frame 來創建友好的代碼打印格式,通過 Error.stackTraceLimit 設置為 0 去掉調用棧信息。

const tmp = Error.stackTraceLimit; Error.stackTraceLimit = 0; let errorMessage = `this member cannot have an 'override' modifier because it is not declared in the base class '${superClassName}'`; semanticErrors.push(path.get('key').buildCodeFrameError(errorMessage, Error)); Error.stackTraceLimit = tmp;

這樣,我們就完成了 override 的類型檢查,整體代碼如下:

const { declare } = require('@babel/helper-plugin-utils');  function getAllClassMethodNames(classDeclarationNodePath) {     const state = {         allSuperMethodNames: []     }     classDeclarationNodePath.traverse({         ClassMethod(path) {             state.allSuperMethodNames.push(path.get('key').toString())         }     });     return state.allSuperMethodNames; }  const overrideCheckerPlugin = declare((api, options, dirname) => {     api.assertVersion(7);      return {         pre(file) {             file.set('errors', []);         },         visitor: {             ClassDeclaration(path, state) {                 const semanticErrors = state.file.get('errors');                  const superClass = path.node.superClass;                 if (superClass) {                     const superClassPath = path.scope.getBinding(superClass.name).path;                     const allMethodNames = getAllClassMethodNames(superClassPath);                              path.traverse({                         ClassMethod(path) {                             if (path.node.override){                                 const methodName = path.get('key').toString();                                 const superClassName = superClassPath.get('id').toString();                                 if (!allMethodNames.includes(methodName)) {                                     const tmp = Error.stackTraceLimit;                                     Error.stackTraceLimit = 0;                                     let errorMessage = `this member cannot have an 'override' modifier because it is not declared in the base class '${superClassName}'`;                                     semanticErrors.push(path.get('key').buildCodeFrameError(errorMessage, Error));                                     Error.stackTraceLimit = tmp;                                                                     }                             }                         }                     });                 }                 state.file.set('errors', semanticErrors);             }         },         post(file) {             console.log(file.get('errors'));         }     } });  module.exports = overrideCheckerPlugin;

測試效果

我們用最開始的代碼來測試一下:

class Animal {     getName() { return ''; } } class Dog extends Animal {     override bak() {         return 'wang';     }     override getName() {         return 'wang';     } }

打印信息為:

Typescript類型檢查原理之Override如何實現

正確的識別出了 bak 在父類不存在的錯誤。

關于“Typescript類型檢查原理之Override如何實現”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“Typescript類型檢查原理之Override如何實現”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

合江县| 固原市| 同江市| 额济纳旗| 秦皇岛市| 开远市| 平阳县| 习水县| 德兴市| 乌恰县| 峡江县| 安塞县| 榆林市| 务川| 建瓯市| 桑日县| 高阳县| 静安区| 长寿区| 亚东县| 尼勒克县| 土默特右旗| 县级市| 龙口市| 徐汇区| 镇沅| 广灵县| 靖远县| 科技| 湖北省| 梅河口市| 江阴市| 玉林市| 武夷山市| 河北区| 望谟县| 华安县| 江城| 江都市| 嘉鱼县| 临夏市|