Skip to content

Commit

Permalink
Merge pull request #6 from Sevavietl/master
Browse files Browse the repository at this point in the history
Added namespaces and traits functionality.
  • Loading branch information
ichiriac authored Dec 16, 2017
2 parents d833e12 + 36d9834 commit 0ac57da
Show file tree
Hide file tree
Showing 15 changed files with 655 additions and 170 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"homepage": "https://github.com/glayzzle/php-writer#readme",
"dependencies": {
"php-parser": "^2.1.0",
"php-unparser": "^0.2.3"
"php-unparser": "git+https://github.com/Sevavietl/php-unparser.git"
},
"devDependencies": {
"coveralls": "^2.11.15",
Expand All @@ -30,4 +30,4 @@
"nyc": "^11.2.1",
"should": "^13.1.0"
}
}
}
56 changes: 22 additions & 34 deletions src/class.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ var serialize = require('./helpers/serializer');
var Method = require('./method');
var Property = require('./property');
var Constant = require('./constant');
var traits = require('./helpers/traits');

/**
* @constructor
Expand Down Expand Up @@ -44,30 +45,29 @@ Class.prototype.setExtends = function(name) {
* Sets a list of implementation classes
*/
Class.prototype.setImplements = function(names) {
if (Array.isArray(names)) names = names.join(', ');
if(names) {
var ast = parser.parseEval('class a implements '+names+' {}');
this.ast.implements = ast.children[0].implements;
} else {
this.ast.implements = null;
}
return this;
if (Array.isArray(names)) names = names.join(', ');
if(names) {
var ast = parser.parseEval('class a implements '+names+' {}');
this.ast.implements = ast.children[0].implements;
} else {
this.ast.implements = null;
}
return this;
};

/**
* Gets a list of implemented classes
*/
Class.prototype.getImplements = function() {
var result = [];
if (this.ast.implements) {
for (var i = 0; i < this.ast.implements.length; i++) {
result.push(
this.ast.implements[i].resolution === 'rn' ?
'namespace\\' + this.ast.implements[i].name :
this.ast.implements[i].name
);
}
}
if (!this.ast.implements) {
return []
}

return this.ast.implements.map(function (_interface) {
return _interface.resolution === 'rn'
? 'namespace\\' + _interface.name
: _interface.name;
});
}

/**
Expand All @@ -82,23 +82,11 @@ Class.prototype.addImplements = function(name) {
return this;
};

Class.prototype.setTraits = function(names) {
// @todo
};
Class.prototype.setTraits = traits.setTraits;

Class.prototype.getTraits = function() {
// @todo
};
Class.prototype.getTraits = traits.getTraits;


Class.prototype.addTrait = function(name) {
var list = this.getTraits();
if (list.indexOf(name) === -1) {
list.push(name);
this.setTraits(list);
}
return this;
};
Class.prototype.addTrait = traits.addTrait;

/**
* Retrieves a class property
Expand Down Expand Up @@ -194,7 +182,7 @@ Class.prototype.setMethod = function(name, args, body, flags) {
*/
Class.locate = function(ast, name) {
return filter(ast, 'class', function(node) {
if (node.name === name) {
if (!name || node.name === name) {
return new Class(node);
}
});
Expand Down
67 changes: 67 additions & 0 deletions src/helpers/traits.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
var parser = require('php-parser');

var traitPredicate = function (node) {
return node.kind === 'traituse';
};

var findTraitsChild = function (subject) {
return subject.body.find(traitPredicate);
};

var findTraitsChildIndex = function (subject) {
return subject.body.findIndex(traitPredicate);
};

var traits = {
setTraits: function (names) {
if (Array.isArray(names)) {
names = names.join(', ');
}

if (!names) {
var index = findTraitsChildIndex(this.ast);

if (index !== -1) {
this.ast.body.splice(index, 1);
}

return this;
}

var ast = parser
.parseEval('class a { use ' + names + '; }')
.children
.shift()
.body
.shift();

this.ast.body.unshift(ast);

return this;
},

addTrait: function (name) {
var traits = this.getTraits();

if (traits.indexOf(name) === -1) {
traits.push(name);
this.setTraits(traits);
}

return this;
},

getTraits: function (name) {
var traituse = findTraitsChild(this.ast);

if (!traituse) {
return [];
}

return traituse.traits.map(function (trait) {
return trait.name;
});
}
}

module.exports = traits;
18 changes: 18 additions & 0 deletions src/helpers/usegroup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
var parser = require('php-parser');

var usegroup = {
add: function (name) {
var usegroup = parser.parseEval('use a;').children.shift();
usegroup.items[0].name = name;

var insertBefore = this.ast.children.findIndex(function (node) {
return node.kind !== 'usegroup';
});

this.ast.children.splice(insertBefore, 0, usegroup);

return this;
}
}

module.exports = usegroup;
42 changes: 42 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ var Class = require('./class');
var fn = require('./function');
var Interface = require('./interface');
var Trait = require('./trait');
var usegroup = require('./helpers/usegroup');

// Parser default options
var defaultOptions = {
Expand Down Expand Up @@ -51,6 +52,35 @@ var Writer = function(buffer, options = {}) {
};
editor(Writer, 1);

/**
* Add a namespace
* @param {String} name
* @return {Namespace|Null}
*/
Writer.prototype.addNamespace = function(name) {
if (!name) {
return;
}

var namespace = parser.parseEval('namespace a;').children.shift();
namespace.name = name;

this.ast.children.forEach(function (node) {
namespace.children.push(node);
});

this.ast.children = [namespace];

return Namespace.locate(this.ast.children, name);
}

/**
* Add usegroup
* @param {String}
* @return {Writer}
*/
Writer.prototype.addUsegroup = usegroup.add;

/**
* Finds a namespace
* @param {String} name
Expand Down Expand Up @@ -81,6 +111,10 @@ Writer.prototype.nsLocator = function(name) {
* @return {Class|Null}
*/
Writer.prototype.findClass = function(name) {
if (!name) {
return Class.locate(this.ast.children);
}

var ns = this.nsLocator(name);
if (ns[1]) return ns[1].findClass(ns[0]);
return Class.locate(this.ast.children, ns[0]);
Expand All @@ -102,6 +136,10 @@ Writer.prototype.findFunction = function(name) {
* @return {Trait|Null}
*/
Writer.prototype.findTrait = function(name) {
if (!name) {
return Trait.locate(this.ast.children);
}

var ns = this.nsLocator(name);
if (ns[1]) return ns[1].findTrait(ns[0]);
return Trait.locate(this.ast.children, ns[0]);
Expand All @@ -112,6 +150,10 @@ Writer.prototype.findTrait = function(name) {
* @return {Interface|Null}
*/
Writer.prototype.findInterface = function(name) {
if (!name) {
return Interface.locate(this.ast.children);
}

var ns = this.nsLocator(name);
if (ns[1]) return ns[1].findInterface(ns[0]);
return Interface.locate(this.ast.children, ns[0]);
Expand Down
3 changes: 1 addition & 2 deletions src/interface.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ Interface.prototype.setExtends = function(name) {
return this;
};


/**
* Sets a constant value
*/
Expand Down Expand Up @@ -101,7 +100,7 @@ Interface.prototype.setMethod = function(name, args, body, flags) {
*/
Interface.locate = function(ast, name) {
return filter(ast, 'interface', function(node) {
if (node.name === name) {
if (!name || node.name === name) {
return new Interface(node);
}
});
Expand Down
11 changes: 10 additions & 1 deletion src/namespace.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ var Interface = require('./interface');
var Trait = require('./trait');
var filter = require('./helpers/filter');
var editor = require('./helpers/editor');
var parser = require('php-parser');
var usegroup = require('./helpers/usegroup');

/**
* A namespace entry
Expand All @@ -32,6 +34,13 @@ Namespace.prototype.setName = function(name) {
return this;
};

/**
* Add usegroup
* @param {String}
* @return {namespace}
*/
Namespace.prototype.addUsegroup = usegroup.add;

/**
* Lookup for a class
* @param {String} name
Expand Down Expand Up @@ -82,7 +91,7 @@ Namespace.prototype.findConstant = function(name) {
*/
Namespace.locate = function(ast, name) {
return filter(ast, 'namespace', function(node) {
if (node.name == name) {
if (!name || node.name == name) {
return new Namespace(node);
}
});
Expand Down
35 changes: 6 additions & 29 deletions src/trait.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ var parser = require('php-parser');
var filter = require('./helpers/filter');
var Method = require('./method');
var Constant = require('./constant');
var traits = require('./helpers/traits');

/**
* @constructor
Expand Down Expand Up @@ -58,42 +59,18 @@ Trait.prototype.setMethod = function(name, args, body, flags) {
return this;
};

Trait.prototype.setTraits = traits.setTraits;

/**
* Sets a constant value
*/
Trait.prototype.getConstant = function(name) {
return Constant.locate(this.ast.body, name);
};

/**
* Sets a constant value
*/
Trait.prototype.setConstant = function(name, value) {
var constant = this.getConstant(name);
if (!constant) {
// append the function
var ast = parser.parseEval('class a { \n' +
'const ' + name + (
value ? ' = ' + value : ''
) + ';\n' +
' }');
this.ast.body.unshift(
ast.children[0].body[0]
);
} else {
if (typeof value !== 'undefined') constant.setValue(value);
}
return this;
};
Trait.prototype.getTraits = traits.getTraits;

Trait.prototype.addTrait = traits.addTrait;

/**
* @return {Interface|Null}
* @return {Trait|Null}
*/
Trait.locate = function(ast, name) {
return filter(ast, 'trait', function(node) {
if (node.name === name) {
if (!name || node.name === name) {
return new Trait(node);
}
});
Expand Down
Loading

0 comments on commit 0ac57da

Please sign in to comment.