8000 Have constructor list for more human like C++ code as well as more flexible immutable variables (Ignore the failed testcases, trust me bro) by Just-Feeshy · Pull Request #50 · SomeRanDev/reflaxe.CPP · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Have constructor list for more human like C++ code as well as more flexible immutable variables (Ignore the failed testcases, trust me bro) #50

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 17, 2024

Conversation

Just-Feeshy
Copy link
Contributor

This will most likely fail a good portion of unit tests due to the change in how constructors are compiled now. I added constructor list support for the compiler because I came across a situation with my own learning project that would almost require the argument to be put in the constructor list since the class's property variable was immutable. Let me show an example. I do recommend doing some further tests of your own to see if there might be any issues.

This is the Test.hx I used:

package;

class Test {
		public var lol:String;
		public var hah:String;

		@:const private var test:String;

		public function gyatt() {
			trace("gyatt");
		}

		public function new(hah:String) {
		    for (i in 0...hah.length) {
		        trace(i);
		    }

		    this.lol= "lol";
		       this.hah = hah;
			trace("Hello World");
			this.start();

			this.test = "test 2";
		}

		public function start() {
			trace("Starting...");
			trace("test: " + test);
		}
}

And here is how it would look before this PR:

#include "Test.h"

#include <iostream>
#include <memory>
#include <string>
#include "_AnonStructs.h"
#include "haxe_Log.h"

using namespace std::string_literals;

Test::Test(std::string hah):
	_order_id(generate_order_id())
{
	int _g = 0;
	int _g1 = (int)(hah.size());

	while(_g < _g1) {
		int i = _g++;

		haxe::Log::trace(i, haxe::shared_anon<haxe::PosInfos>("Test"s, "Test.hx"s, 15, "new"s));
	};

	this->lol = "lol"s;
	this->hah = hah;
	std::cout << "Test.hx:20: Hello World"s << std::endl;
	this->start();
	this->test = "test 2"s;
}

void Test::gyatt() {
	std::cout << "Test.hx:10: gyatt"s << std::endl;
}

void Test::start() {
	std::cout << "Test.hx:27: Starting..."s << std::endl;
	haxe::Log::trace("test: "s + this->test, haxe::shared_anon<haxe::PosInfos>("Test"s, "Test.hx"s, 28, "start"s));
}

And I received an error since I'm trying to overload an immutable variable. However, I really just want to initialize my variable with my argument.

src/Test.cpp:27:13: error: no viable overloaded '='
   27 |         this->test = "test 2"s;
      |         ~~~~~~~~~~ ^ ~~~~~~~~~
/opt/homebrew/opt/llvm/bin/../include/c++/v1/string:1113:3: note: candidate function not viable: 'this' argument has type 'const std::string' (aka 'const basic_string<char>'), but method is not marked const
 1113 |   operator=(const basic_string& __str);
      |   ^
/opt/homebrew/opt/llvm/bin/../include/c++/v1/string:1119:47: note: candidate template ignored: requirement '!__is_same_uncvref<std::string, std::string>::value' was not satisfied [with _Tp = basic_string<char>]
 1119 |   _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(const _Tp& __t) {
      |                                               ^
/opt/homebrew/opt/llvm/bin/../include/c++/v1/string:1125:69: note: candidate function not viable: 'this' argument has type 'const std::string' (aka 'const basic_string<char>'), but method is not marked const
 1125 |   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(basic_string&& __str)
      |                                                                     ^
/opt/homebrew/opt/llvm/bin/../include/c++/v1/string:1131:69: note: candidate function not viable: 'this' argument has type 'const std::string' (aka 'const basic_string<char>'), but method is not marked const
 1131 |   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(initializer_list<value_type> __il) {
      |                                                                     ^
/opt/homebrew/opt/llvm/bin/../include/c++/v1/string:1135:69: note: candidate function not viable: 'this' argument has type 'const std::string' (aka 'const basic_string<char>'), but method is not marked const
 1135 |   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(const value_type* __s) {
      |                                                                     ^
/opt/homebrew/opt/llvm/bin/../include/c++/v1/string:1141:85: note: candidate function not viable: 'this' argument has type 'const std::string' (aka 'const basic_string<char>'), but method is not marked const
 1141 |   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS basic_string& operator=(value_type __c);
      |                                                                                     ^
1 error generated.

Now with this PR, I can do exactly that without removing the @:const keyword:

#include "Test.h"

#include <iostream>
#include <memory>
#include <string>
#include "_AnonStructs.h"
#include "haxe_Log.h"

using namespace std::string_literals;

Test::Test(std::string hah):
	_order_id(generate_order_id()), test("test 2"s), hah(hah), lol("lol"s)
{
	int _g = 0;
	int _g1 = (int)(hah.size());

	while(_g < _g1) {
		int i = _g++;

		haxe::Log::trace(i, haxe::shared_anon<haxe::PosInfos>("Test"s, "Test.hx"s, 15, "new"s));
	};
	std::cout << "Test.hx:20: Hello World"s << std::endl;
	this->start();
}

void Test::gyatt() {
	std::cout << "Test.hx:10: gyatt"s << std::endl;
}

void Test::start() {
	std::cout << "Test.hx:27: Starting..."s << std::endl;
	haxe::Log::trace("test: "s + this->test, haxe::shared_anon<haxe::PosInfos>("Test"s, "Test.hx"s, 28, "start"s));
}

There we go! It works!

Test.hx:15: 0
Test.hx:15: 1
Test.hx:15: 2
Test.hx:15: 3
Test.hx:15: 4
Test.hx:15: 5
Test.hx:15: 6
Test.hx:15: 7
Test.hx:15: 8
Test.hx:15: 9
Test.hx:15: 10
Test.hx:20: Hello World
Test.hx:27: Starting...
Test.hx:28: test: test 2
Main.hx:3: Hello World

@Just-Feeshy Just-Feeshy changed the title Have constructor list for more human like C++ code as well as more flexible immutable variables Have constructor list for more human like C++ code as well as more flexible immutable variables (Ignore the failed testcases, trust me bro) Jun 17, 2024
@SomeRanDev SomeRanDev merged commit 7e82e4a into SomeRanDev:main Jun 17, 2024
1 of 4 checks passed
github-actions bot pushed a commit that referenced this pull request Jun 17, 2024
Have c
8000
onstructor list for more human like C++ code as well as more flexible immutable variables (Ignore the failed testcases, trust me bro)
SomeRanDev added a commit that referenced this pull request Jun 17, 2024
SomeRanDev added a commit that referenced this pull request Jun 17, 2024
github-actions bot pushed a commit that referenced this pull request Jun 17, 2024
@SomeRanDev
Copy link
Owner

OOF, I think I merged this too quickly. When you said tests didn't work, I assume the tests just needed to be regenerated... but this actually breaks a lot of stuff. 😅

Mainly the direct String manipulation breaks lambda assignments in constructors and other large constructions in there. For example, Issue38_CallFindFuncDataOnVar test generates like this:

Main::Main():
	_order_id(generate_order_id()), fn([&]() mutable {	std::cout << "test/unit_testing/tests/Issue38_CallFindFuncDataOnVar/Main.hx:12: do something"s << std::endl)
{

	};
	this->fn();
}

I wrote this as a comment in the code, but I guess seeing how troublesome this is, I think my "TODO" has to happen immediately for this feature to be properly added. The correct way to do this would be to analyze the constructor function body's TypedExpr. This can be done above the following code using bodyExpr:

XComp.pushTrackLines(useCallStack);
body.push(Main.compileClassFuncExpr(bodyExpr));
XComp.popTrackLines();

If bodyExpr is TBlock, extract the expressions from it and read the expressions from the start of the list as long as they are TBinop(OpAssign, TField(e, name), e2) expressions where the e expression is a TConst(TThis). Filter out expressions where e2 is not simple or constant. Haxe always generates the this->NAME = INIT_VALUE expressions at the start of the constructor, so once those stop appearing, you can end the process. You would then need a system to ignore these expressions when generating in the Expressions compiler, not sure exactly how to do that yet. Hmmm...

@SomeRanDev
Copy link
Owner

Also, don't forget the fields are compiled before functions, so maybe the ones you want to initialize in the constructor can be stored there and then accessed later? There's a lot of ways this could be done, sorry my code is such a mess.

@Just-Feeshy
Copy link
Contributor Author

I assume that this is still under ctx.isConstructor since we are only working with the constructor's fields.

@Just-Feeshy Just-Feeshy deleted the Prop branch June 21, 2024 07:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
0