why adding a multi-line comment in the code makes it uncompilable

Viewed 138

In the following function, if I add a multi-line comment then the code doesn't compile. Why?

def updateValues(tableName:String, model:User, id:UserKeys):Update.Where = {
    QueryBuilder.update(tableName).`with`/*WORKS*/(QueryBuilder.set("confirmed",model.profile.internalProfileDetails.get.confirmed))/*(QueryBuilder.set("authprovider",model.profile.internalProfileDetails.get.loginInfo.providerID)) //TODOM - remove hardcoding for bucket and also add bucket in User model*/
      .and(QueryBuilder.set("id",model.id))
      .and(QueryBuilder.set("password",model.profile.internalProfileDetails.get.passwordInfo.get.password))
      .and(QueryBuilder.set("hasher",model.profile.internalProfileDetails.get.passwordInfo.get.hasher))
      .and(QueryBuilder.set("salt",""/*model.profile.internalProfileDetails.get.passwordInfo.get.salt.get*/)) //salt is empty for BCryptSha256PasswordHasher. The 'hash' method of BCryptSha256PasswordHasher does not return the salt separately because it is embedded in the hashed password.
      .where(QueryBuilder.eq("bucket", id.bucket)) //TODOM - pick column names from config/env file
      .and(QueryBuilder.eq("email", id.email))
      .and(QueryBuilder.eq("authprovider", model.profile.internalProfileDetails.get.loginInfo.providerID))//TODOM - this should come from id
      .and(QueryBuilder.eq("firstname",model.profile.externalProfileDetails.firstName))
      .and(QueryBuilder.eq("lastname",model.profile.externalProfileDetails.lastName))

  }

But

    def updateValues(tableName:String, model:User, id:UserKeys):Update.Where = {
        QueryBuilder.update(tableName).`with`/*
DOESNT WORKS. I get error, cannot resolve and */(QueryBuilder.set("confirmed",model.profile.internalProfileDetails.get.confirmed))/*(QueryBuilder.set("authprovider",model.profile.internalProfileDetails.get.loginInfo.providerID)) //TODOM - remove hardcoding for bucket and also add bucket in User model*/
          .and(QueryBuilder.set("id",model.id))
          .and(QueryBuilder.set("password",model.profile.internalProfileDetails.get.passwordInfo.get.password))
          .and(QueryBuilder.set("hasher",model.profile.internalProfileDetails.get.passwordInfo.get.hasher))
          .and(QueryBuilder.set("salt",""/*model.profile.internalProfileDetails.get.passwordInfo.get.salt.get*/)) //salt is empty for BCryptSha256PasswordHasher. The 'hash' method of BCryptSha256PasswordHasher does not return the salt separately because it is embedded in the hashed password.
          .where(QueryBuilder.eq("bucket", id.bucket)) //TODOM - pick column names from config/env file
          .and(QueryBuilder.eq("email", id.email))
          .and(QueryBuilder.eq("authprovider", model.profile.internalProfileDetails.get.loginInfo.providerID))//TODOM - this should come from id
          .and(QueryBuilder.eq("firstname",model.profile.externalProfileDetails.firstName))
          .and(QueryBuilder.eq("lastname",model.profile.externalProfileDetails.lastName))

      }
1 Answers

Fast check in ammonite:

val x = List/*
multi */(1, 2, 3) 
x: List.type = scala.collection.immutable.List$@3697a307

val x = List/* single */(1, 2, 3)
x: List[Int] = List(1, 2, 3)

shows that parser interpret them as

val x = List
(1, 2, 3) 
x: List.type = scala.collection.immutable.List$@3697a307

val x = List(1, 2, 3)
x: List[Int] = List(1, 2, 3)

Why? Why isn't it simply removing comments and acting as if they weren't there?

My guess is that it is a bug in compiler, coming from the fact that Scala's parser tries to track all that created the AST - empty characters and comments including - and when it analyses whether it should be:

method(arg1, arg2)

or

value
(next expression in parenthesis)

it compares line numbers to distinguish them. Apparently no one considered the corner case when such handling of multi line comment would change the semantics. (Notice than in other cases this doesn't product erroneous behavior, which is why probably no one bothered with fixing this).

Update: you might try to fix this by forcing compiler to acknowledge it as one expression e.g. by moving left parenthesis before the comment:

val x = List(/*
multi */1, 2, 3)
x: List[Int] = List(1, 2, 3)
Related