Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat: create action generators
  • Loading branch information
dstallenberg committed Aug 1, 2023
commit 301fac8188a48d7c487bc5ee821c80c4252b754c
2 changes: 1 addition & 1 deletion libraries/analysis-javascript/lib/RootContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ export class RootContext extends CoreRootContext<t.Node> {
this._elementMap,
this._relationMap
);
this._typePool = new TypePool(this._objectMap);
this._typePool = new TypePool(this._objectMap, this.getAllExports());
}
}

Expand Down
4 changes: 2 additions & 2 deletions libraries/analysis-javascript/lib/target/Target.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export interface ClassTarget extends NamedSubTarget, Exportable {

export interface MethodTarget extends NamedSubTarget, Callable {
type: TargetType.METHOD;
className: string;
classId: string;

visibility: VisibilityType;

Expand All @@ -79,7 +79,7 @@ export interface ObjectTarget extends NamedSubTarget, Exportable {

export interface ObjectFunctionTarget extends NamedSubTarget, Callable {
type: TargetType.OBJECT_FUNCTION;
objectName: string;
objectId: string;
}

export interface PathTarget extends SubTarget {
Expand Down
145 changes: 73 additions & 72 deletions libraries/analysis-javascript/lib/target/TargetVisitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -333,77 +333,78 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
this.subTargets.push(target);
};

private _getParentClassName(
private _getParentClassId(
path: NodePath<
| t.ClassMethod
| t.ClassProperty
| t.ClassPrivateMethod
| t.ClassPrivateProperty
>
): string {
const parentNode = path.parentPath.parentPath.node;
const parentOfParentNode = path.parentPath.parentPath.parentPath.node;
if (parentNode.type === "ClassDeclaration") {
// e.g. class A { ... }
if (parentNode.id && parentNode.id.type === "Identifier") {
return parentNode.id.name;
} else if (
parentOfParentNode !== undefined &&
parentOfParentNode.type === "ExportDefaultDeclaration"
) {
// e.g. export default class { ... }
return "default";
} else {
// e.g. class { ... }
// unsupported
// should not be possible
throw new Error("unknown class method parent");
}
} else if (parentNode.type === "ClassExpression") {
// e.g. const x = class A { ... }
// e.g. const x = class { ... }
// e.g. { x: class A { ... } }
// in all cases the name should be x

if (
parentOfParentNode !== undefined &&
parentOfParentNode.type === "VariableDeclarator"
) {
// e.g. ? = class A { ... }
if (parentOfParentNode.id.type === "Identifier") {
// e.g. const x = class A { ... }
return parentOfParentNode.id.name;
} else {
// e.g. ? = class { ... }
// unsupported
// should not be possible
throw new Error("unknown class method parent");
}
} else if (
parentOfParentNode !== undefined &&
parentOfParentNode.type === "ObjectProperty"
) {
// e.g. { x: class A { ... } }
if (parentOfParentNode.key.type === "Identifier") {
return parentOfParentNode.key.name;
} else if (parentOfParentNode.key.type.includes("Literal")) {
// e.g. { "x": class A { ... } }
return "value" in parentOfParentNode.key
? parentOfParentNode.key.value.toString()
: "null";
} else {
// e.g. { ??: class { ... } }
// unsupported
throw new Error("unknown class method parent");
}
} else {
// unsupported
throw new Error("unknown class method parent");
}
} else {
// unsupported
throw new Error("unknown class method parent");
}
return this._getNodeId(path.parentPath.parentPath);
// const parentNode = path.parentPath.parentPath.node;
// const parentOfParentNode = path.parentPath.parentPath.parentPath.node;
// if (parentNode.type === "ClassDeclaration") {
// // e.g. class A { ... }
// if (parentNode.id && parentNode.id.type === "Identifier") {
// return parentNode.id.name;
// } else if (
// parentOfParentNode !== undefined &&
// parentOfParentNode.type === "ExportDefaultDeclaration"
// ) {
// // e.g. export default class { ... }
// return "default";
// } else {
// // e.g. class { ... }
// // unsupported
// // should not be possible
// throw new Error("unknown class method parent");
// }
// } else if (parentNode.type === "ClassExpression") {
// // e.g. const x = class A { ... }
// // e.g. const x = class { ... }
// // e.g. { x: class A { ... } }
// // in all cases the name should be x

// if (
// parentOfParentNode !== undefined &&
// parentOfParentNode.type === "VariableDeclarator"
// ) {
// // e.g. ? = class A { ... }
// if (parentOfParentNode.id.type === "Identifier") {
// // e.g. const x = class A { ... }
// return parentOfParentNode.id.name;
// } else {
// // e.g. ? = class { ... }
// // unsupported
// // should not be possible
// throw new Error("unknown class method parent");
// }
// } else if (
// parentOfParentNode !== undefined &&
// parentOfParentNode.type === "ObjectProperty"
// ) {
// // e.g. { x: class A { ... } }
// if (parentOfParentNode.key.type === "Identifier") {
// return parentOfParentNode.key.name;
// } else if (parentOfParentNode.key.type.includes("Literal")) {
// // e.g. { "x": class A { ... } }
// return "value" in parentOfParentNode.key
// ? parentOfParentNode.key.value.toString()
// : "null";
// } else {
// // e.g. { ??: class { ... } }
// // unsupported
// throw new Error("unknown class method parent");
// }
// } else {
// // unsupported
// throw new Error("unknown class method parent");
// }
// } else {
// // unsupported
// throw new Error("unknown class method parent");
// }
}

public ClassMethod: (path: NodePath<t.ClassMethod>) => void = (path) => {
Expand All @@ -413,7 +414,7 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
throw new Error("unknown class method parent");
}

const parentClassName: string = this._getParentClassName(path);
const parentClassId: string = this._getParentClassId(path);

if (path.node.key.type !== "Identifier") {
// e.g. class A { ?() {} }
Expand All @@ -435,7 +436,7 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
id: `${this._getNodeId(path)}`,
name: targetName,
type: TargetType.METHOD,
className: parentClassName,
classId: parentClassId,
isStatic: path.node.static,
isAsync: path.node.async,
methodType: path.node.kind,
Expand Down Expand Up @@ -506,7 +507,7 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
id: target.id,
type: TargetType.METHOD,
name: "constructor",
className: prototypeName,
classId: target.id,

visibility: VisibilityType.PUBLIC,

Expand All @@ -527,7 +528,7 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
id: `${this._getNodeId(path)}`,
type: TargetType.METHOD,
name: property.node.name,
className: prototypeName,
classId: target.id,

visibility: VisibilityType.PUBLIC,

Expand Down Expand Up @@ -632,7 +633,7 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
}
case "ClassProperty": {
// e.g. class A { x = () => {} }
const parentClassName: string = this._getParentClassName(
const parentClassId: string = this._getParentClassId(
<NodePath<t.ClassProperty>>path.parentPath
);

Expand All @@ -646,7 +647,7 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {

const target: MethodTarget = {
id: `${this._getNodeId(path)}`,
className: parentClassName,
classId: parentClassId,
name: targetName,
type: TargetType.METHOD,
isStatic: (<t.ClassProperty>parent.node).static,
Expand Down Expand Up @@ -961,8 +962,8 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
(<MethodTarget>subTarget).methodType &&
(<MethodTarget>t).isStatic ===
(<MethodTarget>subTarget).isStatic &&
(<MethodTarget>t).className ===
(<MethodTarget>subTarget).className
(<MethodTarget>t).classId ===
(<MethodTarget>subTarget).classId
: true)
);
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,17 +309,15 @@ export class ObjectVisitor extends AbstractSyntaxTreeVisitor {
}
} else if (path.node.object.type === "Identifier") {
const bindingId = this._getBindingId(path.get("object"));
const _object = this.complexTypeMap.get(bindingId);
let _object = this.complexTypeMap.get(bindingId);

if (!_object) {
// do not consider newly generated objects
return;
// _object = {
// id: bindingId,
// kind: DiscoveredObjectKind.OBJECT, // not sure actually
// properties: new Map(),
// };
// this._complexTypeMap.set(bindingId, _object);
_object = {
id: bindingId,
kind: DiscoveredObjectKind.OBJECT, // not sure actually
properties: new Map(),
};
this._complexTypeMap.set(bindingId, _object);
}

if (path.node.property.type === "PrivateName") {
Expand Down
33 changes: 31 additions & 2 deletions libraries/analysis-javascript/lib/type/resolving/TypePool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,47 @@
import { prng } from "@syntest/prng";
import { DiscoveredObjectType } from "../discovery/object/DiscoveredType";
import { ObjectType } from "./Type";
import { Export } from "../../target/export/Export";

// TODO we could cache some of this stuff (unless we do dynamic adding of properties at some point)
export class TypePool {
private _objectMap: Map<string, DiscoveredObjectType>;
private _exports: Map<string, Export[]>;

constructor(objectMap: Map<string, DiscoveredObjectType>) {
private _exportedObjects: Map<string, DiscoveredObjectType>;

constructor(
objectMap: Map<string, DiscoveredObjectType>,
exports: Map<string, Export[]>
) {
this._objectMap = objectMap;
this._exports = exports;

this._exportedObjects = this._extractExportedTypes();
}

private _extractExportedTypes(): Map<string, DiscoveredObjectType> {
const exportedTypes: Map<string, DiscoveredObjectType> = new Map();

for (const [, exports] of this._exports.entries()) {
for (const export_ of exports) {
for (const [
objectName,
discoveredObject,
] of this._objectMap.entries()) {
if (discoveredObject.id === export_.id) {
exportedTypes.set(objectName, discoveredObject);
}
}
}
}

return exportedTypes;
}

protected _getMatchingTypes(objectType: ObjectType): DiscoveredObjectType[] {
const matchingTypes: DiscoveredObjectType[] = [];
for (const object_ of this._objectMap.values()) {
for (const object_ of this._exportedObjects.values()) {
let match = true;
for (const property of objectType.properties.keys()) {
if (!object_.properties.has(property)) {
Expand Down
2 changes: 1 addition & 1 deletion libraries/search-javascript/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export * from "./lib/testcase/statements/primitive/UndefinedStatement";

export * from "./lib/testcase/statements/action/ConstructorCall";
export * from "./lib/testcase/statements/action/FunctionCall";
export * from "./lib/testcase/statements/action/RootObject";
export * from "./lib/testcase/statements/action/ConstantObject";
export * from "./lib/testcase/statements/root/RootStatement";

export * from "./lib/testcase/statements/Statement";
Expand Down
Loading