Skip to content

Commit fd10dd7

Browse files
committed
#343: Arrow Functions, add static and return refs.
1 parent 40edfce commit fd10dd7

File tree

10 files changed

+65
-60
lines changed

10 files changed

+65
-60
lines changed

jphp-core/src/org/develnext/jphp/core/compiler/jvm/statement/expr/value/ClosureValueCompiler.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ public void write(ClosureStmtToken closure, boolean returnValue) {
8686
if (returnValue){
8787
ClosureEntity entity = compiler.getModule().findClosure( closure.getId() );
8888
boolean thisExists = closure.getFunction().isThisExists();
89+
90+
if (closure.isStatic()) {
91+
thisExists = false;
92+
}
93+
8994
boolean staticExists = closure.getFunction().isStaticExists();
9095

9196
if (closure.getFunction().getUses().isEmpty() && !thisExists && !staticExists

jphp-core/src/org/develnext/jphp/core/syntax/generators/LambdaGenerator.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import org.develnext.jphp.core.syntax.generators.manually.SimpleExprGenerator;
77
import org.develnext.jphp.core.tokenizer.token.Token;
88
import org.develnext.jphp.core.tokenizer.token.expr.BraceExprToken;
9+
import org.develnext.jphp.core.tokenizer.token.expr.operator.AmpersandRefToken;
910
import org.develnext.jphp.core.tokenizer.token.expr.operator.KeyValueExprToken;
1011
import org.develnext.jphp.core.tokenizer.token.expr.value.VariableExprToken;
1112
import org.develnext.jphp.core.tokenizer.token.stmt.*;
@@ -72,6 +73,13 @@ public LambdaStmtToken getToken(Token current, ListIterator<Token> iterator, Sep
7273

7374
nextToken(iterator);
7475

76+
Token tk = nextToken(iterator);
77+
if (tk instanceof AmpersandRefToken) {
78+
func.setReturnReference(true);
79+
} else {
80+
prevToken(iterator);
81+
}
82+
7583
processArguments(func, iterator);
7684
nextAndExpected(iterator, KeyValueExprToken.class);
7785
processBody(func, iterator, separator, braceKind);

jphp-core/src/org/develnext/jphp/core/syntax/generators/manually/SimpleExprGenerator.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,14 @@ public boolean isSingleton() {
6262
return false;
6363
}
6464

65-
protected Token processLambda(Token current, ListIterator<Token> iterator, Separator separator, BraceExprToken.Kind braceKind) {
65+
protected Token processLambda(Token current, ListIterator<Token> iterator, Separator separator, BraceExprToken.Kind braceKind, boolean isStatic) {
6666
LambdaStmtToken token = analyzer.generator(LambdaGenerator.class).getToken(current, iterator, separator, braceKind);
6767

6868
ClosureStmtToken closureStmtToken = new ClosureStmtToken(current.getMeta());
6969
closureStmtToken.setFunction(token.getFunction());
7070
closureStmtToken.setOwnerClass(analyzer.getClazz());
7171
closureStmtToken.setParentFunction(token.getParentFunction());
72+
closureStmtToken.setStatic(isStatic);
7273
analyzer.registerClosure(closureStmtToken);
7374

7475
return closureStmtToken;
@@ -1488,8 +1489,12 @@ else if (previous instanceof StaticAccessExprToken){
14881489
} else if (current instanceof FunctionStmtToken) {
14891490
current = processClosure(current, next, iterator);
14901491
tokens.add(current);
1492+
} else if (current instanceof StaticExprToken && nextTokenAndPrev(iterator) instanceof LambdaStmtToken) {
1493+
current = nextToken(iterator);
1494+
current = processLambda(current, iterator, separator, closedBraceKind, true);
1495+
tokens.add(current);
14911496
} else if (current instanceof LambdaStmtToken) {
1492-
current = processLambda(current, iterator, separator, closedBraceKind);
1497+
current = processLambda(current, iterator, separator, closedBraceKind, false);
14931498
tokens.add(current);
14941499
} else if (current instanceof ListExprToken && isOpenedBrace(next, SIMPLE)){
14951500
current = processList(current, iterator, null, closedBraceKind, braceOpened);

jphp-core/src/org/develnext/jphp/core/tokenizer/token/expr/value/ClosureStmtToken.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ public class ClosureStmtToken extends ValueExprToken {
1111
protected FunctionStmtToken parentFunction;
1212
protected ClassStmtToken ownerClass;
1313
protected int id;
14+
protected boolean _static;
1415

1516
public ClosureStmtToken(TokenMeta meta) {
1617
super(meta, TokenType.T_J_CUSTOM);
@@ -32,6 +33,14 @@ public void setId(int id) {
3233
this.id = id;
3334
}
3435

36+
public boolean isStatic() {
37+
return _static;
38+
}
39+
40+
public void setStatic(boolean _static) {
41+
this._static = _static;
42+
}
43+
3544
public ClassStmtToken getOwnerClass() {
3645
return ownerClass;
3746
}

jphp-core/tests/resources/lambdas/lambda_this_001.php

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
2+
$GLOBALS['x'] = 20;
23

34
class Test {
4-
55
function make(): Closure
66
{
77
return fn() => $this;
@@ -11,6 +11,16 @@ function make2(): Closure
1111
{
1212
return fn() => fn() => $this;
1313
}
14+
15+
function make3(): Closure
16+
{
17+
return static fn() => $this;
18+
}
19+
20+
function make4(): Closure
21+
{
22+
return fn&() => $GLOBALS['x'];
23+
}
1424
}
1525

1626
$test = new Test();
@@ -27,4 +37,17 @@ function make2(): Closure
2737
return "fail_2";
2838
}
2939

40+
$lambda = $test->make3();
41+
if ($lambda() !== null) {
42+
return "fail_3";
43+
}
44+
45+
$lambda = $test->make4();
46+
$x = $lambda();
47+
$x = 40;
48+
if ($GLOBALS['x'] !== 40) {
49+
return "fail_4";
50+
}
51+
52+
3053
return "success";

jphp-runtime/src/php/runtime/lang/Closure.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,17 @@ public Memory bindTo(Environment env, Memory... args) throws CloneNotSupportedEx
135135
return new ObjectMemory(newClosure);
136136
}
137137

138+
@Signature
139+
public Memory __debugInfo(Environment env, Memory... args) {
140+
ArrayMemory r = new ArrayMemory();
141+
142+
if (self.isNotNull()) {
143+
r.put("this", self.toImmutable());
144+
}
145+
146+
return r;
147+
}
148+
138149
@Signature({
139150
@Arg(value = "closure", typeClass = "Closure"),
140151
@Arg(value = "newThis"),

jphp-runtime/src/php/runtime/memory/output/PrintR.java

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -113,28 +113,6 @@ protected void writeObjectHeader(String name){
113113
printer.write(" Object\n");
114114
}
115115

116-
@Override
117-
protected void printClosure(Closure closure, int level, Set<Integer> used) {
118-
ClassEntity classEntity = closure.getReflection();
119-
120-
writeObjectHeader(Closure.class.getSimpleName());
121-
if (used.contains(closure.getPointer())){
122-
printer.write(" *RECURSION*");
123-
} else {
124-
printer.write(StringUtils.repeat(' ', level));
125-
writeOpen();
126-
level += PRINT_INDENT;
127-
128-
used.add(closure.getPointer());
129-
130-
level -= PRINT_INDENT;
131-
printer.write(StringUtils.repeat(' ', level));
132-
writeClose();
133-
134-
used.remove(closure.getPointer());
135-
}
136-
}
137-
138116
@Override
139117
protected void printObject(ObjectMemory value, int level, Set<Integer> used) {
140118
ClassEntity classEntity = value.getReflection();

jphp-runtime/src/php/runtime/memory/output/Printer.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ public boolean isRecursionExists() {
3333
abstract protected void printString(StringMemory value);
3434
abstract protected void printArray(ArrayMemory value, int level, Set<Integer> used);
3535
abstract protected void printObject(ObjectMemory value, int level, Set<Integer> used);
36-
abstract protected void printClosure(Closure value, int level, Set<Integer> used);
3736

3837
protected void printReference(ReferenceMemory reference, int level, Set<Integer> used){
3938
Memory value = reference.toValue();
@@ -64,11 +63,7 @@ protected void print(Memory value, int level, Set<Integer> used){
6463
printArray((ArrayMemory) value, level, used);
6564
break;
6665
case OBJECT:
67-
ObjectMemory tmp = (ObjectMemory)value;
68-
if (tmp.value instanceof Closure)
69-
printClosure((Closure)tmp.value, level, used);
70-
else
71-
printObject((ObjectMemory) value, level, used);
66+
printObject((ObjectMemory) value, level, used);
7267
break;
7368
case REFERENCE: printReference((ReferenceMemory)value, level, used); break;
7469
default:

jphp-runtime/src/php/runtime/memory/output/VarDump.java

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -116,30 +116,6 @@ protected void printArray(ArrayMemory value, int level, Set<Integer> used) {
116116
}
117117
}
118118

119-
@Override
120-
protected void printClosure(Closure closure, int level, Set<Integer> used) {
121-
ClassEntity classEntity = closure.getReflection();
122-
123-
if (used.contains(closure.getPointer())){
124-
printer.write("*RECURSION*\n");
125-
} else {
126-
printer.write("object(");
127-
printer.write(Closure.class.getSimpleName());
128-
printer.write(")#" + closure.getPointer());
129-
printer.write(" (" + closure.getUses().length + ") {\n");
130-
131-
level += PRINT_INDENT;
132-
133-
used.add(closure.getPointer());
134-
135-
level -= PRINT_INDENT;
136-
printer.write(StringUtils.repeat(' ', level));
137-
printer.write("}\n");
138-
139-
used.remove(closure.getPointer());
140-
}
141-
}
142-
143119
@Override
144120
protected void printObject(ObjectMemory value, int level, Set<Integer> used) {
145121
ClassEntity classEntity = value.getReflection();

jphp-runtime/src/php/runtime/memory/output/VarExport.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,4 @@ protected void printObject(ObjectMemory value, int level, Set<Integer> used) {
139139
used.remove(value.getPointer());
140140
}
141141
}
142-
143-
@Override
144-
protected void printClosure(Closure value, int level, Set<Integer> used) {
145-
printObject(new ObjectMemory(value), level, used);
146-
}
147142
}

0 commit comments

Comments
 (0)