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

Adding decorator parameter #7

Merged
merged 4 commits into from
Feb 8, 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
16 changes: 2 additions & 14 deletions src/analyzers/astree/child-decorator-analyzer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export class ChildDecoratorAnalyzer implements Base.ChildDecoratorAnalyzer {
}

getMethodParameters() {
return this.node.arguments.map(x => this.getParameter(x));
return this.node.arguments.map(x => H.getDecoratorParameterName(x));
}

getParameterDecoratorName() {
Expand All @@ -42,19 +42,7 @@ export class ChildDecoratorAnalyzer implements Base.ChildDecoratorAnalyzer {

getParameterDecoratorParameters() {
return this.node.arguments[1].arguments
.map(x => this.getParameter(x));
.map(x => H.getDecoratorParameterName(x));
}


private getParameter(x) {
return <MetaData>{
type: "Parameter",
name: H.getDecoratorParameterName(x),
analysis: AnalysisType.Valid,
location: <SourceLocation>{
start: this.node.start,
end: this.node.end
},
};
}
}
62 changes: 55 additions & 7 deletions src/analyzers/astree/helper.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { SyntaxKind, MetaData, AnalysisType } from "../../core"
import { SyntaxKind, MetaData, AnalysisType, ValueMetaData, ValueMetaDataType, PrimitiveValueMetaData, ObjectValueMetaData, ArrayValueMetaData } from "../../core"
import * as Analyzer from "../../analyzers"

/**
* require CallExpression.callee
Expand All @@ -18,15 +19,62 @@ export function isReservedDecorator(callExpression) {
|| getMethodNameFromCallee(callExpression.callee) == "__decorate"
}

export function getDecoratorParameterName(param) {
export function getDecoratorParameterName(param):ValueMetaData {
switch (param.type) {
case SyntaxKind.StringLiteral:
return getPrimitiveParameter("String", param)
case SyntaxKind.NumericLiteral:
return getPrimitiveParameter("Number", param)
case SyntaxKind.BooleanLiteral:
return param.value;
case SyntaxKind.Identifier:
return param.name;
return getPrimitiveParameter("Boolean", param)
case SyntaxKind.NullLiteral:
return getPrimitiveParameter("Null", param)
case SyntaxKind.ArrayExpression:
return getArrayParameter(param)
case SyntaxKind.ObjectExpression:
return getObjectParameter(param)
default:
return "Unknown";
return <ValueMetaData>{
type: "Unknown"
};
}
}
}

function getPrimitiveParameter(type: ValueMetaDataType, param) {
return <PrimitiveValueMetaData>{
type: type,
value: param.value
}
}


function getArrayParameter(param) {
let result = <ArrayValueMetaData>{
type: "Array",
children: []
}
for (let item of param.elements) {
result.children.push(getDecoratorParameterName(item))
}
return result;
}

function getPropertyParameter(param) {
let value = getDecoratorParameterName(param.value);
return <PrimitiveValueMetaData>{
type: value.type,
name: param.key.name,
value: value
}
}

function getObjectParameter(param) {
let result = <ObjectValueMetaData>{
type: "Object",
properties: []
}
for (let item of param.properties) {
result.properties.push(getPropertyParameter(item))
}
return result
}
18 changes: 14 additions & 4 deletions src/analyzers/baseclasses.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { SyntaxKind, MethodMetaData, MetaData, AnalysisType, SourceLocation } from "../core"
import { SyntaxKind, MethodMetaData, MetaData, ValueMetaData, AnalysisType, SourceLocation } from "../core"

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

export interface ChildDecoratorAnalyzer {
isMethodDecorator(): boolean
isParameterDecorator(): boolean
getMethodName(): string
getMethodLocation(): SourceLocation
getMethodParameters(): MetaData[]
getMethodParameters(): ValueMetaData[]
getParameterDecoratorName(): string
getParameterDecoratorLocation(): SourceLocation
getParameterDecoratorParameters(): MetaData[]
getParameterDecoratorParameters(): ValueMetaData[]
}

export interface ClassAnalyzer {
Expand Down Expand Up @@ -67,4 +67,14 @@ export interface ModuleAnalyzer {
export interface ParameterAnalyzer {
getName(): string
getLocation(): SourceLocation
}

export interface ValueAnalyzer{
isPrimitive()
isObject()
isArray()
isNull()
isProperty()
getValue()
getName()
}
3 changes: 2 additions & 1 deletion src/analyzers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@ export {
FileAnalyzer,
MethodAnalyzer,
ModuleAnalyzer,
ParameterAnalyzer
ParameterAnalyzer,
ValueAnalyzer
} from "./baseclasses"
29 changes: 28 additions & 1 deletion src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,35 @@ export type MetadataType = "File" | "Module" | "Class"
| "Method" | "Parameter" | "Decorator"
| "Function" | "Constructor" | "Property"

export type ValueMetaDataType = "Object" | "String" | "Boolean"
| "Number" | "Array" | "Null" | "Unknown"

export interface SourceLocation {
start: number,
end: number
}

export interface ValueMetaData {
type: ValueMetaDataType
name?: string
location?: SourceLocation
}

export interface PrimitiveValueMetaData extends ValueMetaData{
type: "String" | "Boolean" | "Number" | "Null"
value: any
}

export interface ObjectValueMetaData extends ValueMetaData{
type: "Object",
properties: ValueMetaData[]
}

export interface ArrayValueMetaData extends ValueMetaData {
type: "Array",
children: ValueMetaData[]
}

export interface MetaData {
type: MetadataType
name: string
Expand All @@ -32,9 +56,10 @@ export interface MetaData {

export interface DecoratorMetaData extends MetaData {
type: "Decorator"
parameters: MetaData[]
parameters: ValueMetaData[]
}


export interface ParameterMetaData extends MetaData {
type: "Parameter"
decorators: DecoratorMetaData[]
Expand Down Expand Up @@ -94,6 +119,8 @@ export module SyntaxKind {
export const ClassExpression = "ClassExpression"
export const UnaryExpression = "UnaryExpression"
export const NullLiteral = "NullLiteral"
export const ObjectExpression = "ObjectExpression"
export const ObjectProperty = "ObjectProperty"
}

export module Call {
Expand Down
1 change: 1 addition & 0 deletions src/transformers/ts-child-decorator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export class TsChildDecoratorTransformer extends Core.TransformerBase {
let parameter = parent.parameters[parseInt(node.arguments[0].value)]
this.transformParameter(analyzers, parameter)
}

}

private transformMethod(analyzer: Analyzer.ChildDecoratorAnalyzer, parent: Core.MethodMetaData | Core.ClassMetaData | Core.PropertyMetaData) {
Expand Down
80 changes: 80 additions & 0 deletions src/transformers/value.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import * as Analyzer from "../analyzers"
import { ParameterTransformer } from "./parameter"
import * as Core from "../core"


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

@Core.Call.when(Core.SyntaxKind.BooleanLiteral)
transform(node, parent: Core.DecoratorMetaData) {
let analyser = <Analyzer.ValueAnalyzer>Analyzer
.get(this.parserType, Analyzer.AnalyzerType.ValueAnalyzer, node)
if (analyser.isPrimitive()) {
if(!parent.parameters) parent.parameters = []
parent.parameters.push(<Core.PrimitiveValueMetaData>{
type: "Boolean",
value: analyser.getValue()
})
}
}
}

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

@Core.Call.when(Core.SyntaxKind.StringLiteral)
transform(node, parent: Core.DecoratorMetaData) {
let analyser = <Analyzer.ValueAnalyzer>Analyzer
.get(this.parserType, Analyzer.AnalyzerType.ValueAnalyzer, node)
if (analyser.isPrimitive()) {
if(!parent.parameters) parent.parameters = []
parent.parameters.push(<Core.PrimitiveValueMetaData>{
type: "String",
value: analyser.getValue()
})
}
}
}

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

@Core.Call.when(Core.SyntaxKind.NumericLiteral)
transform(node, parent: Core.DecoratorMetaData) {
let analyser = <Analyzer.ValueAnalyzer>Analyzer
.get(this.parserType, Analyzer.AnalyzerType.ValueAnalyzer, node)
if (analyser.isPrimitive()) {
if(!parent.parameters) parent.parameters = []
parent.parameters.push(<Core.PrimitiveValueMetaData>{
type: "Number",
value: analyser.getValue()
})
}
}
}

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

@Core.Call.when(Core.SyntaxKind.NullLiteral)
transform(node, parent: Core.DecoratorMetaData) {
let analyser = <Analyzer.ValueAnalyzer>Analyzer
.get(this.parserType, Analyzer.AnalyzerType.ValueAnalyzer, node)
if (analyser.isNull()) {
if(!parent.parameters) parent.parameters = []
parent.parameters.push(<Core.PrimitiveValueMetaData>{
type: "Null",
value: analyser.getValue()
})
}
}
}
Loading