Reflect.field on public static inline return null
With the nightly build e477477 (2017-10-01 21:32);
If I want resolve an public static inline with Reflect.field, I get null.
Without inline is working.
class Test {
public static inline var TEST="hehe";
public static function main() {
trace("Haxe is great!");
var classReference : Class<Dynamic> = Type.resolveClass( "Test" );
trace("Test.TEST: " + Test.TEST);
trace(Reflect.field(Test, "TEST"));
}
}
haxe -main Test.hx -php test && php test/index.php
Related to HaxeFoundation/haxe#6583 hexMachina failing test : https://travis-ci.org/DoclerLabs/hexCore/jobs/282173307#L1135
cc @RealyUniqueName
Working correctly on haxe 3.4.2
Nothing changed in genphp regarding static vars. Maybe inlined vars are now gone before compiled code get to generator.
Maybe Reflect::field(Boot::getClass(Test::class), "TEST") do not work with php const :
With nightly and inline
const TEST = "hehe";
Without inline
static public $TEST = "hehe";
And with 3.4.2, with and without inline
static $TEST = "hehe";
the rest of generated code looks similar.
It looks like static inline var is now cut out by dce. Disable dce or add @:keep and it will be generated.
Also since it's supposed to be inlined, i think it's not valid to rely on existance of this field at runtime.
It's generated as class const to improve interop with 3rd-party php code.
I don't get the point about DCE, because the const is in the generated PHP. By the way, the problem still with @:keep or haxe -main Test.hx -php test -dce no && php test/index.php.
Test.hx:6: Haxe is great!
Test.hx:8: Test.TEST: hehe
Test.hx:9: null
The behavior is no the same between Haxe 3.4.2 and Haxe 4.
The point with DCE is that genphp can't generate something, which does not exist when compiled code comes to generator.
I checked 3.4.2 and static inline var did not survive DCE. Here is an example for js, but it's the same for php: https://try.haxe.org/#EEf1e
I doubt it can be considered a bug. cc @Simn
As for Reflect.field() i now think you're right. This is a bug.
If you use DCE it makes sence, but here is not the case, and const is generated, but not accessible by Reflect.field.
Bellow the PHP generated from the example :
<?php
/**
* Generated by Haxe 4.0.0 (git build development @ e477477)
*/
use \php\Boot;
use \haxe\Log;
use \php\_Boot\HxAnon;
class Test {
/**
* @var string
*/
const TEST = "hehe";
/**
* @return void
*/
static public function main () {
#Test.hx:6: characters 5-10
(Log::$trace)("Haxe is great!", new HxAnon([
"fileName" => "Test.hx",
"lineNumber" => 6,
"className" => "Test",
"methodName" => "main",
]));
#Test.hx:7: characters 5-71
$classReference = \Type::resolveClass("Test");
#Test.hx:8: characters 5-10
(Log::$trace)("Test.TEST: " . "hehe", new HxAnon([
"fileName" => "Test.hx",
"lineNumber" => 8,
"className" => "Test",
"methodName" => "main",
]));
#Test.hx:9: characters 5-10
(Log::$trace)(\Reflect::field(Boot::getClass(Test::class), "TEST"), new HxAnon([
"fileName" => "Test.hx",
"lineNumber" => 9,
"className" => "Test",
"methodName" => "main",
]));
}
/**
* @return void
*/
public function __construct () {
}
}
Boot::registerClass(Test::class, 'Test');
The test failed for the cpp target.
Command: /home/travis/build/HaxeFoundation/haxe/tests/unit/bin/cpp/TestMain-debug []
TestMain.hx:38: Generated at: 2017-10-03 06:47:00
TestMain.hx:40: START
Issue6630.hx:9: null should be hello
Issue6630.hx:10: null should be hello
Test.hx:222: DONE [7226 tests]
Test.hx:223: SUCCESS: false
Maybe open separate issue for cpp?
Feel free to reassign to hugh or open a separate issue. I merely reopen this because the failed test case is from here. :)
There could be some code-size issues making inline-variables reflective. If we are going have the option of "final", then I would suggest that no reflection is the correct optimization & behaviour for "inline", since "final" would mean reflective/read-only/use in "case", so there would be some value in having both.
I agree anything inline should not be reflective. These two concepts just don't mix.
It's still nice to be able to generate such fields. E.g. if i use haxe generated php code in "native" php code.
Clarifying docs for Reflect should be enough.
But shouldnt one use extern inline if she does not want to generate the field?
Moreover, what a user can do to keep the method at runtime? Use @:keep?
I think "being reflective" is one level above "being generated". But that probably depends on the actual target.
Can we remove Reflect in Haxe 4? :P
inline fields should be DCE'd if they are not used, but they should not be removed with -dce no
On Tue, Oct 10, 2017 at 6:55 PM, Juraj Kirchheim [email protected] wrote:
Can we remove Reflect in Haxe 4? :P
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/HaxeFoundation/haxe/issues/6630#issuecomment-335538892, or mute the thread https://github.com/notifications/unsubscribe-auth/AA-bwETj_elF8sTNFlTkFj7ltK2qaMx4ks5sq6FtgaJpZM4PqrYn .
And yes, generated means reflective/Dynamic accessible in Haxe specification.
On Wed, Oct 11, 2017 at 3:17 PM, Nicolas Cannasse [email protected] wrote:
inline fields should be DCE'd if they are not used, but they should not be removed with -dce no
On Tue, Oct 10, 2017 at 6:55 PM, Juraj Kirchheim <[email protected]
wrote:
Can we remove Reflect in Haxe 4? :P
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/HaxeFoundation/haxe/issues/6630#issuecomment-335538892, or mute the thread https://github.com/notifications/unsubscribe-auth/AA-bwETj_elF8sTNFlTkFj7ltK2qaMx4ks5sq6FtgaJpZM4PqrYn .
What about @:extern? The semantics of that aren't really clear to me because we basically use it as @:forceInline.
@:extern means no generation , like if the class was extern (but it's per field/class)
and it implies forceInline because else it would fail at runtime
I still get the issue with 4.0.0-preview.3 on cpp.
class Main {
public static inline var TEST="hehe";
public static function main() {
trace("Haxe is great!");
var classReference : Class<Dynamic> = Type.resolveClass( "Main" );
trace("Main.TEST: " + Main.TEST);
trace(Reflect.field(Main, "TEST"));
}
}
LUX153:Desktop laurent$ haxe -main Main.hx -cpp test && test/Main
haxelib run hxcpp Build.xml haxe -Dhaxe3="1" -Dhaxe_ver="4.000" -Dhxcpp_api_level="332" -Dsource-header="Generated by Haxe 4.0.0 (git build development @ 3018ab1)" -Dstatic="1" -I"" -I"/Users/laurent/haxe/versions/4.0.0-preview.3/std/cpp/_std/" -I"/Users/laurent/haxe/versions/4.0.0-preview.3/std/"
Main.hx:6: Haxe is great!
Main.hx:8: Main.TEST: hehe
Main.hx:9: null
I confirm this is still an issue on hxcpp.
Can confirm this issue is still occurring. For HaxeFlixel games, this affects the AssetPaths class as well as other static inline fields.
C++, this doesn't happen on static inline functions, only on static inline variables, i feel like this is a bug, it should either be "both work on reflection" or "neither work on reflection", in my personal opinion i feel like they should both work on reflection.