This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Recursively visit every node in sourcefile. | |
const visitSourceFile = (sourceFile: ts.SourceFile, context: ts.TransformationContext): ts.SourceFile => { | |
const imports = new Set<RxJSPart>(); | |
const visitNodes = (node: ts.Node): ts.Node => { | |
const [dispatchedNode, classification] = dispatch(node); | |
imports.add(classification); | |
return ts.visitEachChild(dispatchedNode, visitNodes, context); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Recursively visit every node in sourcefile. | |
const visitSourceFile = (sourceFile: ts.SourceFile, context: ts.TransformationContext): ts.SourceFile => { | |
const imports = new Set<RxJSPart>(); | |
const visitNodes = (node: ts.Node): ts.Node => { | |
const [dispatchedNode, classification] = dispatch(node); | |
imports.add(classification); | |
return ts.visitEachChild(dispatchedNode, visitNodes, context); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Classify node, dispatch to appropriate wrapper function. | |
export const dispatch = (node: Touched<ts.Node>): [Transformed<ts.Node>, RxJSPart] => { | |
const classification = classify(node); | |
switch (classification) { | |
case RxJSPart.observable: { | |
const transformed = markAsTransformed(wrapObservableStatement(node as ts.CallExpression)); | |
return [transformed, classification]; | |
} | |
case RxJSPart.subscriber: { |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const isObjectOrSubjectConstructor: Classifier = classifierTemplate((node) => { | |
if (ts.isNewExpression(node) && ts.isIdentifier(node.expression)) { | |
if ([...rxjsObjectKinds, ...rxjsSubjectKinds].some(operator => operator === node.expression.getText())) { | |
return true; | |
} | |
} | |
return false; | |
}); | |
// Classify node by set of classifiers, if classified return true. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const isObjectOrSubjectConstructor: Classifier = classifierTemplate((node) => { | |
if (ts.isNewExpression(node) && ts.isIdentifier(node.expression)) { | |
if ([...rxjsObjectKinds, ...rxjsSubjectKinds].some(operator => operator === node.expression.getText())) { | |
return true; | |
} | |
} | |
return false; | |
}); | |
// Classify node by set of classifiers, if classified return true. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const isObjectOrSubjectConstructor: Classifier = classifierTemplate((node) => { | |
if (ts.isNewExpression(node) && ts.isIdentifier(node.expression)) { | |
if ([...rxjsObjectKinds, ...rxjsSubjectKinds].some(operator => operator === node.expression.getText())) { | |
return true; | |
} | |
} | |
return false; | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as ts from 'typescript'; | |
const printer = ts.createPrinter(); | |
// Create ts.Node from given typescript code. | |
export const createNode = <T extends ts.Node>(code: string, type: number): [T, ts.SourceFile] => { | |
const sourcefile = ts.createSourceFile('test.ts', code, ts.ScriptTarget.ES2015, true); | |
const node = fetchNodeFromSourceFile(sourcefile); | |
if (node.kind !== type) { | |
throw new Error(`TypeScript node created from given code doesn't match expected type, expected: ${type} but compiled: ${node.kind}!`); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
test('isObjectOrSubjectConstructor should identifiy RxJS Subject or Object contructor nodes.', () => { | |
const [node] = createNode<ts.NewExpression>(`new Observable();`, ts.SyntaxKind.NewExpression); | |
const [node2] = createNode<ts.NewExpression>(`new Observable<number>();`, ts.SyntaxKind.NewExpression); | |
const [node3] = createNode<ts.NewExpression>(`new BehaviorSubject<string>();`, ts.SyntaxKind.NewExpression); | |
const [node4] = createNode<ts.NewExpression>(`new NoRxJSSubject<string>();`, ts.SyntaxKind.NewExpression); | |
expect(isObjectOrSubjectConstructor(node)).toBe(true); | |
expect(isObjectOrSubjectConstructor(node2)).toBe(true); | |
expect(isObjectOrSubjectConstructor(node3)).toBe(true); | |
expect(isObjectOrSubjectConstructor(node4)).toBe(false); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Fetch identifier for given node in AST if existing. | |
export const fetchIdentifier = (node: ts.Node): string | null => { | |
if (!ts.isPropertyDeclaration(node) && !ts.isVariableDeclaration(node) && !ts.isExpressionStatement(node)) { | |
return fetchIdentifier(node.parent); | |
} else if (ts.isPropertyDeclaration(node) || ts.isVariableDeclaration(node)) { | |
return node.name.getText(); | |
} else { | |
return null; | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Create TypeScript property with given name and value, primitive literal values only. | |
const createPrimitiveProperty = (name: string, value: any) => ts.createPropertyAssignment(name, ts.createLiteral(defined(value))); | |
// Turn metadata object into TypeScript ObjectLiteralExpression. | |
const createMetadataObjectLiteral = (metadata: Metadata): ts.ObjectLiteralExpression => { | |
return ts.createObjectLiteral([ | |
createPrimitiveProperty('uuid', metadata.uuid), | |
createPrimitiveProperty('part', metadata.part), | |
createPrimitiveProperty('observable', metadata.observable), | |
createPrimitiveProperty('identifier', metadata.identifier), |
OlderNewer