Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 7 additions & 108 deletions jcodemodel/src/main/java/com/helger/jcodemodel/JAtomInt.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,140 +42,39 @@

import static com.helger.jcodemodel.util.JCHashCodeGenerator.getHashCode;

import java.util.function.IntFunction;

import org.jspecify.annotations.NonNull;

import com.helger.base.equals.EqualsHelper;
import com.helger.jcodemodel.literals.AIntegerRepresented;
import com.helger.jcodemodel.literals.IntegerRepresentation;

/**
* A special atom for int values
*/
public class JAtomInt implements IJExpression
public class JAtomInt extends AIntegerRepresented <JAtomInt> implements IJExpression
{

/// @see https://docs.oracle.com/javase/specs/jls/se17/html/jls-3.html#jls-3.10.1
public static enum Representation
{
BINARY ("0b", Integer::toBinaryString),
DECIMAL ("", Integer::toString),
HEX ("0x", Integer::toHexString),
OCTAL ("0", Integer::toOctalString);

@NonNull
final IntFunction <String> representer;

@NonNull
final String prefix;

Representation (String prefix, IntFunction <String> representer)
{
this.prefix = prefix;
this.representer = representer;
}

public String represent (int i, int every, int sepSize)
{
boolean neg = i < 0;
i = neg ? -i : i;
StringBuilder sb = new StringBuilder ();
if (neg)
sb.append ('-');
sb.append (prefix);
addSep (representer.apply (i), every, sepSize, sb);
return sb.toString ();
}

/// @param source unsigned non-prefixed representation , eg a5 for -0xa5 .
static void addSep(@NonNull String source, int every, int sepSize, StringBuilder sb) {
if (every < 1 || every >= source.length () || sepSize < 1)
{
sb.append (source);
return;
}
String sep = "_".repeat (sepSize);
for (int start = 0, end = source.length () % every; end <= source.length (); start = end, end += every)
{
if (start != 0)
sb.append (sep);
sb.append (source.substring (start, end));
}
}
}

private final int m_nValue;

@NonNull
private Representation representation = Representation.DECIMAL;

protected JAtomInt (final int nWhat)
{
m_nValue = nWhat;
}

public JAtomInt representation (Representation representation)
{
if (representation != null)
this.representation = representation;
return this;
}

public JAtomInt binary ()
{
return representation (Representation.BINARY);
}

public JAtomInt decimal ()
{
return representation (Representation.DECIMAL);
}

public JAtomInt hex ()
protected JAtomInt (final int nWhat, IntegerRepresentation representation)
{
return representation (Representation.HEX);
}

public JAtomInt octal ()
{
return representation (Representation.OCTAL);
m_nValue = nWhat;
representation (representation);
}

public int what ()
{
return m_nValue;
}

/// how many underscores per separation
private int separatorSize = 1;

public int separatorSize ()
{
return separatorSize;
}

public JAtomInt separatorSize (int size)
{
this.separatorSize = size;
return this;
}

/// how many underscores per separation
private int separateEvery = 0;

public int separateEvery ()
{
return separateEvery;
}

public JAtomInt separateEvery (int every)
{
this.separateEvery = every;
return this;
}

public void generate (@NonNull final IJFormatter f)
{
f.print (representation.represent (m_nValue, separateEvery, separatorSize));
f.print (representation.format (m_nValue));
}

@Override
Expand Down
13 changes: 10 additions & 3 deletions jcodemodel/src/main/java/com/helger/jcodemodel/JAtomLong.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,14 @@
import org.jspecify.annotations.NonNull;

import com.helger.base.equals.EqualsHelper;
import com.helger.jcodemodel.literals.AIntegerRepresented;
import com.helger.jcodemodel.literals.IntegerRepresentation;

/**
* A special atom for long values
*/
public class JAtomLong implements IJExpression
public class JAtomLong extends AIntegerRepresented <JAtomLong> implements IJExpression
{
public static final String SUFFIX_LONG = "L";

private final long m_nValue;

Expand All @@ -60,14 +61,20 @@ protected JAtomLong (final long nWhat)
m_nValue = nWhat;
}

public JAtomLong (final long nWhat, IntegerRepresentation representation)
{
m_nValue = nWhat;
representation (representation);
}

public long what ()
{
return m_nValue;
}

public void generate (@NonNull final IJFormatter f)
{
f.print (Long.toString (m_nValue) + SUFFIX_LONG);
f.print (representation.format (m_nValue));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package com.helger.jcodemodel.literals;

import org.jspecify.annotations.NonNull;

/// Something that has an IntegerRepresentation to update, in practice only JAtomInt and JAtomLong
///
/// Its abstract because it's just a tooling class to extend.
///
/// @param T must be declaring class, eg `class A extends AIntegerRepresented<A>`
public abstract class AIntegerRepresented <T extends AIntegerRepresented <T>>
{

@NonNull
protected IntegerRepresentation representation = IntegerRepresentation.DEFAULT;

@SuppressWarnings ("unchecked")
protected T self ()
{
return (T) this;
}

@NonNull
public IntegerRepresentation representation ()

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

I would prefer the annotations on the method return types and method parameters. If not, then not

@glelouet glelouet Aug 28, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

you mean add @NonNull on the return ? Sure. Can you do it, or I do it ?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

If it is too cumbersome for you, let me know

{
return representation;
}

/// change the internal representation to the provided one
///
/// @return this
/// @param representation if null, nothing changes.
public @NonNull T representation (IntegerRepresentation representation)
{
if (representation != null)
this.representation = representation;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

else this.representation = null?

@glelouet glelouet Aug 28, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

no, representation is @NonNull

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Then I'd prefer a "if (null) throw" with the parameter - to make sure the contract of the method is clear

return self ();
}

/// change the internal representation to show positive sign
///
/// @return this
public @NonNull T positiveSign (boolean positiveSign)
{
return representation (representation.positiveSign (positiveSign));
}

/// change the internal representation to use binary base
///
/// @return this
public @NonNull T binary ()
{
return representation (representation.base (EIntegerBase.BINARY));
}

/// change the internal representation to use decimal base
///
/// @return this
public @NonNull T decimal ()
{
return representation (representation.base (EIntegerBase.DECIMAL));
}

/// change the internal representation to use hexadecimal base
///
/// @return this
public @NonNull T hexadecimal ()
{
return representation (representation.base (EIntegerBase.HEXADECIMAL));
}

/// change the internal representation to use octal base
///
/// @return this
public @NonNull T octal ()
{
return representation (representation.base (EIntegerBase.OCTAL));
}

/// change the internal representation to use a fixed separator size (the number of character
/// BETWEEN
/// each separated group), used only when **NO** separator format is provided
///
/// @return this
public @NonNull T separatorSize (int size)
{
return representation (representation.separatorSize (size));
}

/// change the internal representation to use a fixed separator distance (the maximum number of
/// character IN
/// a separated group), used only when **NO** separator format is provided
///
/// @return this
public @NonNull T separateEvery (int every)
{
return representation (representation.separateEvery (every));
}

/// change the internal representation to use a padding value. The padding is not used for decimal
/// base, since leading "0" makes an octal.
///
/// @return this
public @NonNull T padding (int padding)
{
return representation (representation.padding (padding));
}

}
Loading
Loading