2017-10-12 3 views
0

Compte tenuDéterminer le type de valeur d'une propriété déclarée dans une classe en utilisant RegExp, String ou d'autres méthodes

class MyClass { 
    constructor() { 
     this.hello = 'greetings'; 
    } 
} 

comment peut-on déterminer si this.hello devrait être l'un des types JavaScript, par exemple, String , Array, Boolean, sans initialiser le class? Aux fins de l'enquête, nous ne nous intéressons pas à la praticabilité de la procédure, mais plutôt à la mesure dans laquelle la procédure est possible et vérifiable.

Par exemple

let c = MyClass.toString().match(/constructor\s\(?.+\)\s\{?\n.+\n.+\‌​}/); 
c[0].match(/this\.\w+?\s=?\s.*(?:;)/); 

nous pouvons obtenir this.hello = 'greeting';, qui sont les prochaines étapes pour déterminer que 'greeting' devrait être ou sera une chaîne?

Quels sont les problèmes d'utilisation des méthodes RegExp ou String pour répondre aux exigences?


Pour obtenir des précisions exigence:

Compte tenu de toute classe JavaScript arbitraire, déterminer le type des arguments utilisés dans son constructeur.

+1

Utiliser un analyseur, analyser le code source. N'utilisez pas regex pour faire cela. – Tomalak

+1

Ne semble pas être une approche viable. Par exemple. 'this.hello = 'salutations salut howdy'.split()' signifierait que 'hello' est un' Array', mais pour bien faire, votre regex devrait être capable d'interpréter ce 'String.prototype.split' résultats. OMI, vous aurez plus de chance avec un parser/AST complet qu'une regex. –

+0

@Tomalak Pouvez-vous poster vos observations et suggestions à une réponse? – guest271314

Répondre

1

N'utilisez pas regex pour cela; la complexité de la syntaxe JavaScript est trop importante pour les expressions régulières simples. Au lieu de cela, utilisez un analyseur et suivez l'AST.

Voici un coup assez brutale en utilisant acorn. Cela ne capture que les propriétés déclarées dans le formulaire,

this.<propName> = <literal>; 

mais cela démontre le concept de base.

class MyClass { 
 
    constructor() { 
 
    this.hello = 'greetings'; 
 
    } 
 
} 
 

 
var ast = acorn.parse(MyClass.toString()); 
 
document.write(`Class: '${ast.body[0].id.name}'<br>`); 
 
var ctor = ast.body[0].body.body.find(fn => fn.kind == "constructor"); 
 
ctor.value.body.body.forEach(x => 
 
    x.type == "ExpressionStatement" && 
 
    x.expression.type == "AssignmentExpression" && 
 
    x.expression.left.type == "MemberExpression" && 
 
    x.expression.left.object.type == "ThisExpression" && 
 
    x.expression.left.property.type == "Identifier" && 
 
    x.expression.right.type == "Literal" && 
 
    document.write(`&emsp;Property '${x.expression.left.property.name}' of type '${typeof(x.expression.right.value)}'<br>`));
<script src="//cdnjs.cloudflare.com/ajax/libs/acorn/5.1.2/acorn.js"></script>