HaxeFoundation / HaxeFoundation/haxe
Missing/Wrong code completion when using inline markup processed by macro
- Dominant language
- Haxe
- Stars
- 6.9k
- Forks
- 715
- Avg merge
- 2d 2h
- Merged PRs (30d)
- 11
Description
I have been playing with inline markup/xml feature of Haxe, but noticed a problem with code completion: no matter what the macro is returning as expr in place of the `@:markup` meta, code completion will not be affected by it. Instead it will always provide the same `@:markup` thing (which by the way only work on the first character `<`):
Code completion inside a `${}` isn't working either, even if the macro returns a matching expression (see the macro below).
I would expect that the code completion would reflect what the macro actually returns as expression, so if it returns a string literal expression like in my macro, then the code completion would reflect that string.
As a comparison, this is what I have if, instead of the inline markup, I put directly the same string literal as the one my macro would return. In that situation, everything is working as expected:
Here is the example reproducing the case with a macro that converts any inline markup to the equivalent string literal (single quoted):
**The class processed by the macro**
```haxe
class Main implements RenderMarkup {
function new() {}
var name = "John";
public static function main() {
var main = new Main();
var result = main.render();
trace(result);
}
function render() {
return
}
}
```
**The macro**
```haxe
#if macro
import haxe.macro.Context;
import haxe.macro.Expr;
import haxe.macro.ExprTools;
using StringTools;
class RenderMarkupMacro {
macro static public function build():Array {
var fields = Context.getBuildFields();
for (field in fields) {
switch field.kind {
case FVar(t, e):
if (e != null)
field.kind = FVar(t, processInlineXml(e));
case FProp(get, set, t, e):
if (e != null)
field.kind = FProp(get, set, t, processInlineXml(e));
case FFun(f):
f.expr = processInlineXml(f.expr);
}
}
return fields;
}
static function processInlineXml(e:Expr):Expr {
switch e.expr {
case EMeta(s, expr) if (s.name == ':markup'):
switch expr.expr {
case EConst(CString(s, kind)):
return {
expr: EConst(CString(s, SingleQuotes)),
pos: expr.pos
};
case _:
}
case _:
}
return ExprTools.map(e, e -> {
return processInlineXml(e);
});
}
}
#end
```
To confirm that my macro returns a valid single quoted string literal, I checked the js output, which is correct in referencing the `${name}`. Only the code completion is missing.
```js
// Generated by Haxe 4.3.6
(function ($global) { "use strict";
var Main = function() {
this.name = "John";
};
Main.main = function() {
var main = new Main();
var result = main.render();
console.log("src/Main.hx:14:",result);
};
Main.prototype = {
render: function() {
return "
}
};
var haxe_iterators_ArrayIterator = function(array) {
this.current = 0;
this.array = array;
};
haxe_iterators_ArrayIterator.prototype = {
hasNext: function() {
return this.current < this.array.length;
}
,next: function() {
return this.array[this.current++];
}
};
Main.main();
})({});
```
It would be great if code completion was working in that situation, because that's so far the biggest obstacle against building well integrated react-style/jsx-like libraries for Haxe. Everything else in Haxe is there and well designed already for that, especially taking advantage of macros to process the inline markup 🙏
Contributor guide
Assessment
This issue has not been assessed yet.