Skip to content
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

Java fixes #459

Merged
merged 14 commits into from
Jan 2, 2020
Merged

Java fixes #459

merged 14 commits into from
Jan 2, 2020

Conversation

lukemaurer
Copy link
Collaborator

This is a pile of bug fixes coming from getting a sizable real-world Dafny project to compile to Java. (Also there are places where I discovered a bug in another backend when I added a test, and fixing the bug was easier than adapting the test.)

Luke Maurer added 12 commits December 12, 2019 13:28
There was a problem if a Dafny module happened to be called Random.  Now,
there's still a problem if a Dafny module is called BigInteger, Array,
ArrayList, Arrays, or Function, but at least the issue is limited to those.
Now the user is free to have modules with such illustrious names as Array,
Arrays, ArrayList, Function, or BigInteger.
In Java, ill-typed code was generated for the special case of |s| as int8 (or
any native type) when s is a sequence, map, set, or multiset.  Go had a wrong
type in the runtime library, leading to a similar issue.

Tests included.
The previous implementation of generics for Java assumed that each type
parameter corresponds to a field, whose name is the same but lowercase, and
that either all type parameters need to be reified as type descriptors or none
do.
I was getting weird behavior (possibly a Mono bug) with characters at the end
being copied twice.  Fortunately, this is the right way anyway.
If an extern class includes Dafny code, the generated code is now put into an abstract base class, whose name is prefixed with `_ExternBase_`, so that the user-provided class can extend it.

FIXME: Currently there is nothing to detect whether a class has *only* Dafny
methods.  Which means that any pure-Dafny module with an `{:extern}`
declaration (even just to give it an external name) requires the user to
provide a `__default` class (extending `_ExternBase___default`).

FIXME: The included tests break Go and JavaScript, which don't correctly
implement extern constructors.
It's useful to declare a module as {:extern} even if it has no extern members,
just to give it an externally-visible name.  Unfortunately, this causes its
default class to be considered (by Compiler.Compile()) to be extern as well,
and for Java this means forcing the user to provide an implementation of the
__default class that does nothing but extend _ExternBase___default.  This patch
makes sure that at least one member carries a zero- or one-argument {:extern}
before considering a class to be extern.

Why not a two-argument {:extern}?

    module {:extern "Library"} Library {
      static method Method() { ... }
      static method {:extern "Library.Class", "ExternMethod"} ExternMethod()
    }

Here the user has specified that the method Method lives not in
Library.__default but in Library.Class (presumably because __default looks
weird).  Since Library.__default has no methods that need to be filled in
by the user, it would be silly to force them to write

    package Library
    public class __default extends _ExternBase___default {
    }

Note that there is still a corner case:

    module {:extern "Library"} Library {
      class {:extern "Class"} Class {
        static method Method() { ... }
	static method {:extern "Library.Class.InnerClass", "ExternMethod"} ExternMethod()
      }
    }

Now we *do* need to generate _ExternBase_Class so that the user can supply
Library.Class so that they can define Library.Class.InnerClass.  It's not clear
this will ever come up, though (whereas the first example comes from the wild),
and in any case the workaround is just to define a dummy extern method.
Extern constructors are currently broken on Go and JavaScript, so I'm moving
that functionality from the tests in Extern.dfy and moving it to the new
ExternCtors.dfy, which only has RUN lines for C# and Java.  I've included the
extern code that *should* make the tests work (but currently doesn't).
@robin-aws
Copy link
Member

AWS CodeBuild CI Report

  • CodeBuild project: Dafny
  • Commit ID: b505d02
  • Result: FAILED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

Comment on lines 621 to 660
else if (cl is TupleTypeDecl tupleDecl)
{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move L622 curly brace to end of L621.

Comment on lines 624 to 663
}
else if (cl.Module.CompileName == ModuleName || cl.Module.IsDefaultModule) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move L625 to end of 624.

@robin-aws
Copy link
Member

AWS CodeBuild CI Report

  • CodeBuild project: Dafny
  • Commit ID: 0ee2500
  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@robin-aws
Copy link
Member

AWS CodeBuild CI Report

  • CodeBuild project: Dafny
  • Commit ID: 4ea261d
  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

Source/Dafny/Compiler.cs Outdated Show resolved Hide resolved
Effectively reverts 42466b5, though I kept the change to the test case (and
adjusted the JavaScript extern for the test so that it still works).

See issue dafny-lang#469 for a better solution.
@robin-aws
Copy link
Member

AWS CodeBuild CI Report

  • CodeBuild project: Dafny
  • Commit ID: 0dcf116
  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@RustanLeino RustanLeino merged commit f18cf16 into dafny-lang:master Jan 2, 2020
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.

None yet

3 participants