manifold-systems / manifold

Manifold is a Java compiler plugin, its features include Metaprogramming, Properties, Extension Methods, Operator Overloading, Templates, a Preprocessor, and more.
http://manifold.systems/
Apache License 2.0
2.42k stars 125 forks source link

Extension Methods do not work #593

Closed Benjamin-Bergman closed 6 months ago

Benjamin-Bergman commented 6 months ago

Describe the bug Extension methods fail too compile with a message like:

[ERROR] /mnt/c/Users/Work/Documents/YearUp/Java/Quarantine/Foo/src/main/java/com/example/Foo.java:[10,18] cannot find symbol
[ERROR]   symbol:   method qux()
[ERROR]   location: class com.example.Foo.Bar

Both usages of extension methods in the code below fail to compile.

To Reproduce Steps to reproduce the behavior: Here is my folder structure:

.
├── pom.xml
└── src
    └── main
        └── java
            └── com
                └── example
                    ├── Foo.java
                    └── extensions
                        └── com
                            └── example
                                └── Foo
                                    └── FooExt.java

Here is my pom.xml (which is exactly the example listed):

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>my-ext-app</artifactId>
    <version>0.1-SNAPSHOT</version>

    <name>My Java Extension App</name>

    <properties>
        <!-- set latest manifold version here -->
        <manifold.version>2024.1.15</manifold.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>systems.manifold</groupId>
            <artifactId>manifold-ext-rt</artifactId>
            <version>${manifold.version}</version>
        </dependency>
    </dependencies>

    <!--Add the -Xplugin:Manifold argument for the javac compiler-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                    <encoding>UTF-8</encoding>
                    <compilerArgs>
                        <!-- Configure manifold plugin-->
                        <arg>-Xplugin:Manifold</arg>
                    </compilerArgs>
                    <!-- Add the processor path for the plugin -->
                    <annotationProcessorPaths>
                        <path>
                            <groupId>systems.manifold</groupId>
                            <artifactId>manifold-ext</artifactId>
                            <version>${manifold.version}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Here is Foo.java:

package com.example;

public class Foo {
    public static void main(String[] args) {
        new Foo().baz();
        new Bar().qux();
    }

    public static class Bar {

    }
}

Here is FooExt.java:

package com.example.extensions.com.example.Foo;

import com.example.*;
import manifold.ext.rt.api.*;

@Extension
public class FooExt {
    public static void baz(@This Foo foo) {
    }

    public static class Bar {
        public static void qux(@This Foo.Bar bar) {
        }
    }
}

Expected behavior Running mvn compile should succeed without error.

Desktop (please complete the following information):

Stack trace Here is the entire output of mvn compile --debug -Dstyle.color=never: output.txt

Benjamin-Bergman commented 6 months ago

This also fails with everything related to the nested class removed (The IntelliJ plugin marks only that extension method as not existing).

As a side note, it would be nice to have a full example project using manifold-ext (perhaps to add functionality to a json schema, which happens to be my use case). I'd be happy to submit a PR to add that once this is resolved.

rsmckinney commented 6 months ago

Sorry, you cannot make class extensions on Java source files in the same module, only on compiled Java classes outside the module/project containing the extension class.

You can, however, extend types produced from type manifolds in the same module such as JSON and SQL types.

There is compiler warning about this on the offending extension class. It should probably be an error though shrug

rsmckinney commented 6 months ago

As a side note, it would be nice to have a full example project using manifold-ext (perhaps to add functionality to a json schema, which happens to be my use case). I'd be happy to submit a PR to add that once this is resolved.

Thanks!