Permalink
Browse files

Add namespace support for native types

For the time being, there is no mechanism to add user classes,
or even using() statements, but now at least the mechanism is
fully defined, and the fully qualified class types are displayed
and internally tracked. The syntax for now is :: as the separator,
but it will probably change to . after some discussion and a
deprecation period. ms.lang and com.commandhelper are default
namespaces, and do not need to be specified, and in fact, at this
time cannot be specified, as there is currently no supported way
in code to fully qualify a class type. com.commandhelper will
eventually be removed once the CH functionality is split out, but
will be extensible by the embedding program, so will be added
back in specifically for CH scripts.

Before . can be used as the path separator, there needs to be a
deprecation period, for non-strict mode users, they could potentially
be concatenating bare strings, and that would interfere with this
mechanism, so this "feature" must be removed.
  • Loading branch information...
LadyCailin committed Oct 10, 2018
1 parent 867e071 commit dd1ed43f9da7af799fc64c56c6bef4fe06678a2f
Showing with 343 additions and 144 deletions.
  1. +3 −2 src/main/java/com/laytonsmith/core/Static.java
  2. +1 −1 src/main/java/com/laytonsmith/core/constructs/Auto.java
  3. +3 −3 src/main/java/com/laytonsmith/core/constructs/CArray.java
  4. +2 −2 src/main/java/com/laytonsmith/core/constructs/CBoolean.java
  5. +6 −6 src/main/java/com/laytonsmith/core/constructs/CByteArray.java
  6. +45 −2 src/main/java/com/laytonsmith/core/constructs/CClassType.java
  7. +2 −2 src/main/java/com/laytonsmith/core/constructs/CClosure.java
  8. +2 −2 src/main/java/com/laytonsmith/core/constructs/CDecimal.java
  9. +2 −2 src/main/java/com/laytonsmith/core/constructs/CDouble.java
  10. +2 −2 src/main/java/com/laytonsmith/core/constructs/CIClosure.java
  11. +2 −2 src/main/java/com/laytonsmith/core/constructs/CInt.java
  12. +2 −2 src/main/java/com/laytonsmith/core/constructs/CMutablePrimitive.java
  13. +2 −2 src/main/java/com/laytonsmith/core/constructs/CNumber.java
  14. +52 −0 src/main/java/com/laytonsmith/core/constructs/CPackage.java
  15. +2 −2 src/main/java/com/laytonsmith/core/constructs/CPrimitive.java
  16. +2 −2 src/main/java/com/laytonsmith/core/constructs/CResource.java
  17. +2 −2 src/main/java/com/laytonsmith/core/constructs/CSecureString.java
  18. +2 −2 src/main/java/com/laytonsmith/core/constructs/CSlice.java
  19. +2 −2 src/main/java/com/laytonsmith/core/constructs/CString.java
  20. +1 −1 src/main/java/com/laytonsmith/core/constructs/CVoid.java
  21. +13 −2 src/main/java/com/laytonsmith/core/constructs/InstanceofUtil.java
  22. +35 −5 src/main/java/com/laytonsmith/core/constructs/NativeTypeList.java
  23. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CREBadEntityException.java
  24. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CREBadEntityTypeException.java
  25. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CREBindException.java
  26. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CRECastException.java
  27. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CREEnchantmentException.java
  28. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CREError.java
  29. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CREEventException.java
  30. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CREException.java
  31. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CREFormatException.java
  32. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CREIOException.java
  33. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CREIllegalArgumentException.java
  34. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CREIncludeException.java
  35. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CREIndexOverflowException.java
  36. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CREInsufficientArgumentsException.java
  37. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CREInsufficientPermissionException.java
  38. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CREInvalidPluginException.java
  39. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CREInvalidProcedureException.java
  40. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CREInvalidWorldException.java
  41. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CRELengthException.java
  42. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CRENotFoundException.java
  43. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CRENullPointerException.java
  44. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CREOAuthException.java
  45. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CREPlayerOfflineException.java
  46. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CREPluginChannelException.java
  47. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CREPluginInternalException.java
  48. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CRERangeException.java
  49. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CREReadOnlyException.java
  50. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CRESQLException.java
  51. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CREScoreboardException.java
  52. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CRESecurityException.java
  53. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CREShellException.java
  54. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CREStackOverflowError.java
  55. +3 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CREThrowable.java
  56. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CREUnageableMobException.java
  57. +2 −2 src/main/java/com/laytonsmith/core/exceptions/CRE/CREUntameableMobException.java
  58. +59 −0 src/main/java/com/laytonsmith/core/functions/Reflection.java
  59. +2 −2 src/main/java/com/laytonsmith/core/natives/interfaces/ArrayAccess.java
  60. +2 −2 src/main/java/com/laytonsmith/core/natives/interfaces/Sizeable.java
  61. +8 −8 src/test/java/com/laytonsmith/core/MethodScriptCompilerTest.java
  62. +7 −6 src/test/java/com/laytonsmith/core/NewExceptionHandlingTest.java
  63. +1 −1 src/test/java/com/laytonsmith/core/OptimizationTest.java
  64. +5 −4 src/test/java/com/laytonsmith/core/constructs/InstanceofUtilTest.java
  65. +1 −1 src/test/java/com/laytonsmith/core/functions/BasicLogicTest.java
  66. +1 −1 src/test/java/com/laytonsmith/core/functions/StringHandlingTest.java
  67. +1 −1 src/test/java/com/laytonsmith/testing/RandomTests.java
@@ -524,8 +524,9 @@ public static Construct resolveConstruct(String val, Target t) throws ConfigRunt
}
// TODO: Once compiler environments are added, we would need to check to see if the value here is a custom
// type. However, as it stands, since we only support the native types, we will just hardcode the check here.
if(NativeTypeList.getNativeTypeList().contains(val)) {
return CClassType.get(val);
String fqType = NativeTypeList.resolveType(val);
if(fqType != null) {
return CClassType.get(fqType);
} else {
return new CString(val, t);
}
@@ -7,5 +7,5 @@
*/
public class Auto {
public static final CClassType TYPE = CClassType.get("auto");
public static final CClassType TYPE = CClassType.AUTO;
}
@@ -37,10 +37,10 @@
* For subclasses, the ArrayAccess methods are the most commonly overridden methods. There are several overloaded
* methods in this class, you need only to override the non-final ones for the same effect.
*/
@typeof("array")
@typeof("ms::lang::array")
public class CArray extends Construct implements ArrayAccess {
public static final CClassType TYPE = CClassType.get("array");
public static final CClassType TYPE = CClassType.get("ms::lang::array");
private boolean associativeMode = false;
private long nextIndex = 0;
private List<Construct> array;
@@ -863,7 +863,7 @@ public int compare(Construct o1, Construct o2) {
}
if(!(c instanceof CBoolean || c instanceof CString || c instanceof CInt
|| c instanceof CDouble || c instanceof CNull)) {
throw new CREFormatException("Unsupported type being sorted: " + c.getCType(), CArray.this.getTarget());
throw new CREFormatException("Unsupported type being sorted: " + c.typeof(), CArray.this.getTarget());
}
}
if(o1 instanceof CNull || o2 instanceof CNull) {
@@ -10,11 +10,11 @@
/**
* Represents a MethodScript boolean.
*/
@typeof("boolean")
@typeof("ms::lang::boolean")
public final class CBoolean extends CPrimitive implements Cloneable {
@SuppressWarnings("FieldNameHidesFieldInSuperclass")
public static final CClassType TYPE = CClassType.get("boolean");
public static final CClassType TYPE = CClassType.get("ms::lang::boolean");
public static final long serialVersionUID = 1L;
@@ -23,11 +23,11 @@
*
*
*/
@typeof("byte_array")
@typeof("ms::lang::byte_array")
public class CByteArray extends CArray implements Sizeable, ArrayAccess {
@SuppressWarnings("FieldNameHidesFieldInSuperclass")
public static final CClassType TYPE = CClassType.get("byte_array");
public static final CClassType TYPE = CClassType.get("ms::lang::byte_array");
/**
* Initial size of the ByteBuffer
@@ -524,11 +524,11 @@ public Version since() {
/**
* This is a more efficient implementation of CArray for the backing byte arrays.
*/
@typeof("ByteBackingArray")
@typeof("ms::lang::ByteBackingArray")
private static class CArrayByteBacking extends CArray {
@SuppressWarnings("FieldNameHidesFieldInSuperclass")
public static final CClassType TYPE = CClassType.get("ByteBackingArray");
public static final CClassType TYPE = CClassType.get("ms::lang::ByteBackingArray");
private final byte[] backing;
private String value = null;
@@ -626,11 +626,11 @@ public CClassType getContainingClass() {
return CByteArray.TYPE;
}
@typeof("ByteArrayReadOnlyException")
@typeof("ms::lang::ByteArrayReadOnlyException")
public static class CREByteArrayReadOnlyException extends CREReadOnlyException {
@SuppressWarnings("FieldNameHidesFieldInSuperclass")
public static final CClassType TYPE = CClassType.get("ByteArrayReadOnlyException");
public static final CClassType TYPE = CClassType.get("ms::lang::ByteArrayReadOnlyException");
public CREByteArrayReadOnlyException(java.lang.String msg, com.laytonsmith.core.constructs.Target t) {
super(msg, t);
@@ -1,5 +1,6 @@
package com.laytonsmith.core.constructs;
import com.laytonsmith.PureUtilities.Common.ArrayUtils;
import com.laytonsmith.PureUtilities.Common.StringUtils;
import com.laytonsmith.PureUtilities.Version;
import com.laytonsmith.annotations.typeof;
@@ -15,16 +16,21 @@
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.regex.Pattern;
/**
*
*/
@typeof("ClassType")
@typeof("ms::lang::ClassType")
public final class CClassType extends Construct {
public static final String PATH_SEPARATOR = "::";
private static final Map<String, CClassType> CACHE = new HashMap<>();
@SuppressWarnings("FieldNameHidesFieldInSuperclass")
public static final CClassType TYPE = new CClassType("ClassType", Target.UNKNOWN);
public static final CClassType TYPE = new CClassType("ms::lang::ClassType", Target.UNKNOWN);
public static final CClassType AUTO = new CClassType("auto", Target.UNKNOWN);
public static final CClassType VOID = new CClassType("void", Target.UNKNOWN);
/**
* This should generally be used instead of creating a new empty array in getInterfaces, if no interfaces are
@@ -53,6 +59,9 @@ public int compare(String o1, String o2) {
* @return
*/
public static CClassType get(String type) {
// This must change once user types are added
type = NativeTypeList.resolveType(type);
assert type != null;
if(!CACHE.containsKey(type)) {
CACHE.put(type, new CClassType(type, Target.UNKNOWN));
}
@@ -71,6 +80,10 @@ public static CClassType get(String type) {
*/
public static CClassType get(String... types) {
// First, we have to canonicalize this type union
for(int i = 0; i < types.length; i++) {
// This must change once user types are added
types[i] = NativeTypeList.resolveType(types[i]);
}
SortedSet<String> t = new TreeSet<>(Arrays.asList(types));
String type = StringUtils.Join(t, "|");
if(!CACHE.containsKey(type)) {
@@ -258,6 +271,36 @@ public boolean unsafeIsExtendedBy(CClassType checkClass) {
}
return t;
}
/**
* Returns the package that this class is in. If the class is not in a package, or if this is a class union, null
* is returned.
* @return
*/
public CPackage getPackage() {
if(isTypeUnion) {
return null;
}
if(!val().contains(PATH_SEPARATOR)) {
return null;
}
String[] parts = val().split(Pattern.quote(PATH_SEPARATOR));
return new CPackage(Target.UNKNOWN, ArrayUtils.slice(parts, 0, parts.length - 2));
}
/**
* Returns the name of the class type without the package. If this is a type union, then each type is simplified,
* and returned as a string such as "int|string".
* @return
*/
public String getSimpleName() {
List<String> parts = new ArrayList<>();
for(CClassType t : getTypes()) {
String[] sparts = val().split(Pattern.quote(PATH_SEPARATOR));
parts.add(sparts[sparts.length - 1]);
}
return StringUtils.Join(parts, "|");
}
@Override
public String docs() {
@@ -27,7 +27,7 @@
*
*
*/
@typeof("closure")
@typeof("ms::lang::closure")
public class CClosure extends Construct {
public static final long serialVersionUID = 1L;
@@ -39,7 +39,7 @@
protected final CClassType returnType;
@SuppressWarnings("FieldNameHidesFieldInSuperclass")
public static final CClassType TYPE = CClassType.get("closure");
public static final CClassType TYPE = CClassType.get("ms::lang::closure");
public CClosure(ParseTree node, Environment env, CClassType returnType, String[] names, Construct[] defaults, CClassType[] types, Target t) {
super(node != null ? node.toString() : "", ConstructType.CLOSURE, t);
@@ -10,11 +10,11 @@
*
* @author cailin
*/
@typeof("decimal")
@typeof("ms::lang::decimal")
public class CDecimal extends CPrimitive implements Cloneable {
@SuppressWarnings("FieldNameHidesFieldInSuperclass")
public static final CClassType TYPE = CClassType.get("decimal");
public static final CClassType TYPE = CClassType.get("ms::lang::decimal");
private final BigDecimal val;
@@ -9,11 +9,11 @@
*
*
*/
@typeof("double")
@typeof("ms::lang::double")
public class CDouble extends CNumber implements Cloneable {
@SuppressWarnings("FieldNameHidesFieldInSuperclass")
public static final CClassType TYPE = CClassType.get("double");
public static final CClassType TYPE = CClassType.get("ms::lang::double");
public static final long serialVersionUID = 1L;
final double val;
@@ -23,11 +23,11 @@
/**
*
*/
@typeof("iclosure")
@typeof("ms::lang::iclosure")
public class CIClosure extends CClosure {
@SuppressWarnings("FieldNameHidesFieldInSuperclass")
public static final CClassType TYPE = CClassType.get("iclosure");
public static final CClassType TYPE = CClassType.get("ms::lang::iclosure");
public CIClosure(ParseTree node, Environment env, CClassType returnType, String[] names, Construct[] defaults, CClassType[] types, Target t) {
super(node, env, returnType, names, defaults, types, t);
@@ -9,11 +9,11 @@
*
*
*/
@typeof("int")
@typeof("ms::lang::int")
public class CInt extends CNumber implements Cloneable {
@SuppressWarnings("FieldNameHidesFieldInSuperclass")
public static final CClassType TYPE = CClassType.get("int");
public static final CClassType TYPE = CClassType.get("ms::lang::int");
public static final long serialVersionUID = 1L;
final long val;
@@ -13,11 +13,11 @@
/**
*
*/
@typeof("mutable_primitive")
@typeof("ms::lang::mutable_primitive")
public class CMutablePrimitive extends CArray implements Sizeable {
@SuppressWarnings("FieldNameHidesFieldInSuperclass")
public static final CClassType TYPE = CClassType.get("mutable_primitive");
public static final CClassType TYPE = CClassType.get("ms::lang::mutable_primitive");
private Construct value = CNull.NULL;
@@ -7,11 +7,11 @@
/**
*
*/
@typeof("number")
@typeof("ms::lang::number")
public abstract class CNumber extends CPrimitive {
@SuppressWarnings("FieldNameHidesFieldInSuperclass")
public static final CClassType TYPE = CClassType.get("number");
public static final CClassType TYPE = CClassType.get("ms::lang::number");
public CNumber(String value, ConstructType type, Target t) {
super(value, type, t);
@@ -0,0 +1,52 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.laytonsmith.core.constructs;
import com.laytonsmith.PureUtilities.Common.StringUtils;
import com.laytonsmith.PureUtilities.Version;
import com.laytonsmith.annotations.typeof;
import com.laytonsmith.core.CHVersion;
/**
*
* @author Cailin
*/
@typeof("ms::lang::Package")
public class CPackage extends Construct {
@SuppressWarnings("FieldNameHidesFieldInSuperclass")
public static final CClassType TYPE = CClassType.get("ms::lang::Package");
public CPackage(Target t, String... parts) {
super(StringUtils.Join(parts, CClassType.PATH_SEPARATOR), Construct.ConstructType.IDENTIFIER, t);
}
@Override
public boolean isDynamic() {
return false;
}
@Override
public String docs() {
return "Represents the package that a class is in.";
}
@Override
public Version since() {
return CHVersion.V3_3_3;
}
@Override
public CClassType[] getSuperclasses() {
return new CClassType[0];
}
@Override
public CClassType[] getInterfaces() {
return new CClassType[0];
}
}
@@ -7,11 +7,11 @@
/**
*
*/
@typeof("primitive")
@typeof("ms::lang::primitive")
public abstract class CPrimitive extends Construct {
@SuppressWarnings("FieldNameHidesFieldInSuperclass")
public static final CClassType TYPE = CClassType.get("primitive");
public static final CClassType TYPE = CClassType.get("ms::lang::primitive");
public CPrimitive(String value, ConstructType type, Target t) {
super(value, type, t);
@@ -12,11 +12,11 @@
* slightly more complicated. Therefore, this is a stopgap measure that WILL be removed at some point, once Objects are
* created.
*/
@typeof("resource")
@typeof("ms::lang::resource")
public class CResource<T> extends Construct {
@SuppressWarnings("FieldNameHidesFieldInSuperclass")
public static final CClassType TYPE = CClassType.get("resource");
public static final CClassType TYPE = CClassType.get("ms::lang::resource");
private static final AtomicLong RESOURCE_POOL = new AtomicLong(0);
@@ -28,11 +28,11 @@
*
* @author cailin
*/
@typeof("secure_string")
@typeof("ms::lang::secure_string")
public class CSecureString extends CString {
@SuppressWarnings("FieldNameHidesFieldInSuperclass")
public static final CClassType TYPE = CClassType.get("secure_string");
public static final CClassType TYPE = CClassType.get("ms::lang::secure_string");
private byte[] encrypted;
private Cipher decrypter;
@@ -19,11 +19,11 @@
*
*
*/
@typeof("slice")
@typeof("ms::lang::slice")
public class CSlice extends CArray {
@SuppressWarnings("FieldNameHidesFieldInSuperclass")
public static final CClassType TYPE = CClassType.get("slice");
public static final CClassType TYPE = CClassType.get("ms::lang::slice");
private long start;
private long finish;
Oops, something went wrong.

0 comments on commit dd1ed43

Please sign in to comment.