Skip to content
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
92 changes: 75 additions & 17 deletions plugins/axiomcode/skills/axiomcode/scripts/axiomcode-changed

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions plugins/axiomcode/skills/axiomcode/scripts/axiomcode-path
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,10 @@ BODILESS_KINDS = {'METHOD_SIGNATURE', 'TYPE_LITERAL_METHOD_SIGNATURE', 'CALL_SIG
'FUNCTION_TYPE_SIGNATURE', 'CONSTRUCT_SIGNATURE', 'TYPE_LITERAL_CONSTRUCT_SIGNATURE', 'CONSTRUCTOR_TYPE_SIGNATURE'}
# of those, the ones a call through a VALUE lands on: a function type or a bare call signature, not a member of an interface
FUNCTION_TYPE_KINDS = {'FUNCTION_TYPE_SIGNATURE', 'CALL_SIGNATURE', 'TYPE_LITERAL_CALL_SIGNATURE'}
# the one name a front end gives every lambda it declares (Python and C#; Java declares none): a name that says nothing
# about WHICH lambda, so it is never a target on its own (G.lambda_label, G.lambda_target)
LAMBDA_NAMES = {'<lambda>'}
# the one name a front end gives every lambda it declares (Python and C# `<lambda>`, C# `<anonymous-method>`, TypeScript
# and JavaScript `<arrow>` / `<function-expression>`; Java declares none): a name that says nothing about WHICH lambda,
# so it is never a target on its own (G.lambda_label, G.lambda_target)
LAMBDA_NAMES = {'<lambda>', '<anonymous-method>', '<arrow>', '<function-expression>'}
# what a front end synthesises ON a field's line that is the field's own, never a callable written there (G.decl_at_line):
# the node that runs a class's field initializers, and the unnamed function an initializer holds (`cb = wrap(() => …)`),
# which JavaScript and TypeScript name `<arrow>` / `<function-expression>` where Python and C# say `<lambda>`
Expand Down
29 changes: 29 additions & 0 deletions tests/cases/csharp/grown-file-read-against-its-base/case.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"lang": "csharp",
"src": "src",
"checks": [
{
"why": "a graph from a later text than the base: a parameter inserted into a constructor header written one per line (a C# constructor is recorded as `<constructor>`, its header spells the type's name) is its signature change, not its body and not a removal; a new method with a generic return type is named as added, and a local in it is no field",
"run": [
"changed",
"{repo}",
"--old",
"{repo}/old.cs",
"--new",
"{repo}/new.cs",
"--file",
"src/Service.cs"
],
"want": [
"signature Service.<constructor>",
"+gateway",
"added Service.Pay"
],
"avoid": [
"removed",
"Service.total",
"added Service.gateway src/Service.cs:11"
]
}
]
}
33 changes: 33 additions & 0 deletions tests/cases/csharp/grown-file-read-against-its-base/new.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
namespace App
{
public class Service
{
private readonly Repo repo;

private readonly Gateway gateway;

public Service(
Repo repo,
Gateway gateway,
Clock clock)
{
this.repo = repo;
this.gateway = gateway;
}

public int Get(string id)
{
return repo.Find(id);
}

public async System.Threading.Tasks.Task<int> Pay(int n)
{
var total = n;
return await gateway.Pay(total);
}
}

public class Repo { public int Find(string id) { return 0; } }
public class Clock { }
public class Gateway { public System.Threading.Tasks.Task<int> Pay(int n) { return System.Threading.Tasks.Task.FromResult(n); } }
}
19 changes: 19 additions & 0 deletions tests/cases/csharp/grown-file-read-against-its-base/old.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace App
{
public class Service
{
private readonly Repo repo;

public Service(
Repo repo,
Clock clock)
{
this.repo = repo;
}

public int Get(string id)
{
return repo.Find(id);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
namespace App
{
public class Service
{
private readonly Repo repo;

private readonly Gateway gateway;

public Service(
Repo repo,
Gateway gateway,
Clock clock)
{
this.repo = repo;
this.gateway = gateway;
}

public int Get(string id)
{
return repo.Find(id);
}

public async System.Threading.Tasks.Task<int> Pay(int n)
{
var total = n;
return await gateway.Pay(total);
}
}

public class Repo { public int Find(string id) { return 0; } }
public class Clock { }
public class Gateway { public System.Threading.Tasks.Task<int> Pay(int n) { return System.Threading.Tasks.Task.FromResult(n); } }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"lang": "javascript",
"src": "src",
"checks": [
{
"why": "a graph from a later text than the base: a parameter inserted into a constructor header is its signature change; an edit inside an arrow passed from a method is that method's body, not an `<arrow>` of its own; a new method and an exported async function are named, and a local in the function is no field of the class",
"run": [
"changed",
"{repo}",
"--old",
"{repo}/old.js",
"--new",
"{repo}/new.js",
"--file",
"src/service.js"
],
"want": [
"signature Service.<constructor>",
"+gateway",
"added Service.pay",
"added report",
"body Service.get"
],
"avoid": [
"removed",
"Service.base",
"Service.total",
"<arrow>",
"<function-expression>"
]
}
]
}
26 changes: 26 additions & 0 deletions tests/cases/javascript/grown-file-read-against-its-base/new.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
export class Service {
constructor(
repo,
clock,
gateway,
) {
this.repo = repo;
this.gateway = gateway;
}

get(id) {
return this.repo.run(async () => {
return this.pay(this.repo.find(id));
});
}

async pay(n) {
const total = n;
return this.gateway.pay(total);
}
}

export async function report(event) {
const base = { id: event.id };
return base;
}
14 changes: 14 additions & 0 deletions tests/cases/javascript/grown-file-read-against-its-base/old.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export class Service {
constructor(
repo,
clock,
) {
this.repo = repo;
}

get(id) {
return this.repo.run(async () => {
return this.repo.find(id);
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
export class Service {
constructor(
repo,
clock,
gateway,
) {
this.repo = repo;
this.gateway = gateway;
}

get(id) {
return this.repo.run(async () => {
return this.pay(this.repo.find(id));
});
}

async pay(n) {
const total = n;
return this.gateway.pay(total);
}
}

export async function report(event) {
const base = { id: event.id };
return base;
}
52 changes: 52 additions & 0 deletions tests/cases/python/grown-file-read-against-its-base/case.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"lang": "python",
"src": "src",
"checks": [
{
"why": "a graph from a later text than the base: a parameter inserted into a def header written one per line is its signature change; new methods at the end of a class and a function after it are one inserted block, and the function is named at the top level, not dropped nor read as a member",
"run": [
"changed",
"{repo}",
"--old",
"{repo}/old.py",
"--new",
"{repo}/new.py",
"--file",
"src/service.py"
],
"want": [
"signature Service.__init__",
"+gateway",
"added Service.pay",
"added report"
],
"avoid": [
"removed",
"Service.total",
"Service.base",
"Service.report",
"new line(s)"
]
},
{
"why": "control: a method added after a class's last method, at the same indentation, is not that method's body; a line appended inside `__init__` is",
"run": [
"changed",
"{repo}",
"--old",
"{repo}/old.py",
"--new",
"{repo}/new.py",
"--file",
"src/service.py"
],
"want": [
"signature Service.__init__"
],
"avoid": [
"body Service.get",
"inside Service"
]
}
]
}
21 changes: 21 additions & 0 deletions tests/cases/python/grown-file-read-against-its-base/new.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
class Service:
def __init__(
self,
repo,
clock,
gateway,
):
self.repo = repo
self.gateway = gateway

def get(self, id):
return self.repo.find(id)

async def pay(self, n) -> int:
total = n
return await self.gateway.pay(total)


def report(event):
base = {"id": event.id}
return base
10 changes: 10 additions & 0 deletions tests/cases/python/grown-file-read-against-its-base/old.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class Service:
def __init__(
self,
repo,
clock,
):
self.repo = repo

def get(self, id):
return self.repo.find(id)
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
class Service:
def __init__(
self,
repo,
clock,
gateway,
):
self.repo = repo
self.gateway = gateway

def get(self, id):
return self.repo.find(id)

async def pay(self, n) -> int:
total = n
return await self.gateway.pay(total)


def report(event):
base = {"id": event.id}
return base
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Clock, Repo } from './repo';

export class Service {
private readonly cache: Map<string, number>;

constructor(
private readonly repo: Repo,
clock: Clock,
) {
this.cache = new Map([["", 0]]);
}

place(id: string): Promise<number> {
return this.repo.run(async () => {
const n = await this.repo.find(id);
return n;
});
}

get(id: string): number {
return this.cache.get(id) ?? 0;
}
}
Loading
Loading