homunculus
Advanced tools
Comparing version 0.0.19 to 0.1.0
{ | ||
"name": "homunculus", | ||
"version": "0.0.19", | ||
"version": "0.1.0", | ||
"description": "A lexer&parser by Javascript", | ||
@@ -5,0 +5,0 @@ "maintainers": [ |
@@ -118,2 +118,3 @@ var Class = require('../util/Class'); | ||
if(this.peek == character.LINE) { | ||
this.error('SyntaxError: unterminated regular expression literal ' + this.peek, this.code.slice(lastIndex, this.index)); | ||
break; | ||
@@ -128,2 +129,3 @@ } | ||
if(this.peek == character.LINE) { | ||
this.error('SyntaxError: unterminated regular expression literal ' + this.peek, this.code.slice(lastIndex, this.index)); | ||
break outer; | ||
@@ -130,0 +132,0 @@ } |
@@ -41,3 +41,3 @@ var Class = require('../../util/Class'); | ||
//需被实现 | ||
return false; | ||
throw new Error('match needs to be implement'); | ||
}, | ||
@@ -44,0 +44,0 @@ error: function() { |
@@ -51,4 +51,4 @@ var Rule = require('./Rule'); | ||
}).statics({ | ||
KEYWORDS: 'abstract boolean break byte case catch char class const continue debugger default delete do double else enum export extends false final finally float for function goto if implements import in instanceof int interface let long native new null package private protected public return short static super switch synchronized this throw throws transient true try typeof var void volatile while with'.split(' ') | ||
KEYWORDS: 'abstract boolean break byte case catch class const continue debugger default delete do double else enum export extends false final finally float for function goto if implements import in instanceof int interface let long native new null package private protected public return short static super switch synchronized this throw throws transient true try typeof var void volatile while with'.split(' ') | ||
}); | ||
module.exports = EcmascriptRule; |
@@ -15,2 +15,3 @@ var Class = require('../../util/Class'); | ||
this.varsMap = Object.create(null); //键为id字面量,值是它的token的节点 | ||
this.vardeclMap = Object.create(null); //var赋值记录,优先级vardecl > fndecl > varnodecl | ||
this.params = []; //形参,函数上下文才有,即全局无 | ||
@@ -86,2 +87,6 @@ this.paramsMap = Object.create(null); //键为id字面量,值是它的token的节点 | ||
if(name) { | ||
if(name in this.vardeclMap) { | ||
return this; | ||
} | ||
this.delVar(name); | ||
this.delChild(name); | ||
@@ -115,2 +120,3 @@ } | ||
this.delChild(v); | ||
this.vardeclMap[v] = true; | ||
} | ||
@@ -117,0 +123,0 @@ //仅仅是var声明无赋值,且已有过声明或函数,忽略之 |
@@ -21,2 +21,19 @@ var homunculus = require('../homunculus'); | ||
}); | ||
it('var duplicate', function() { | ||
var context = homunculus.getContext('js'); | ||
context.parse('var a = 1;var a = 2;'); | ||
expect(context.getVars().length).to.be(1); | ||
}); | ||
it('var replace with fn', function() { | ||
var context = homunculus.getContext('js'); | ||
context.parse('var a;function a(){}'); | ||
expect(context.hasVar('a')).to.be(false); | ||
expect(context.hasChild('a')).to.be(true); | ||
}); | ||
it('vardecl replace with fn', function() { | ||
var context = homunculus.getContext('js'); | ||
context.parse('var a = 1;function a(){}'); | ||
expect(context.hasVar('a')).to.be(true); | ||
expect(context.hasChild('a')).to.be(false); | ||
}); | ||
it('fndecl 1', function() { | ||
@@ -77,2 +94,3 @@ var context = homunculus.getContext('js'); | ||
expect(first.hasParam('b')).to.ok(); | ||
expect(first.getParams().length).to.be(1); | ||
}); | ||
@@ -79,0 +97,0 @@ it('fnexpr in ()', function() { |
@@ -35,2 +35,7 @@ var homunculus = require('../homunculus'); | ||
}); | ||
it('string multiline', function() { | ||
var lexer = homunculus.getLexer('js'); | ||
var tokens = lexer.parse('"string\\\r\n""str"'); | ||
expect(join(tokens)).to.eql(['"string\\\r\n"', '"str"']); | ||
}); | ||
it('id and sign in var stmt', function() { | ||
@@ -67,8 +72,44 @@ var lexer = homunculus.getLexer('js'); | ||
}); | ||
it('perl style regular no end 2', function() { | ||
it('perl style regular with unknow flag in loose mode', function() { | ||
var lexer = homunculus.getLexer('js'); | ||
Lexer.mode(Lexer.LOOSE); | ||
expect(function() { | ||
lexer.parse('/reg/op;'); | ||
}).to.not.throwError(); | ||
Lexer.mode(Lexer.STRICT); | ||
}); | ||
it('perl style regular no end', function() { | ||
var lexer = homunculus.getLexer('js'); | ||
expect(function() { | ||
lexer.parse('/reg'); | ||
}).to.throwError(); | ||
}); | ||
it('perl style regular cross line', function() { | ||
var lexer = homunculus.getLexer('js'); | ||
expect(function() { | ||
lexer.parse('/reg\n/'); | ||
}).to.throwError(); | ||
}); | ||
it('perl style regular cross line in loose mode', function() { | ||
var lexer = homunculus.getLexer('js'); | ||
Lexer.mode(Lexer.LOOSE); | ||
expect(function() { | ||
lexer.parse('/reg\n/'); | ||
}).to.not.throwError(); | ||
Lexer.mode(Lexer.STRICT); | ||
}); | ||
it('perl style regular cross line in []', function() { | ||
var lexer = homunculus.getLexer('js'); | ||
expect(function() { | ||
lexer.parse('/reg[\n]/'); | ||
}).to.throwError(); | ||
}); | ||
it('perl style regular cross line in [] in loose mode', function() { | ||
var lexer = homunculus.getLexer('js'); | ||
Lexer.mode(Lexer.LOOSE); | ||
expect(function() { | ||
lexer.parse('/reg[\n]/'); | ||
}).to.not.throwError(); | ||
Lexer.mode(Lexer.STRICT); | ||
}); | ||
it('signle line comment', function() { | ||
@@ -75,0 +116,0 @@ var lexer = homunculus.getLexer('js'); |
@@ -794,2 +794,10 @@ var homunculus = require('../homunculus'); | ||
}); | ||
it('formatter', function() { | ||
var parser = homunculus.getParser('js'); | ||
var code = fs.readFileSync(path.join(__dirname, './lib/formatter.js'), { encoding: 'utf-8' }); | ||
var node = parser.parse(code); | ||
var ignore = parser.ignore(); | ||
var str = jion(node, ignore); | ||
expect(str).to.eql(code); | ||
}); | ||
}); | ||
@@ -796,0 +804,0 @@ describe('other test', function() { |
@@ -119,2 +119,3 @@ define(function(require, exports, module) { | ||
if(this.peek == character.LINE) { | ||
this.error('SyntaxError: unterminated regular expression literal ' + this.peek, this.code.slice(lastIndex, this.index)); | ||
break; | ||
@@ -129,2 +130,3 @@ } | ||
if(this.peek == character.LINE) { | ||
this.error('SyntaxError: unterminated regular expression literal ' + this.peek, this.code.slice(lastIndex, this.index)); | ||
break outer; | ||
@@ -131,0 +133,0 @@ } |
@@ -42,3 +42,3 @@ define(function(require, exports, module) { | ||
//需被实现 | ||
return false; | ||
throw new Error('match needs to be implement'); | ||
}, | ||
@@ -45,0 +45,0 @@ error: function() { |
@@ -52,5 +52,5 @@ define(function(require, exports, module) { | ||
}).statics({ | ||
KEYWORDS: 'abstract boolean break byte case catch char class const continue debugger default delete do double else enum export extends false final finally float for function goto if implements import in instanceof int interface let long native new null package private protected public return short static super switch synchronized this throw throws transient true try typeof var void volatile while with'.split(' ') | ||
KEYWORDS: 'abstract boolean break byte case catch class const continue debugger default delete do double else enum export extends false final finally float for function goto if implements import in instanceof int interface let long native new null package private protected public return short static super switch synchronized this throw throws transient true try typeof var void volatile while with'.split(' ') | ||
}); | ||
module.exports = EcmascriptRule; | ||
}); |
@@ -13,10 +13,11 @@ define(function(require, exports, module) { | ||
this.children = []; //函数声明或函数表达式所产生的上下文 | ||
this.childrenMap = {}; //键是函数名,值是上下文,匿名函数表达式键为cid | ||
this.childrenMap = Object.create(null); //键是函数名,值是上下文,匿名函数表达式键为cid | ||
this.vars = []; //变量var声明 | ||
this.varsMap = {}; //键为id字面量,值是它的token的节点 | ||
this.varsMap = Object.create(null); //键为id字面量,值是它的token的节点 | ||
this.vardeclMap = Object.create(null); //var赋值记录,优先级vardecl > fndecl > varnodecl | ||
this.params = []; //形参,函数上下文才有,即全局无 | ||
this.paramsMap = {}; //键为id字面量,值是它的token的节点 | ||
this.paramsMap = Object.create(null); //键为id字面量,值是它的token的节点 | ||
this.aParams = []; //实参,函数表达式才有 | ||
this.vids = []; //上下文环境里用到的变量id | ||
this.vidsMap = {}; //键为id字面量,值是它的token的节点 | ||
this.vidsMap = Object.create(null); //键为id字面量,值是它的token的节点 | ||
this.returns = []; //上下文环境里return语句 | ||
@@ -55,3 +56,3 @@ this.node = null; //对应的ast的节点 | ||
hasParam: function(p) { | ||
return this.paramsMap.hasOwnProperty(p); | ||
return p in this.paramsMap; | ||
}, | ||
@@ -82,3 +83,3 @@ getParams: function() { | ||
hasChild: function(name) { | ||
return this.childrenMap.hasOwnProperty(name); | ||
return name in this.childrenMap; | ||
}, | ||
@@ -89,2 +90,6 @@ addChild: function(child) { | ||
if(name) { | ||
if(name in this.vardeclMap) { | ||
return this; | ||
} | ||
this.delVar(name); | ||
this.delChild(name); | ||
@@ -110,3 +115,3 @@ } | ||
hasVar: function(v) { | ||
return this.varsMap.hasOwnProperty(v); | ||
return v in this.varsMap; | ||
}, | ||
@@ -119,2 +124,3 @@ addVar: function(node, assign) { | ||
this.delChild(v); | ||
this.vardeclMap[v] = true; | ||
} | ||
@@ -148,11 +154,12 @@ //仅仅是var声明无赋值,且已有过声明或函数,忽略之 | ||
hasVid: function(v) { | ||
return this.vidsMap.hasOwnProperty(v); | ||
return v in this.vidsMap; | ||
}, | ||
getVid: function(v) { | ||
return this.vidsMap[v]; | ||
}, | ||
addVid: function(node) { | ||
var v = node.token().content(); | ||
if(this.vidsMap.hasOwnProperty(v)) { | ||
return; | ||
} | ||
this.vids.push(node); | ||
this.vidsMap[v] = node; | ||
this.vidsMap[v] = this.vidsMap[v] || []; | ||
this.vidsMap[v].push(node); | ||
return this; | ||
@@ -159,0 +166,0 @@ }, |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1361318
78
26116