"(a=b).value" => "unresolved symbol"

I don't know how it's happening. Idea says "unresolved symbol" only :).
next for copy-paste:
using StringTools;
class Demo{
function demo(){
var lines = "--+--+--".split("+");
for(i in 0...lines.length)
if((lines[i] = lines[i].rtrim()).length > 0)
trace(lines[i]);
}
}
TIR: STB-7290
More simply and without using:
var a = {v:1};
var b = 1;
(a = (a.v + b)).v // <- unresolved

In "more..." - nothing.
If I read the second example correctly, then 'a' is being assigned the value 2, instead of the structure that it used to point to. Therefore, 'a' no longer has a '.v' field to resolve. (Thus, the result is correct.)
The first example is more interesting, since the resulting type of 'line[i]' after the assignment is still a String.
Ooo, it's stupid typo. Correctly: 'a.v =' instead 'a ='.
I still don't think so. The type of an assignment is the type of the value that was assigned, not the type of the object which was assigned to; in the case '(a.v = (a.v + b))', the type of the value assigned is an integer, which doesn't have a .v field. (And my first comment was also misleading in that I focused on 'a', rather than the type of the assignment.)
Consider the following: var c = (a.v = a.v + b); The variable 'c' holds an integer because the value assigned to 'a.v' was an integer (the result of an addition operation). It would not be a copy of 'a', or even a copy of the field 'a.v'.
The first (and correctly coded) example shows the bug: that the result of an expression is not typed correctly by the haxe plugin when the expression is an assignment wrapped in parenthesis.
In the demo program below (adapted from above), rtrim() remains unresolved because the compiler conditionals are choking when parsing the following line in StringTools.hx:
public static #if (cs || java) inline #end function startsWith( s : String, start : String ) : Bool {
The error is
PsiErrorElement:The rest of the file doesn't parse, so we don't find the rtrim function in StringTools., '@:autoBuild', '@:build', '@:debug', '@:final', '@:getter', '@:keep', '@:macro', '@:meta', '@:nodebug', '@:ns', '@:overload', '@:protected', '@:require', '@:setter', MACRO_ID or static expected, got 'static'(3912,3912)
using StringTools;
class Demo{
function demo(){
var lines = "--+--+--".split("+");
for(i in 0...lines.length)
if((lines[i] = lines[i].rtrim()).length > 0) { // <-- remains unresolved
trace(lines[i]);
lines[i].rtrim();
StringTools.rtrim(lines[i]); // <--rtrim is unresolved
}
}
function demo2() {
var a = {v:1};
var b = 1;
var c = a.v; // <- unresolved
(a = (a.v + b)).v // <- unresolved
}
}
At the following line, .v could be resolvable, though it might be a bit complex: The parser would have to track the type of variable 'a' as an anonymous class. And track it through assignments, which really is a runtime function. It's not this simple example that is tricky, it's when the code becomes complex, or there are multiple steps before the resolution is needed.
var c = a.v; // <- unresolved
The second resolve case in demo2() was discussed above.
Even simpler cases like these are not working:
(new haxe.Timer(1000)).run(); (m[i]).length; // m is Array<String>
Any expression in paranthesis is not being interpreted correctly as HaxeReference.
I fixed most cases except the very two examples that fzzr mentioned. That's because, in those two cases... it is unresolved on a local identifier. HaxeIdentifier is not of type HaxeReference (but it is inside HaxeReferenceExpression). Also, some PSI compliance is missing for HaxeIdentifier.
So, I will commit the fixes made so far for handling other kinds of expressions in paranthesis. I will update once I fix the HaxeIdentifier kinds as in examples by fzzr.
This kind of stuff is hard to resolve in current architecture. I am unassigning this from me, I did partial work that resolved several expression types that are within paranthesis (which was not working earlier... but I did not resolve the 2 examples by fzzr and they are best resolved (1) either by implementing many unimplemented methods in HaxeReferenceImpl, HaxeIdentifierPsiMixInImpl (for PSI compliance) etc, (2) or by using Haxe compiler for type inference and code assist. Solution # 1 will not be robust enough and hard to keep up with language like Haxe because OpenAPI PSI is more Java oriented and does not encompass supporting all kinds that Haxe allows. Also the language changes needs frequent patches to implementation if # 1 route is taken. So, I'm suggested to go for # 2.
Unresolved too:
var a:{v:Int} = {v:1};
var c = a.v; // <- unresolved
Here's the current state at 0.11.0-RC3:
class Demo{
function demo(){
var lines = "--+--+--".split("+");
for(i in 0...lines.length)
if((lines[i] = lines[i].rtrim()).length > 0) { // <-- remains unresolved
trace(lines[i]);
lines[i].rtrim();
StringTools.rtrim(lines[i]); // <--rtrim is unresolved -- Fixed!!
}
}
function demo2() {
var a = {v:1};
var b = 1;
var c = a.v; // <- unresolved
var d = (a = (a.v + b)).v; // <- unresolved -- And should remain so!!
var e = (a.v = (a.v + b)).v; // <- unresolved -- And should remain so!!
var f = a;
f.v = (a.v = (a.v + b)); // <- unresolved -- and should be -- both at f and internally.
}
function demo3() {
var a:{v:Int} = {v:1}; // Specific typing doesn't seem to help.
var c = a.v; // <- unresolved
}
function demo4() { // From Srikanth
(new haxe.Timer(1000)).run(); // <- unresolved
var m:Array<Int> = new Array<Int>(0);
(m[i]).length; // m is Array // <- unresolved
}
}
Hm, why it should remain to be unresolved? Isn't IDE's prime duty is to make coding easy and comfortable? :-)
var d = (a = (a.v + b)).v; should remain unresolved -- marked as an error would be better -- because the type of sub-expression (a = (a.v + b)) is an integer, not an anonymous type. Integers don't have fields named .v.
For a more precise explanation, you can read my above comment from Oct 11, 2015. The short story is: The last thing assigned a = is an integer, and this is still true if a.v = is assigned. Parenthesis change evaluation ordering, but do not change the type of the value being assigned. The whole anonymous type is a Red Herring.
Well, (a.v+b).v is obvious, but my question rather was about:
function demo3() {
var a:{v:Int} = {v:1}; // Specific typing doesn't seem to help.
var c = a.v; // <- unresolved -- and should be
}
a have field v, and it described in anonym type. Or it's just a copy-paste of the comment?
Oh, you're right. That one should resolve. I fixed it in the comment above.
Here's the state with 1.3.1. Usings have been fixed (e.g. StringTools.rtrim() is found), and expressions inside of parenthesis now work.
package ;
using StringTools;
class TestIssue29 {
public function new() {
}
}
class Demo{
function demo(){
var lines = "--+--+--".split("+");
for(i in 0...lines.length)
if((lines[i] = lines[i].rtrim()).length > 0) { // <-- rtrim and length were unresolved -- Fixed!!
trace(lines[i]);
lines[i].rtrim();
StringTools.rtrim(lines[i]); // <--rtrim is unresolved -- Fixed!!
}
}
function demo2() {
var a = {v:1};
var b = 1;
var c = a.v; // <- unresolved
var d = (a = (a.v + b)).v; // <- unresolved -- And should remain so!! // characters 17-30 : Int should be { v : Int }
var e = (a.v = (a.v + b)).v; // <- unresolved -- And should remain so!! // characters 16-35 : Int has no field v
var f = a;
f.v = (a.v = (a.v + b)); // <- unresolved -- and should be -- both at f and internally.
}
function demo3() { // From mayakwd
var a:{v:Int} = {v:1};
var c = a.v; // <- unresolved
}
function demo4() { // From Srikanth
(new haxe.Timer(1000)).run(); // <- unresolved -- Fixed!!
var m:Array<Int> = new Array<Int>(0); // characters 42-43 : Too many arguments
(m[i]).length; // m is Array // <- unresolved -- Correct. // characters 11-12 : Unknown identifier : i
(m).length; // Works!!
}
}
Still have to fix resolving fields in anonymous structs (but that is not what this bug was primarily about).