Skip to content

Commit

Permalink
Adding decorator value detection
Browse files Browse the repository at this point in the history
  • Loading branch information
ktutnik committed Feb 8, 2017
1 parent ecc768f commit 9a809d9
Show file tree
Hide file tree
Showing 11 changed files with 329 additions and 215 deletions.
15 changes: 2 additions & 13 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,18 +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"
14 changes: 8 additions & 6 deletions src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export type MetadataType = "File" | "Module" | "Class"
| "Function" | "Constructor" | "Property"

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

export interface SourceLocation {
start: number,
Expand All @@ -32,18 +32,18 @@ export interface ValueMetaData {
location?: SourceLocation
}

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

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

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

Expand Down Expand Up @@ -119,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

0 comments on commit 9a809d9

Please sign in to comment.