Giter Site home page Giter Site logo

amelentev / java-oo Goto Github PK

View Code? Open in Web Editor NEW
266.0 20.0 31.0 590 KB

Java Operator Overloading

Home Page: http://amelentev.github.io/java-oo/

AspectJ 19.50% Java 80.39% Shell 0.12%
javac-plugin eclipse-plugin java intellij operator-overloading eclipse

java-oo's Introduction

Java Operator Overloading

Java-OO is a modular extension (plugin) to Java compilers and IDEs for (Scala-like) Operator Overloading support. Works with standard JavaC compiler, Netbeans IDE, Eclipse IDE, IntelliJ IDEA IDE and any build tools.

Example (see other examples at examples/ dir):

import java.math.*;
import java.util.*;
public class Test {
  public static void main(String[] args) {
    BigInteger a = BigInteger.valueOf(1), // without OO
               b = 2, // with OO

    c1 = a.negate().add(b.multiply(b)).add(b.divide(a)), // without OO
    c2 = -a + b*b + b/a; // with OO

    if (c1.compareTo(c2)<0 || c1.compareTo(c2)>0) // without OO
      System.out.println("impossible");
    if (c1<c2 || c1>c2) // with OO
      System.out.println("impossible");

    HashMap<String, String> map = new HashMap<>();
    if (!map.containsKey("qwe")) map.put("qwe", map.get("asd")); // without OO
    if (map["qwe"]==null) map["qwe"] = map["asd"]; // with OO
  }
}

Versions

JavaC/Netbeans: 0.5
JavaC8:         0.5
Eclipse:        0.5
IntelliJ IDEA:  0.7

Note plugin versions are independent. If version for X > version for Y then it doesn't mean Y is behind feature wise.

News

16 Nov 2019. IntelliJ IDEA plugin v0.7 released with support of IDEA 2019.2+.

20 May 2017. IntelliJ IDEA plugin v0.6 released with support of IDEA 2017.

14 July 2016. As a workaround Eclipse plugin works fine on Eclipse 4.4+ if you install Scala IDE plugin first.

2 Feb 2016. IntelliJ IDEA plugin v0.5 released with support of IDEA 15. Requires Java8 to run the plugin.

10 April 2015. IntelliJ IDEA plugin v0.4.1 released with support of IDEA 14.1.

27 January 2015. Eclipse-oo-plugin version 0.5 released with support of reverse binary operator overload.

2 December 2014. New feature: Reverse binary operator overload via operatorRev methods.
Plugin versions updated:
JavaC7 & JavaC8: 0.5
IntelliJ IDEA: 0.4. Support of IDEA 14

31 May 2014. Javac8 plugin version 0.1.1 released. Removed runtime depencendy on nbjavac.

24 May 2014. IntelliJ IDEA plugin v0.3.1 released. Bugfixes for IDEA 13 Ultimate and for type resolution for binary expressions with primitives.

30 April 2014. IJPLA published a paper about Java-OO.

3 Feb 2014. New JavaC8 plugin version 0.1 for JDK8 was released. It has the same features as JavaC plugin for JDK7 but doesn't work in Netbeans yet.

12 Jan 2014. JavaC plugin version 0.4 and Eclipse plugin version 0.4 released. Now operator overloading perform autoboxing/autounboxing primitive to/from wrapper types where appropriate. Fixed javac plugin bug with index-set OO.

3 Jan 2014. JavaC plugin version 0.3 released. Fixed #10 javac: binary operator adds erroneous cast on 1st operand.

8 Sep 2013. Eclipse plugin version 0.3 released. Removed copypasta from Eclipse Compiler. Plugin should be more steady agains compiler changes.

14 May 2013. IntelliJ IDEA IDE plugin v0.2.1 with IDEA Ultimate Edition support.

17 Apr 2013. IntelliJ IDEA IDE plugin v0.2.

26 Nov 2012. Version 0.2 released. New feature: Assignment operator overloading via static #valueOf method.

Installation

Just add to classpath: javac8-oo-plugin.jar for JDK8 or javac-oo-plugin.jar for JDK7.

javac -cp javac8-oo-plugin.jar <sources>

Demo at examples/compile.sh

Eclipse IDE update site

Click in menu: Help - Install New Software. Enter in Work with field:

http://amelentev.github.io/eclipse.jdt-oo-site/

Tested on Eclipse Standard 4.3.2. Should work with older versions too.
To work on 4.4+ you need to install Scala IDE plugin (or similar plugin with Equanox weaving). You can find it in Help -> Eclipse Marketplace. This is workaround until normal solution will be found. Tested on 4.4 and 4.6.

  1. Add javac-oo-plugin.jar as compile or processor library to Netbeans.
  2. Enable "Annotation Processing in Editor": Project Properties -> Build -> Compiling.

Tested on 7.2.1

  1. Install Java Operator Overloading support plugin: File -> Settings -> Plugins -> Browse repositories. Mirror: idea-oo-plugin.jar)
    For Maven projects installation is done. IDEA should setup everything according to pom.xml.
    For other project types:
  2. Add javac8-oo-plugin.jar as compile or processor library.
  3. Enable Annotation Processing: Menu File -> Settings -> Compiler -> Annotation Processing -> Enable annotation processing
  4. Make sure you use javac compiler in Settings -> Java Compiler -> Use compiler.
    Tested on IDEA 2019.2.4 Ultimate & Community editions. You can use earlier plugin versions for older IDEA releases.

Android project in IDEA 12

Add javac-oo-plugin.jar to File - Settings - Compiler - Annotation Processors - Processor path

Android Studio (IDEA 13) / Gradle

add to build.gradle:

repositories {
	maven { url 'http://amelentev.github.io/mvnrepo/' }
}
dependencies {
	compile 'java-oo:javac-oo-plugin:0.5'
}

Look at javac-oo-mvndemo/pom.xml

Details

Read the paper to learn more. Supported operators (operator to method name map):

binary:

| OPERATOR | METHOD NAME|
-------------------------
| +        | add        |
| -        | subtract   |
| *        | multiply   |
| /        | divide     |
| %        | remainder  |
| &        | and        |
| |        | or         |
| ^        | xor        |
| <<       | shiftLeft  |
| >>       | shiftRight |

If left operand has no such method then the plugin will try to use 'reverse' method <methodName>Rev on right operand. So 2*a will be transformed to a.multiplyRev(2) if a has such method.

unary:

| -        | negate     |
| ~        | not        |

comparison:

| <, <=, >, >= | compareTo	| example: `a < b` <=> `a.compareTo(b)<0`
`==` and `!=` are not overloadable because it will break things

index:

| []  | get       | `v = lst[i]` <=> `v = lst.get(i)`
| []= | set, put  | `map[s] = v` <=> `map.put(s,v)`,  `lst[i] = v` <=> `lst.set(i,v)`

assignment:

| var = expr | var = VarClass.valueOf(expr) |

if expr is not assignable to var and var is an instance of VarClass and expr has type ExprType and there are static method VarClass#valueOf(ExprType)
then var = expr is transformed to var = VarClass.valueOf(expr). example:
BigInteger a = 1 is transformed to BigInteger a = BigInteger.valueOf(1)

These methods exists in many java classes (example: BigInteger, BigDecimal) so you can use operators on them "out of the box". Or you can add these methods to your classes to use OO (see examples/Vector.java).

Subprojects / Implementation details

Publications

"Java Modular Extension for Operator Overloading", IJPLA, April 2014.

java-oo's People

Contributors

amelentev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

java-oo's Issues

JSR: Compiler Extensions

Is it possible to see if you can get the extension mechanism into the main stream? Perhaps a JSR.

This is amazing and cool.

Eclipse Plugin Bug

Strange errors are reported when a binary or unary operator is used on the same line as a valueOf.
I have the latest version of eclipse (4.3.1) and the latest version of the eclipse plugin (0.4).
Here is a class that consistently produces the error:

public class Main
{
    public static void main(String[] args)
    {
        A a1 = new A();
        A a2 = new A();
        A a3 = a1 - a2;
    }

    public static class A
    {
        public B subtract(A val)
        {
            return new B();
        }

        public static A valueOf(B val)
        {
            return new A();
        }
    }

    public static class B
    {

    }
}

Overload === for equals()

Can you overload a new operator === for equals() ?
I mean:
var1.equals(var2) -> var1 === var2
That world be great if that can be done!

SymJava and Futureye_JIT Cannot Compile in IntelliJ

Before reporting my issue, first, I want to thank the author and contributors of java-oo to make operator overloading possible in Java. Java-oo is an excellent library to me since I've been spending several years since 2010 working on the development of mathematical libraries using Java. I believe that operator overloading is a must have thing for math libraries! The two main libraries I developed are:
1). SymJava, a library for symbolic-numeric computation in Java (https://github.com/yuemingl/SymJava)
2). Futureye_JIT is a library for solving partial differential equations using FEM with Just-In-Time compilation ( https://github.com/yuemingl/Futureye_JIT)
Both of the libraries are developed under eclipse. I think the libraries are now in good shape and hope more individuals who are interested in the libraries can use them. I recently tried to use IntelliJ to compile the two libraries, but failed. I am wondering if anyone can help me figure out the problem? You may need clone the projects and import them into IntelliJ to see what happened.
By the way, I already have two paper published about the libraries. I am now currently working on a paper about the design and implementation of Futureye_JIT. If anyone interested in contribution please let me know.

Reverse binary operator overload

Use case - multiply double to Complex:

Complex a = new Complex(1.2, 2.3)
1.2*a

We can't add method multiply to double.

Solution:
add method Complex#multiplyRev(double)
This method will be used on second operand in cases where is no multiply method in left operand.
So: 1.2 * a will be transformed to a.multiplyRev(1.2)
This should work for every binary operator.

Complex type inference

This is a classic issue in C++. Example:

class X {
    // math ops
    public X multiply(BigDecimal factor) { /* impl */ }
}

And use:

X x = anotherX * 3;

Plugin does not infer that there is a conversion of "3" to a BigDecimal which matches the signature of "multiply".

Align method names with Kotlin

Could we please change the operator-to-method mapping to match that exposed by Kotlin? I think it's very important to have consistency here, because there'll be libraries designed for Kotlin that will use these method names and which won't be compatible with java-oo. Perhaps java-oo needs to be forked for this.

Kotlin's conventions: http://kotlinlang.org/docs/reference/operator-overloading.html

Unfortunately, Kotlin doesn't use "reverse" methods. It uses "extension" methods, which are static methods in utility classes. It's not possible to predict where Kotlin might put them, so I don't know if they can be supported. See http://kotlinlang.org/docs/reference/extensions.html and https://stackoverflow.com/questions/28294509/accessing-kotlin-extension-functions-from-java/36452456#36452456 I would keep supporting the Rev convention.

Netbeans 7.4+ support

Netbeans adds NBAttr, NBResolve which extends Attr, Resolve javac modules.
So we need to extend NBAttr & NBResolve. But we can't because they are in different java package and we need to override package-private methods.

The only way I see is to modify o.n.lib.nbjavac or .libs.javacimpl netbeans modules.

IDE plugin versioning - documentation

Hi,

Really a question more than an issue - that the IntelliJ plugin is 0.4.1 but the others are 0.5 ... does this mean IntelliJ is behind the others, or does it mean they use different version sequences?

A comment in the README about this would help or an FAQ.

Cheers,
Brian

Suggestion: "not" as "complement, boolean "not" overload, and possible type casting?

Not an "issue" per say, unless you count personal preference towards issues, but I figured this was the easiest place to put this.

I started messing around with this plugin in IDEA (you actually got me to use IDEA since my Eclipse version isn't yet supported) and I absolutely love it, I can finally have cleaner math-related Java code. Especially when working with game math and personal languages/features, the ability to clean up code in this way is amazing coming out of Java.

I have noticed both things I'm not fond of and things I'd like to see added. I would really like to see an overload option for the boolean not operator, since it seems one of the only ones not currently implemented (I don't know if there are more,) but in order to do that I have to also suggest changing the method overload name for the bitwise complement/not to "complement." Neither of those sounds like an issue unless you'd like to guarantee compatibility with previous versions, in which case the "not" name change may actually be a problem.

The other thing I've been wanting is a type cast overload, which I'm pretty sure could be implemented identical to a standard assignment overload by searching for the same valueOf(x) method. With a type cast overload new local variables wouldn't need to always be created when using the assignment overload, but could just be used in expressions.

custom operators

You are a genius! Thanks for your wonderful job!
What about defining custom operators? maybe not as flexible as Scala, when you can have the pope operator <+|:-) if you want. But I was thinking about the eq operator, so
a eq b means Object.equals(a, b). It allows you to skip null checks, keep the == for references, and it is nicer on the eye.

Also, one small thing, the example code is somehow wrong, map.get("qwe")==null is not the same as map.containsKey("qwe") unless map is null free.

(I was also going to ask about null handling with ?, but pretty much everything I want to ask is already written in 'ideas' file)

Again, incredible work!

Error compiling

With IntelliJ Ultimate 13.1.4:

Error:java: java.lang.IllegalArgumentException: Can not set com.sun.tools.javac.api.MultiTaskListener field com.sun.tools.javac.main.JavaCompiler.taskListener to javaoo.javac.OOProcessor$WaitAnalyzeTaskListener

index-set OO doesn't works with implicit type conversion

javac on:

import java.util.*;
import java.math.*;
class bug {
        public static void main(String[] args) {
                List<BigInteger> a = new ArrayList<>();
                a.add(BigInteger.ONE);
                a[0] = BigInteger.TEN;
                a[0] = 5; // BigInteger.valueOf(5)
                System.out.println(a[0]);
        }
}

outputs:

bug.java:8: error: array required, but List<BigInteger> found
        a[0] = 5; // BigInteger.valueOf(5)

No Such Field Exception on Plugin Install in Intellij IDEA Ultimate Edition 12.1.3

I love the plugin and this is a godsend for those of us stuck using Java at times. However, having some troubles with getting it working on intellij.

Steps to reproduce:

  1. Install plugin within the IDE

  2. Note the error (I added the jar to my library path after to make sure it was not related to that, but it persisted after restarting)

Other info that might be useful (let me know if you need anything else):

  1. Using Windows 7 x64

  2. Oracle JDK 7 with javac enabled in intellij + annotations.

  3. Cleared Intellij Caches + Indices to no avail.

It also seems to kill my syntax coloring after applying the plugin (and inspections):

Before installing:

before

After installing:

after

  1. StackTrace:

myConstructor: myConstructor
java.lang.NoSuchFieldException: myConstructor
at java.lang.Class.getDeclaredField(Class.java:1899)
at javaoo.idea.Util.set(Util.java:38)
at javaoo.idea.Util.setJavaElementConstructor(Util.java:60)
at javaoo.idea.OOComponent.initComponent(OOComponent.java:52)
at com.intellij.openapi.components.impl.ComponentManagerImpl.b(ComponentManagerImpl.java:217)
at com.intellij.openapi.components.impl.ComponentManagerImpl.access$1300(ComponentManagerImpl.java:55)
at com.intellij.openapi.components.impl.ComponentManagerImpl$ComponentConfigComponentAdapter$1.getComponentInstance(ComponentManagerImpl.java:587)
at com.intellij.openapi.components.impl.ComponentManagerImpl$ComponentConfigComponentAdapter.getComponentInstance(ComponentManagerImpl.java:630)
at com.intellij.util.pico.DefaultPicoContainer.getLocalInstance(DefaultPicoContainer.java:242)
at com.intellij.util.pico.DefaultPicoContainer.getInstance(DefaultPicoContainer.java:229)
at com.intellij.util.pico.DefaultPicoContainer.getComponentInstance(DefaultPicoContainer.java:211)
at org.picocontainer.alternatives.AbstractDelegatingMutablePicoContainer.getComponentInstance(AbstractDelegatingMutablePicoContainer.java:75)
at com.intellij.openapi.components.impl.ComponentManagerImpl.createComponent(ComponentManagerImpl.java:127)
at com.intellij.openapi.components.impl.ComponentManagerImpl.a(ComponentManagerImpl.java:108)
at com.intellij.openapi.components.impl.ComponentManagerImpl.initComponents(ComponentManagerImpl.java:346)
at com.intellij.openapi.components.impl.ComponentManagerImpl.init(ComponentManagerImpl.java:86)
at com.intellij.openapi.project.impl.ProjectImpl.init(ProjectImpl.java:309)
at com.intellij.openapi.project.impl.ProjectManagerImpl.a(ProjectManagerImpl.java:278)
at com.intellij.openapi.project.impl.ProjectManagerImpl.access$300(ProjectManagerImpl.java:82)
at com.intellij.openapi.project.impl.ProjectManagerImpl$9.compute(ProjectManagerImpl.java:558)
at com.intellij.openapi.project.impl.ProjectManagerImpl$9.compute(ProjectManagerImpl.java:554)
at com.intellij.openapi.progress.impl.ProgressManagerImpl$4.run(ProgressManagerImpl.java:269)
at com.intellij.openapi.progress.impl.ProgressManagerImpl$TaskRunnable.run(ProgressManagerImpl.java:495)
at com.intellij.openapi.progress.impl.ProgressManagerImpl$6.run(ProgressManagerImpl.java:304)
at com.intellij.openapi.progress.impl.ProgressManagerImpl$2.run(ProgressManagerImpl.java:185)
at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:226)
at com.intellij.openapi.progress.impl.ProgressManagerImpl.runProcess(ProgressManagerImpl.java:175)
at com.intellij.openapi.application.impl.ApplicationImpl$10$1.run(ApplicationImpl.java:681)
at com.intellij.openapi.application.impl.ApplicationImpl$8.run(ApplicationImpl.java:454)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
at com.intellij.openapi.application.impl.ApplicationImpl$1$1.run(ApplicationImpl.java:152)

Add Intellij Support for Android

It's possible (works with using Ant or Maven fine and subsequently installs and runs fine when testing with your plugin), but compiling directly in Intellij for an Android project triggers the syntax inspection checks so it throws a bunch of "incompatible types/array required errors." I haven't delved far enough into debugging Intellij to see where it gets triggered yet, but I'm guessing your plugin can work around it somehow (since the same errors get thrown out until you add the jar to the project). Not sure if it's related to how it reads the jar or what, but yeah, need to debug some more.

Curious to see what you think though as you have more experience with building plugins than I do.

Eclipse watch and display view support

Right now Java-OO doesn't work in Eclipse watches and display view.
Seems like Eclipse uses some interpreter to evaluate expressions without byte code generation.
(org.eclipse.jdt.internal.debug.eval.ast.engine.Interpreter)

Compatibility issues with Intellij IDEA 2017+

Starting with IDEA 2017, the IDE plugin no longer shows the Operator overloading as correct syntax (IDE shows errors). However the code, with no changes, compiles and runs just fine. I have noticed this behavior from the first 2017 EAP to the current version.

Avoid instantiation with assignment operator

Hi,

Let me first say this is an awesome project!

Second, I'd like to know if it could be possible to change the assignment operator behaviour to avoid a new instantiation whenever the object already exists, for example:

Vec2 a = new Vec2()
a = b + c * 2;

here the assignment operator may point a set method instead of valueOf

java-oo does not work for class whose superclass is parametrized by generic type

public abstract class Abstract {
    static class Base<T> {
        public T add(T a) {
	    return a;
	}
    }
    
    static class Ext extends Base<Integer> {
    }

    public static boolean test() {
        Integer a = new Ext().add(new Integer(1));  // this can compile
        Integer b = new Ext() + new Integer(1);   // this can not compile!
        return true;
    }
}
Running JCPOOTest
Note: Injecting OO to javac8
../tests/Abstract.java:14: error: incompatible types: T cannot be converted to Integer
                Integer b = new Ext() + new Integer(1);  // this can not compile!
                                      ^
  where T is a type-variable:
    T extends Object declared in class Base
1 error

Plugin disables ability show error markers in editor

This Plugin disables ability to show error markers in editor (curves and marker on right scroll bar).
Errors still persist on messages tool window.

For example, following code does not show error markers in editor:
System.out.print123ln("abc");

IDEA 15.0.2
Windows10x64

[Bug] Chaining map accessors

In IntelliJ IDEA 2017.1.3 with up do date plugin and library javac8, using the code:

Map<Integer, Map<Integer, Integer>> map = new HashMap<>();
map[0] = new HashMap<>();
map[0][0] = 4;
return map[0][0];

Will yeld an "Internal Java Compiler Error"

NoSuchFieldException using errorprone

I'm using errorprone gradle plugin together with java-oo.
The gradle.build file is like this:

plugins {
    id "java"
    id "net.ltgt.errorprone" version "0.0.11"
}
repositories {
    maven { url 'http://amelentev.github.io/mvnrepo/' }
    mavenCentral()
}
dependencies {
    // error_prone_core:2.0.1 uses com.google.errorprone:javac:1.8.0-u20
    // https://github.com/google/error-prone-javac/tree/1.8.0-u20
    errorprone 'com.google.errorprone:error_prone_core:2.0.1'
    compile 'java-oo:javac8-oo-plugin:0.5'
}

When I build the project, it fails like this:

> Task :compileJava
Note: Injecting OO to javac8


An annotation processor threw an uncaught exception.
Consult the following stack trace for details.
java.lang.NoSuchFieldException: taskListener
        at java.lang.Class.getDeclaredField(Class.java:2070)
        at javaoo.javac8.OOProcessor.get(OOProcessor.java:130)
        at javaoo.javac8.OOProcessor.init(OOProcessor.java:48)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment$ProcessorState.<init>(JavacProcessingEnvironment.java:500)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment$DiscoveredProcessors$ProcessorStateIterator.next(JavacProcessingEnvironment.java:597)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:690)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1800(JavacProcessingEnvironment.java:91)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1035)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1176)
        at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1170)
        at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:855)
        at com.sun.tools.javac.main.Main.compile(Main.java:523)
        at com.sun.tools.javac.main.Main.compile(Main.java:381)
        at com.sun.tools.javac.main.Main.compile(Main.java:370)
        at com.google.errorprone.ErrorProneCompiler.run(ErrorProneCompiler.java:220)
        at com.google.errorprone.ErrorProneCompiler.run(ErrorProneCompiler.java:158)
        at com.google.errorprone.ErrorProneCompiler.compile(ErrorProneCompiler.java:87)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at net.ltgt.gradle.errorprone.ErrorProneCompiler.execute(ErrorProneCompiler.java:63)
        at net.ltgt.gradle.errorprone.ErrorProneCompiler.execute(ErrorProneCompiler.java:24)
        at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.delegateAndHandleErrors(NormalizingJavaCompiler.java:99)
        at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.execute(NormalizingJavaCompiler.java:52)
        at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.execute(NormalizingJavaCompiler.java:37)
        at org.gradle.api.internal.tasks.compile.CleaningJavaCompilerSupport.execute(CleaningJavaCompilerSupport.java:35)
        at org.gradle.api.internal.tasks.compile.CleaningJavaCompilerSupport.execute(CleaningJavaCompilerSupport.java:25)
        at org.gradle.api.tasks.compile.JavaCompile.performCompilation(JavaCompile.java:198)
        at org.gradle.api.tasks.compile.JavaCompile.compile(JavaCompile.java:183)
        at org.gradle.api.tasks.compile.JavaCompile.compile(JavaCompile.java:120)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73)
        at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$IncrementalTaskAction.doExecute(DefaultTaskClassInfoStore.java:168)
        at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.execute(DefaultTaskClassInfoStore.java:134)
        at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.execute(DefaultTaskClassInfoStore.java:121)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$1.run(ExecuteActionsTaskExecuter.java:122)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:317)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:309)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:185)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:95)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:111)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:92)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:70)
        at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:64)
        at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:54)
        at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
        at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:88)
        at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:52)
        at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
        at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:54)
        at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
        at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:34)
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker$1.run(DefaultTaskGraphExecuter.java:242)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:317)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:309)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:185)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:95)
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:235)
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:224)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.processTask(DefaultTaskPlanExecutor.java:121)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.access$200(DefaultTaskPlanExecutor.java:77)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:102)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:96)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.execute(DefaultTaskExecutionPlan.java:612)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.executeWithTask(DefaultTaskExecutionPlan.java:567)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.run(DefaultTaskPlanExecutor.java:96)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
        at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:46)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
        at java.lang.Thread.run(Thread.java:745)


FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':compileJava'.
> Compilation failed with exit code 3; see the compiler error output for details.


Eclipse-oo-plugin not working in Eclipse 4.4+

I'll use Eclipse Luna and installed the Java-OO plugin. I'll use Java 7 and Java 8. The Editor shows always errors if there is an operator used.

b = 2, // with OO shows Type mismatch: Cannot convert from int to BigInteger.

c2 = -a + b*b + b/a; // with OO shows Multiple markers at this line
- The operator / is undefined for the argument type(s) java.math.BigInteger,
java.math.BigInteger
- The operator * is undefined for the argument type(s) java.math.BigInteger,
java.math.BigInteger
- The operator - is undefined for the argument type(s) BigInteger

Problems with autoboxing

class Boxing {
        static class Vec {
                double d[];
                Vec(double... d) { this.d = d; }
                double get(int i) { return d[i]; }
                double set(int i, double a) { return d[i] = a; }
        }
        public static void main(String[] args) {
                Vec v = new Vec(1.,2.,3.);
                Double d1 = Double.valueOf(4.);
                Double d2 = (v[2] = d1);
        }
}

javac result:

Boxing.java:8: error: Internal error: stack sim error on public static void main(String[] args) {

eclipse:

java.lang.VerifyError: Bad type on operand stack ...

Intellij 15 plugin: no inspections

Hi,

A very nice addition to java, I love it. But in Intellij 15.0.2 a lot of inspection don't execute when the plugin is enabled.

Thank you

Release on Maven Central

Java-OO should be available on Maven Central in a similar way to lombok. Just adding the main dependency will work transparently.

Custom method names for overloaded operators

I never really made any Eclipse plugins and such, but could it be possible to use annotations to specify which method should be used as which overload? This way we could both name methods like they should be really named and still use Java-OO.

Bug when using OO out of a map

Thank you for making this brilliant plugin.

I've noticed a bug. Try the following code -- it claims to compile, but breaks class loading at runtime. This is using Java 7 on Ubuntu Linux.

Map<String, BigInteger> map = new HashMap<>();
map.put("a",BigInteger.valueOf(2));
BigInteger a2 = map["a"] * map["a"];

Note that if you add casts, e.g. BigInteger a2 = ((BigInteger)map["a"]) * ((BigInteger)map["a"]); it works fine.

JDK8 support

jdk8 developer preview (b121) javac:

java.lang.IllegalArgumentException: Can not set com.sun.tools.javac.api.MultiTaskListener field com.sun.tools.javac.main.JavaCompiler.taskListener to javaoo.javac.OOProcessor$WaitAnalyzeTaskListener

netbeans7.4 (probably due jdk8):

Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - Erroneous tree type: <any>

IntelliJ-plugin: Wrong result-type of binary expressions for float, double and long in the IDE.

Hi!

There is a problem with the IntelliJ-plugin for the primitive types: float, double and long. The following test class compiles fine using javac with the java-oo jar-file on the classpath, but the IntelliJ plugin marks some of the lines as errors.

I've made a test to illustrate the problem. In the test class below, the expression "vector * number" is being given the type "float", when "number" is a float, instead of being given the type "Vector".

The same happens for doubles and longs.
But it works perfectly for int, byte, char, short, boolean and objects.

import java.util.Date;

public class BugReportMain {

    // Test multiply by scalar for float, int, double, etc. Some work, some don't.
    public static void main(String[] args) {

        Vector a = new Vector(1, 2);

        // Multiplying by a float becomes marked as an error in intellij (the type of "a * 2f" seems to be "float" according to the plugin)
        Vector b = a * 2.3f;  // <- The error is: "Incompatible types. Required: Vector, Found: float"

        // This works! (no error) It is exactly the same as above, just with "int" instead of "float"
        Vector c = a * 2;

        // double and long does not seem to work either
        Vector d = a * 2.5;
        Vector e = a * 3L;

        // short, byte, char and boolean works
        Vector f = a * ((short)4);
        Vector g = a * ((byte)5);
        Vector h = a * ((char)6);
        Vector i = a * true;

        // Objects works
        Vector j = a * new Date(1234567890);

        // String works
        Vector k = a * "hello";

        // Works from javac - this prints out the expected values:
        System.out.println(a+"\n"+b+"\n"+c+"\n"+d+"\n"+e+"\n"+f+"\n"+g+"\n"+h+"\n"+i+"\n"+j+"\n"+k);
    }

    // Small test (This is just for testing purposes - many methods do not make sense :D)
    public static class Vector {

        private final float x;
        private final float y;

        public Vector(float x, float y) {
            this.x = x;
            this.y = y;
        }

        public Vector add(Vector other) {
            return new Vector(x + other.x, y + other.y);
        }

        public Vector subtract(Vector other) {
            return new Vector(x - other.x, y - other.y);
        }

        public Vector multiply(float s) {
            return new Vector(x * s, y * s);
        }

        public Vector multiply(int s) {
            return new Vector(x * s, y * s);
        }

        public Vector multiply(double s) {
            return new Vector(x * (float)s, y * (float)s);
        }

        public Vector multiply(byte s) {
            return new Vector(x * s, y * s);
        }

        public Vector multiply(short s) {
            return new Vector(x * s, y * s);
        }

        public Vector multiply(long s) {
            return new Vector(x * s, y * s);
        }

        public Vector multiply(char s) {
            return new Vector(x * s, y * s);
        }

        public Vector multiply(boolean s) {
            int ss = s ? 1 : 2;
            return new Vector(x * ss, y * ss);
        }

        public Vector multiply(Date r) {
            int s = 123;
            return new Vector(x * s, y * s);
        }

        public Vector multiply(String s) {
            int ss = s.length();
            return new Vector(x * ss, y * ss);
        }

        public Vector divide(float s) {
            return new Vector(x / s, y / s);
        }

        public String toString() {return "["+x+","+y+"]";}
    }
}

This is how it looks like in IntelliJ (the main method only):


java-oo1


This is what intelliJ says when you mouse-over one of the errors:


java-oo2


Sorry for being a pain. :) Hope it is an easy fix. ;)

Thank you once again for the awesome plugin!

operators are not found if the parameters are not exactly the same as the arguments

Consider the following scenario:

public class Test
{
    public void foo()
    {
        A a = new A();
        B b = new B();
        
        Base c = a & b; // << "Operator '&' cannot be applied to 'A', 'B'"
        c = a.and(b);
        c = a + b; // << "Operator '+' cannot be applied to 'A', 'B'"
        c = a.add(b);
    }
}

class A implements Base { }

class B implements Base { }

interface Base
{
    default Base and(Base other) { return this;  }
    default Base add(Base other) { return this; }
}

As you might imagine, the functional syntax works fine as "a" implements Base so it has the and/add methods and "b" implements Base so it is a valid parameter.
But the operator syntax cannot recognize them as valid operators.

If I change the parameters from Base to B, it works fine.
Or if I change the variable "B b" to "Base b", it also works fine.
The same also happens if Base is a class.

However, I have 16 classes that all have to be able to use the "and" operator on each other.
And that would result in 16*15 methods with all duplicate code that could very well be in one interface.

I am using IntelliJ Ultimate version 2017.2 with the Java-oo plugin 0.6.
(Javac compiler)

This plugin ruin my eclipse

After installation half of the eclipse features can not start. One of this features is " install new software", "check for updates", and "installation details". So i can not even remove this ๐Ÿ’ฉ!

Cannot compile in IntelliJ IDEA Ultimate 2016.3.3

I am using the javac compiler, annotation processing is enabled, and I have installed the plugin, and also added the library. However, I get this error:

Error:java: java.lang.IllegalArgumentException: Can not set com.sun.tools.javac.api.MultiTaskListener field com.sun.tools.javac.main.JavaCompiler.taskListener to javaoo.javac.OOProcessor$WaitAnalyzeTaskListener

Assignment operator overloading via constructors

Assignment operator overloading now works only via static valueOf method.
In cases we can't add valueOf method to a class we may use constructors:
BigDecimal a = "123"
will be transformed to
BigDecimal a = new BigDecimal("123")
(there is no valueOf(String) method in j.m.BigDecimal)
But this will add more ambiguity.

Expressions fail, assignment works

Contrast:

Money aDollar = Money.parse("USD1");
BigDecimal eight = new BigDecimal("8");
Money m = aDollar / eight;
m.getAmount();

With non-compiling:

(aDollar / eight).getAmount();

javac: binary operator adds erroneous cast on 1st operand.

For example when multiplying Vector to Matrix:

class VecMat {
    static class Vec {
        Vec multiply(Mat A) { return this; }
    }
    static class Mat {}
    public static void main(String[] s) {
        Vec a = new Vec();
        Mat A = new Mat();
        System.out.println(a*A);
    }
}

a*A transforms to ((Mat)a).multiply(A)
which causes ClassCastException at runtime.

Elvis ?: [enhacement]

Thanks again for your extraordinary work.
You said that adding new operator is difficult because of no extension points at that stage. What about the elvis ?: operator, better known as null coalescing operator ? you know, instead of

String firstName = user == null ? null : user.getFirstName()

i'd like to write

String firstName = user?:getFirstName()

I don't know if that counts as a new operator, since both chars already have a meaning

Bug in valueOf

I tried this simple test case:

package symjava.test;
public class TestValueOf {
    public static class Car {
        public int id;
        public Car(int id) {
            this.id = id;
        }
        public Car add(Car c) {
            return new Car(this.id+c.id);
        }
    }
    public static class Jeep extends Car {
        public Jeep(int id) {
            super(id);
        }
        public static Jeep valueOf(Car c) {
            return new Jeep(c.id);
        }
    }
    public static void main(String[] args) {
        Car c1 = new Car(1);
        Car c2 = new Car(10);
        Car c12 = c1 + c2;
        //Jeep j = c12; //works
        //Jeep j = Jeep.valueOf(c1 + c2); //works
        Jeep j = c1 + c2; //NOT work!!!
        System.out.println(j.id);
    }
}

An exception is thrown out:

Exception in thread "main" java.lang.VerifyError: Operand stack underflow
Exception Details:
Location:
symjava/test/TestValueOf.main([Ljava/lang/String;)V @25: invokestatic
Reason:
Attempt to pop empty stack.
Current Frame:
bci: @25
flags: { }
locals: { '[Ljava/lang/String;', 'symjava/test/TestValueOf$Car', 'symjava/test/TestValueOf$Car', 'symjava/test/TestValueOf$Car' }
stack: { }
Bytecode:
0000000: bb00 1059 04b7 0012 4cbb 0010 5910 0ab7
0000010: 0012 4d2b 2cb6 0015 4eb8 0019 3a04 b200
0000020: 1f19 04b4 0025 b600 29b1

at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2615)
at java.lang.Class.getMethod0(Class.java:2856)
at java.lang.Class.getMethod(Class.java:1668)
at sun.launcher.LauncherHelper.getMainMethod(LauncherHelper.java:494)
at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:486)

ClassCastException from IntelliJ-plugin in IntelliJ IDEA 13.1.2 Ultimate

Hi!

I just stumbled upon your extremely awesome project. Very well done! Didn't even know this was possible!

I think I've found a bug in the IntelliJ plugin, however. The plugin throws the following exception:

java.lang.Integer cannot be cast to java.util.List: java.lang.Integer cannot be cast to java.util.List
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.util.List
    at javaoo.idea.OOHighlightVisitorImpl.removeLastHighlight(OOHighlightVisitorImpl.java:132)
    at javaoo.idea.OOHighlightVisitorImpl.visitPolyadicExpression(OOHighlightVisitorImpl.java:60)
    at com.intellij.psi.JavaElementVisitor.visitBinaryExpression(JavaElementVisitor.java:44)
    at com.intellij.psi.impl.source.tree.java.PsiBinaryExpressionImpl.accept(PsiBinaryExpressionImpl.java:139)
    at com.intellij.codeInsight.daemon.impl.analysis.HighlightVisitorImpl.visit(HighlightVisitorImpl.java:136)
    at com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass$5.run(GeneralHighlightingPass.java:312)
    at com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.a(GeneralHighlightingPass.java:397)
    at com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.access$300(GeneralHighlightingPass.java:64)
    at com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass$6.run(GeneralHighlightingPass.java:403)
    at com.intellij.codeInsight.daemon.impl.DefaultHighlightVisitor.analyze(DefaultHighlightVisitor.java:87)
    at com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.a(GeneralHighlightingPass.java:400)
    at com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.access$300(GeneralHighlightingPass.java:64)
    at com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass$6.run(GeneralHighlightingPass.java:403)
    at com.intellij.codeInsight.daemon.impl.RefCountHolder.analyze(RefCountHolder.java:318)
    at com.intellij.codeInsight.daemon.impl.analysis.HighlightVisitorImpl.analyze(HighlightVisitorImpl.java:173)
    at javaoo.idea.OOHighlightVisitorImpl.analyze(OOHighlightVisitorImpl.java:41)
    at com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.a(GeneralHighlightingPass.java:400)
    at com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.a(GeneralHighlightingPass.java:388)
    at com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.collectInformationWithProgress(GeneralHighlightingPass.java:230)
    at com.intellij.codeInsight.daemon.impl.ProgressableTextEditorHighlightingPass.doCollectInformation(ProgressableTextEditorHighlightingPass.java:86)
    at com.intellij.codeHighlighting.TextEditorHighlightingPass.collectInformation(TextEditorHighlightingPass.java:61)
    at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass$1$1.run(PassExecutorService.java:380)
    at com.intellij.openapi.application.impl.ApplicationImpl.tryRunReadAction(ApplicationImpl.java:1154)
    at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass$1.run(PassExecutorService.java:371)
    at com.intellij.openapi.progress.ProgressManager.executeProcessUnderProgress(ProgressManager.java:209)
    at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:212)
    at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.a(PassExecutorService.java:368)
    at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.run(PassExecutorService.java:344)
    at com.intellij.concurrency.JobLauncherImpl$VoidForkJoinTask.exec(JobLauncherImpl.java:193)
    at jsr166e.ForkJoinTask.doExec(ForkJoinTask.java:260)
    at jsr166e.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:858)
    at jsr166e.ForkJoinPool.scan(ForkJoinPool.java:1687)
    at jsr166e.ForkJoinPool.runWorker(ForkJoinPool.java:1642)
    at jsr166e.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:109)

This exception is from the event log of the IDE. It happens periodically while the IDE is running (seems to be approximately each time you navigate to a java file which uses operator overloading or when you edit such file). (And the plugin does not seem to work - all usages of overloaded operators are still underlined with red error lines).

I'm using IntelliJ IDEA 13.1.2 Ultimate Edition, and the javac of java 8. I'm on windows. If you need more information feel free to ask.

I think i installed the plugin and sat up the project correctly (followed these instructions http://amelentev.github.io/java-oo/), but who knows - this is the first time i'm trying it out.

Thanks again for having created this great project!

Problems compiling in Intellij IDEA 2016.1.3 Ult

Hi, i have just started using Java-OO and so far nothing is working. Everywhere i try to use any of the operators, the compiler throws errors while the IDE says that everything is fine. I have tried using the idea plugin as well as the javac plugin and it hasn't worked. I'm not sure what files to upload so if you need any, i can upload them. Hope i can get this working.

IntelliJ plugin 0.4.1 does not support Java 8u51

I love the idea of what the plugin could do (Great paper!). Unfortunately I'm unable to use it:

screen shot 2015-07-26 at 3 14 41 pm

If you know of any way to resolve this or what Java 8 version to use instead I'd like to know. Thanks

[request] Equality operator override

This is a great project, thank you for making this.

The only thing it's lacking is overloading of == operator. Comparing Strings can be a pain in the ass without it.

I know this might break things, as == should compare references and everyone is used to that, but maybe some workaround could be made.

We don't have to override == for every class and object. Could it be enabled only for some classes that we explicitly choose? (it would have it's limitations, but it's better than nothing)

Or maybe is there a possibility to add a new operator? Like ===, which would convert a===b into something like (a == null ? b==null : a.equals(b))

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.