Skip to content

Conversation

@golem131
Copy link

@golem131 golem131 commented Jul 8, 2016

  • Support JEP-223
  • Tests update

@golem131
Copy link
Author

golem131 commented Jul 8, 2016

I have signed the Scala CLA, but check not changed (

@lrytz
Copy link
Member

lrytz commented Jul 8, 2016

/synch

@som-snytt
Copy link
Contributor

That's a lot of infrastructure just to compare a number. Also, it leaks details.

Last time, @soc objected to regex, with the idea that this check should be absolutely minimal (and not require dependencies).

I'd suggest keeping the current code and just strip the optional "1." prefix, perhaps complaining if the suffix is not in "0-8".



object JavaSpecVersionBefore9 {
val pattern = "1.([5-8])"r
Copy link
Contributor

Choose a reason for hiding this comment

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

postfix is warnable.

@Ichoran
Copy link
Contributor

Ichoran commented Jul 8, 2016

Can't this whole thing just be

def javaVersion(s: String) = s.split("\\.")(if (s.startsWith("1.")) 1 else 0).toInt

There admittedly isn't much error checking here, but do we need any more logic than that?

@som-snytt
Copy link
Contributor

som-snytt commented Jul 8, 2016

I was going to say s.stripPrefix("1.") if no checking. But, yeah. I think split is the regex one, right? I remember paulp said that on the old PR.

@Ichoran
Copy link
Contributor

Ichoran commented Jul 8, 2016

Are we playing the no-regex but yes-StringOps-extensions game? Okay.

def javaVersion(s: String) = s.stripPrefix("1.").takeWhile(_ != '.').toInt

Can use (if (s startsWith "1.") s substring 2 else s) in place of stripPrefix if you want to stay with Java methods only. (Why are we playing this game again?)

@som-snytt
Copy link
Contributor

I noticed a second ago that in fact, last time, we said no extensions either, so, jinx.

I think @soc plays with other platforms where he has to boot in 16KB of ram.

@golem131
Copy link
Author

golem131 commented Jul 9, 2016

@Ichoran the problem of your recommended decision is not in Java System API, but in user input.
For example, what would happen in your version, when programer send to minimal version "10.1" or "11.1" or ".1" ?

@Ichoran
Copy link
Contributor

Ichoran commented Jul 9, 2016

@golem131 - 10.1 returns 10. 11.1 returns 11. That's as desired, no? .1 throws an exception. It's a NumberFormatException instead of one that explains what you did wrong, hence my comment about "not much error checking". If someone entered 1.9 it would give 9, but I'm not sure that's a bug instead of a feature. What would they mean other than Java 9 (unless it's just a typo, in which case 1.7 typoed as 1.8 is just as bad but can't be caught).

@golem131
Copy link
Author

golem131 commented Jul 9, 2016

@Ichoran - Ok, ok. So, what decision? We try to create fastest version, simplest version, correct version (more secure checks, more custom exceptions etc.), or we say, that "version string" is not just sequence of numbers, and may be more complex ("9-ea+73" or "9.1.2+62" for example)?

Forgot to say, that we have sbt-nsa sbt plugin (https://github.com/mentat-labs/sbt-nsa) with type safe versions and compiler options. Do you think this plugin have wrong basic idea?

@Ichoran
Copy link
Contributor

Ichoran commented Jul 9, 2016

For libraries that want to extract all the information available in a version string you have different requirements than a routine that merely needs to tell "is this 9 or is this 8".

Realistically, it should handle all the examples in http://openjdk.java.net/jeps/223 which means it can't stop on . alone, but making a decent effort to get the major version number should be enough.

For instance, getting the major version number with this code would, I think, be enough, though it could be rewritten with while loops and such if we wanted to make it easier for Proguard and the like to chop out as much as possible:

// Java version string old format is 1.x.stuff
// Java version string new format is x[.-+u]stuff
// This handles both (and admits mixtures of the two)
def javaVersion(s: String): Int =
  try { s.stripPrefix("1.").takeWhile(c => !(".-+u" contains c.toString)).toInt }
  catch { case nfe: NumberFormatException => 
    throw new NumberFormatException("Could not locate major Java version number in " + s)
  }

Then all the rest of the logic can be done with just an Int.

@golem131
Copy link
Author

golem131 commented Jul 9, 2016

@Ichoran ok, no problem, i'll fix my PR after weekend.

@Ichoran
Copy link
Contributor

Ichoran commented Jul 9, 2016

For reference, a while loop version would look something like this:

def javaVersion(s: String): Int =
  try {
    val i = if (s startsWith "1.") 2 else 0
    var j = i
    while (j < s.length && !(".-+u" contains s.substring(j, j+1))) j += 1
    s.substring(i, j).toInt
  }
  catch { case nfe: NumberFormatException =>
    throw new NumberFormatException("Could not locate major Java version number in " + s)
  }

@som-snytt
Copy link
Contributor

som-snytt commented Jul 9, 2016

The previous long conversation:

#2580

#2666

In which the paulpian knot is cut by defining the method as a spec version test, 1.1, 1.8, 9, 10.

IIUC, this conversation is suggesting to return to impl version tests? That wouldn't be my choice.

@golem131
Copy link
Author

golem131 commented Jul 9, 2016

@som-snytt then what's your choice?

@som-snytt
Copy link
Contributor

I would stick with spec version tests. Fix the Scaladoc if it says different. That's all it used to do:

def isJavaAtLeast(version: String) = {
  val okVersions = version match {
    case "1.5"    => List("1.5", "1.6", "1.7")
    case "1.6"    => List("1.6", "1.7")
    case "1.7"    => List("1.7")
    case _        => Nil
  } 
  okVersions exists (javaVersion startsWith _)
}

It ought to have been, okVersions exists (javaSpecVersion == _).

Moral equivalent, javaSpecVersion.stripPrefix("1.").toInt >= version.stripPrefix("1.").toInt.

Also, I just re-remembered that s.split("\\.") doesn't use regex although it's required in general.

@SethTisue
Copy link
Member

superseded by #5276

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.

6 participants