Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ES6 class support #11

Merged
merged 3 commits into from
Apr 1, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,26 @@ gulp.task("build-source", function () {
return gulp.src([
"src/**/**.ts"
])
.pipe(tsProject())
.on("error", function (err) {
process.exit(1);
})
.pipe(gulp.dest("src/"));
.pipe(tsProject())
.on("error", function (err) {
process.exit(1);
})
.pipe(gulp.dest("src/"));
});

var es6Project = tsc.createProject("tsconfig.es6.json", {
typescript: require("typescript")
});

gulp.task("build-es6", function () {
return gulp.src([
"test/**/**.es6.ts"
])
.pipe(es6Project())
.on("error", function (err) {
process.exit(1);
})
.pipe(gulp.dest("test/"));
});

var tsTestProject = tsc.createProject("tsconfig.json", {
Expand Down
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,25 @@
"url": "https://github.com/kambojajs/kecubung"
},
"dependencies": {
"@types/node": "^7.0.5",
"@types/node": "^7.0.12",
"reflect-metadata": "^0.1.9",
"tslib": "^1.4.0"
},
"devDependencies": {
"@types/babylon": "^6.7.15",
"@types/babylon": "^6.16.0",
"@types/chai": "^3.4.34",
"@types/express": "^4.0.34",
"@types/mocha": "^2.2.33",
"@types/mocha": "^2.2.40",
"babylon": "^6.14.1",
"chai": "^3.5.0",
"coveralls": "^2.11.15",
"coveralls": "^2.13.0",
"del": "^2.2.2",
"gulp": "^3.9.1",
"gulp-istanbul": "^1.1.1",
"gulp-mocha": "^3.0.1",
"gulp-typescript": "^3.1.3",
"gulp-typescript": "^3.1.6",
"mocha": "^3.2.0",
"run-sequence": "^1.2.2",
"typescript": "^2.2.1"
"typescript": "^2.2.2"
}
}
4 changes: 2 additions & 2 deletions src/analyzers/astree/class-analyzer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export class ClassAnalyzer {
/**
* expect VariableDeclaration, ExpressionStatement
*/
constructor(private node) { }
constructor(protected node) { }

/**
* expect ExpressionStatement
Expand All @@ -32,7 +32,7 @@ export class ClassAnalyzer {
/**
* expect ExpressionStatement
*/
private isExportedStatement() {
protected isExportedStatement() {
return this.node.type == SyntaxKind.ExpressionStatement
&& this.node.expression.type == SyntaxKind.AssignmentExpression
&& this.node.expression.left.type == SyntaxKind.MemberExpression
Expand Down
32 changes: 32 additions & 0 deletions src/analyzers/astree/es6-class-analyzer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { SyntaxKind, SourceLocation } from "../../core"
import { ClassAnalyzer } from "./class-analyzer"

export class Es6ClassAnalyzer extends ClassAnalyzer {

/**
* expect VariableDeclaration, ExpressionStatement
*/
constructor(node) { super(node) }

//constructors & methods
getMember() {
return this.node.body.body;
}

getName() {
return this.node.id.name
}

isCandidate() {
return this.node.type == SyntaxKind.ClassDeclaration
}

getBaseClass() {
if(!this.node.superClass) return
if (this.node.superClass.type == SyntaxKind.MemberExpression)
return this.node.superClass.property.name;
else
return this.node.superClass.name
}
}

36 changes: 36 additions & 0 deletions src/analyzers/astree/es6-member-analyzer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { SyntaxKind, SourceLocation } from "../../core"
import { ClassAnalyzer } from "./class-analyzer"

export class Es6MemberAnalyzer {

constructor(private node) { }

getParameters() {
return this.node.params;
}

getType() {
switch (this.node.kind) {
case "constructor":
return "Constructor"
case "method":
return "Method"
}
}

getName() {
return this.node.key.name;
}

isCandidate() {
return this.node.type == SyntaxKind.ClassMethod
}

getLocation() {
return <SourceLocation>{
start: this.node.start,
end: this.node.end
};
}
}

58 changes: 33 additions & 25 deletions src/analyzers/astree/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {AnalyzerType} from "../baseclasses"
import { AnalyzerType } from "../baseclasses"

import { ChildDecoratorAnalyzer } from "./child-decorator-analyzer"
import { ClassAnalyzer } from "./class-analyzer"
Expand All @@ -8,34 +8,42 @@ import { FileAnalyzer } from "./file-analyzer"
import { MethodAnalyzer } from "./method-analyzer"
import { ModuleAnalyzer } from "./module-analyzer"
import { ParameterAnalyzer } from "./parameter-analyzer"
import { Es6ClassAnalyzer } from "./es6-class-analyzer"
import { Es6MemberAnalyzer } from "./es6-member-analyzer"

export function get(type:AnalyzerType, node){
switch(type){
export function get(type: AnalyzerType, node) {
switch (type) {
case AnalyzerType.ChildDecorator:
return new ChildDecoratorAnalyzer(node)
case AnalyzerType.File:
return new FileAnalyzer(node);
case AnalyzerType.Decorator:
return new DecoratorAnalyzer(node);
case AnalyzerType.Method:
return new MethodAnalyzer(node);
case AnalyzerType.Parameter:
return new ParameterAnalyzer(node);
case AnalyzerType.Constructor:
return new ConstructorAnalyzer(node);
case AnalyzerType.TSClass:
return new ClassAnalyzer(node);
case AnalyzerType.TSModule:
return new ModuleAnalyzer(node);
case AnalyzerType.File:
return new FileAnalyzer(node);
case AnalyzerType.Decorator:
return new DecoratorAnalyzer(node);
case AnalyzerType.Method:
return new MethodAnalyzer(node);
case AnalyzerType.Parameter:
return new ParameterAnalyzer(node);
case AnalyzerType.Constructor:
return new ConstructorAnalyzer(node);
case AnalyzerType.TSClass:
return new ClassAnalyzer(node);
case AnalyzerType.Es6Class:
return new Es6ClassAnalyzer(node)
case AnalyzerType.TSModule:
return new ModuleAnalyzer(node);
case AnalyzerType.Es6ClassMember:
return new Es6MemberAnalyzer(node)
}
}


export { ChildDecoratorAnalyzer } from "./child-decorator-analyzer"
export { ClassAnalyzer } from "./class-analyzer"
export { ConstructorAnalyzer } from "./constructor-analyser"
export { DecoratorAnalyzer } from "./decorator-analyzer"
export { FileAnalyzer } from "./file-analyzer"
export { MethodAnalyzer } from "./method-analyzer"
export { ModuleAnalyzer } from "./module-analyzer"
export { ParameterAnalyzer } from "./parameter-analyzer"
export { ChildDecoratorAnalyzer }
export { ClassAnalyzer }
export { ConstructorAnalyzer }
export { DecoratorAnalyzer }
export { FileAnalyzer }
export { MethodAnalyzer }
export { ModuleAnalyzer }
export { ParameterAnalyzer }
export { Es6ClassAnalyzer }
export { Es6MemberAnalyzer }
20 changes: 19 additions & 1 deletion src/analyzers/baseclasses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,17 @@ import { SyntaxKind, MethodMetaData, MetaData, ValueMetaData, AnalysisType, Sour

export type ParserType = "ASTree" | "Acorn"
export enum AnalyzerType {
File, Decorator, ChildDecorator, TSClass, TSModule, Constructor, Method, Parameter, ValueAnalyzer
File,
Decorator,
ChildDecorator,
Es6Class,
TSClass,
TSModule,
Constructor,
Method,
Parameter,
ValueAnalyzer,
Es6ClassMember
}

export interface ChildDecoratorAnalyzer {
Expand Down Expand Up @@ -77,4 +87,12 @@ export interface ValueAnalyzer{
isProperty()
getValue()
getName()
}

export interface Es6MemberAnalyzer {
getParameters()
getType()
getName()
isCandidate()
getLocation()
}
3 changes: 2 additions & 1 deletion src/analyzers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ export {
MethodAnalyzer,
ModuleAnalyzer,
ParameterAnalyzer,
ValueAnalyzer
ValueAnalyzer,
Es6MemberAnalyzer
} from "./baseclasses"
2 changes: 1 addition & 1 deletion src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export interface ParentMetaData extends MetaData {
children: MetaData[]
}

export module SyntaxKind {
export namespace SyntaxKind {
export const File = "File"
export const Program = "Program"
export const BlockStatement = "BlockStatement"
Expand Down
6 changes: 4 additions & 2 deletions src/transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import { TsClassTransformer } from "./transformers/ts-class"
import { TsModuleTransformer } from "./transformers/ts-module"
import { TsDecorator } from "./transformers/ts-decorator"
import { TsClassExporterTransformer } from "./transformers/ts-class-export"
import { Es6ClassTransformer } from "./transformers/es6-class"

export class Transformer {
constructor(private fileName: string, private parser:Analyzer.ParserType) { }
constructor(private fileName: string, private parser: Analyzer.ParserType) { }
transform(ast) {
let analyzer = <Analyzer.FileAnalyzer>Analyzer
.get(this.parser, Analyzer.AnalyzerType.File, ast)
Expand All @@ -27,12 +28,13 @@ class FileTransformer extends TransformerBase {
constructor(private parserType: Analyzer.ParserType) {
super()
}

transform(node, parent: MetaData) {
let analyzer = <Analyzer.FileAnalyzer>Analyzer
.get(this.parserType, Analyzer.AnalyzerType.File, node)
this.traverse(analyzer.getChildren(), parent, [
new TsClassTransformer(this.parserType),
new Es6ClassTransformer(this.parserType),
new TsModuleTransformer(this.parserType),
new TsDecorator(this.parserType),
new TsClassExporterTransformer(this.parserType)
Expand Down
36 changes: 36 additions & 0 deletions src/transformers/es6-class-member.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@

import * as Analyzer from "../analyzers"
import { ParameterTransformer } from "./parameter"
import * as Core from "../core"


export class Es6ClassMember extends Core.TransformerBase {
constructor(private parserType: Analyzer.ParserType) {
super()
}

@Core.Call.when(Core.SyntaxKind.ClassMethod)
transform(node, parent: Core.ClassMetaData) {
let analyser = <Analyzer.Es6MemberAnalyzer>Analyzer
.get(this.parserType, Analyzer.AnalyzerType.Es6ClassMember, node)
let type = analyser.getType()
if (analyser.isCandidate()) {
let method = {
type: type,
name: analyser.getName(),
analysis: Core.AnalysisType.Valid,
location: analyser.getLocation(),
parameters: [],
decorators: undefined
}
if(!parent.methods) parent.methods = []
if(type == "Method")
parent.methods.push(method)
if(type == "Constructor")
parent.constructor = method
this.traverse(analyser.getParameters(), method, [
new ParameterTransformer(this.parserType)
])
}
}
}
42 changes: 42 additions & 0 deletions src/transformers/es6-class.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import * as Analyzer from "../analyzers"
import { Es6ClassMember } from "./es6-class-member"
import { ParameterTransformer } from "./parameter"
import * as Core from "../core"

export class Es6ClassTransformer extends Core.TransformerBase {
constructor(private parserType: Analyzer.ParserType) {
super()
}

@Core.Call.when(Core.SyntaxKind.ClassDeclaration)
transform(node, parent: Core.ParentMetaData) {
let analyzer = <Analyzer.ClassAnalyzer>Analyzer
.get(this.parserType, Analyzer.AnalyzerType.Es6Class, node)
if (analyzer.isCandidate()) {
let clazz = <Core.ClassMetaData>{
type: "Class",
name: analyzer.getName(),
baseClass: analyzer.getBaseClass(),
location: analyzer.getLocation(),
analysis: Core.AnalysisType.Candidate
}
parent.children.push(clazz)
this.traverse(analyzer.getMember(), clazz, [
new Es6ClassMember(this.parserType),
])
this.analyse(clazz, parent, analyzer)
}
}


private analyse(clazz: Core.ClassMetaData, parent: Core.MetaData, analyzer: Analyzer.ClassAnalyzer) {
/*
TS class is not valid *YET* here,
validation done on TSClassExport
*/
clazz.analysis |= Core.AnalysisType.HasConstructor
let hasMethods = clazz.methods && clazz.methods.length > 0;
if (hasMethods) clazz.analysis |= Core.AnalysisType.HasMethod;
}
}

2 changes: 2 additions & 0 deletions src/transformers/ts-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as Core from "../core"
import { TsClassTransformer } from "./ts-class"
import { TsDecorator } from "./ts-decorator"
import { TsClassExporterTransformer } from "./ts-class-export"
import { Es6ClassTransformer } from "./es6-class"

export class TsModuleTransformer extends Core.TransformerBase {
constructor(private parserType: Analyzer.ParserType) {
Expand All @@ -23,6 +24,7 @@ export class TsModuleTransformer extends Core.TransformerBase {
}
parent.children.push(module);
this.traverse(analyzer.getBody(), module, [
new Es6ClassTransformer(this.parserType),
new TsClassTransformer(this.parserType),
new TsModuleTransformer(this.parserType),
new TsDecorator(this.parserType),
Expand Down
Loading