Browse Source

[WIP, I have no idea what I'm doing]Get types declared in StdLibs from the registry

kindlich 5 years ago
parent
commit
422ee64c85
No known key found for this signature in database

+ 4
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/annotations/NativeDefinitionAnnotation.java View File

40
 	public void serialize(CodeSerializationOutput output, HighLevelDefinition definition, TypeContext context) {
40
 	public void serialize(CodeSerializationOutput output, HighLevelDefinition definition, TypeContext context) {
41
 		output.writeString(identifier);
41
 		output.writeString(identifier);
42
 	}
42
 	}
43
+
44
+	public String getIdentifier() {
45
+		return identifier;
46
+	}
43
 }
47
 }

+ 5
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/GlobalTypeRegistry.java View File

5
  */
5
  */
6
 package org.openzen.zenscript.codemodel.type;
6
 package org.openzen.zenscript.codemodel.type;
7
 
7
 
8
+import java.util.Collection;
8
 import java.util.HashMap;
9
 import java.util.HashMap;
9
 import java.util.Map;
10
 import java.util.Map;
10
 import org.openzen.zenscript.codemodel.FunctionHeader;
11
 import org.openzen.zenscript.codemodel.FunctionHeader;
110
 			return id;
111
 			return id;
111
 		}
112
 		}
112
 	}
113
 	}
114
+
115
+	public Collection<DefinitionTypeID> getDefinitions() {
116
+		return definitionTypes.keySet();
117
+	}
113
 }
118
 }

+ 174
- 169
JavaIntegration/src/main/java/org/openzen/zencode/java/JavaNativeModule.java View File

10
 import org.openzen.zencode.shared.LiteralSourceFile;
10
 import org.openzen.zencode.shared.LiteralSourceFile;
11
 import org.openzen.zenscript.codemodel.*;
11
 import org.openzen.zenscript.codemodel.*;
12
 import org.openzen.zenscript.codemodel.annotations.AnnotationDefinition;
12
 import org.openzen.zenscript.codemodel.annotations.AnnotationDefinition;
13
+import org.openzen.zenscript.codemodel.annotations.DefinitionAnnotation;
14
+import org.openzen.zenscript.codemodel.annotations.NativeDefinitionAnnotation;
13
 import org.openzen.zenscript.codemodel.context.CompilingPackage;
15
 import org.openzen.zenscript.codemodel.context.CompilingPackage;
14
 import org.openzen.zenscript.codemodel.context.FileResolutionContext;
16
 import org.openzen.zenscript.codemodel.context.FileResolutionContext;
15
 import org.openzen.zenscript.codemodel.context.ModuleTypeResolutionContext;
17
 import org.openzen.zenscript.codemodel.context.ModuleTypeResolutionContext;
16
-import org.openzen.zenscript.codemodel.definition.ClassDefinition;
17
-import org.openzen.zenscript.codemodel.definition.EnumDefinition;
18
-import org.openzen.zenscript.codemodel.definition.ExpansionDefinition;
19
-import org.openzen.zenscript.codemodel.definition.InterfaceDefinition;
20
-import org.openzen.zenscript.codemodel.definition.StructDefinition;
21
-import org.openzen.zenscript.codemodel.definition.ZSPackage;
22
-import org.openzen.zenscript.codemodel.expression.ConstantByteExpression;
23
-import org.openzen.zenscript.codemodel.expression.ConstantDoubleExpression;
24
-import org.openzen.zenscript.codemodel.expression.ConstantFloatExpression;
25
-import org.openzen.zenscript.codemodel.expression.ConstantIntExpression;
26
-import org.openzen.zenscript.codemodel.expression.ConstantLongExpression;
27
-import org.openzen.zenscript.codemodel.expression.ConstantSByteExpression;
28
-import org.openzen.zenscript.codemodel.expression.ConstantShortExpression;
29
-import org.openzen.zenscript.codemodel.expression.ConstantStringExpression;
30
-import org.openzen.zenscript.codemodel.expression.ConstantUIntExpression;
31
-import org.openzen.zenscript.codemodel.expression.ConstantULongExpression;
32
-import org.openzen.zenscript.codemodel.expression.ConstantUShortExpression;
33
-import org.openzen.zenscript.codemodel.expression.Expression;
34
-import org.openzen.zenscript.codemodel.expression.ExpressionSymbol;
35
-import org.openzen.zenscript.codemodel.expression.StaticGetterExpression;
36
-import org.openzen.zenscript.codemodel.expression.StorageCastExpression;
18
+import org.openzen.zenscript.codemodel.definition.*;
19
+import org.openzen.zenscript.codemodel.expression.*;
37
 import org.openzen.zenscript.codemodel.generic.ParameterTypeBound;
20
 import org.openzen.zenscript.codemodel.generic.ParameterTypeBound;
38
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
21
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
39
-import org.openzen.zenscript.codemodel.member.CasterMember;
40
-import org.openzen.zenscript.codemodel.member.ConstructorMember;
41
-import org.openzen.zenscript.codemodel.member.FieldMember;
42
-import org.openzen.zenscript.codemodel.member.GetterMember;
43
-import org.openzen.zenscript.codemodel.member.ImplementationMember;
44
-import org.openzen.zenscript.codemodel.member.MethodMember;
45
-import org.openzen.zenscript.codemodel.member.OperatorMember;
46
-import org.openzen.zenscript.codemodel.member.SetterMember;
22
+import org.openzen.zenscript.codemodel.member.*;
47
 import org.openzen.zenscript.codemodel.member.ref.FunctionalMemberRef;
23
 import org.openzen.zenscript.codemodel.member.ref.FunctionalMemberRef;
48
 import org.openzen.zenscript.codemodel.partial.PartialStaticMemberGroupExpression;
24
 import org.openzen.zenscript.codemodel.partial.PartialStaticMemberGroupExpression;
49
 import org.openzen.zenscript.codemodel.scope.ExpressionScope;
25
 import org.openzen.zenscript.codemodel.scope.ExpressionScope;
56
 import org.openzen.zenscript.codemodel.type.storage.StorageTag;
32
 import org.openzen.zenscript.codemodel.type.storage.StorageTag;
57
 import org.openzen.zenscript.codemodel.type.storage.StorageType;
33
 import org.openzen.zenscript.codemodel.type.storage.StorageType;
58
 import org.openzen.zenscript.javashared.*;
34
 import org.openzen.zenscript.javashared.*;
59
-import org.openzen.zenscript.lexer.*;
35
+import org.openzen.zenscript.lexer.ParseException;
36
+import org.openzen.zenscript.lexer.ZSTokenParser;
60
 import org.openzen.zenscript.parser.BracketExpressionParser;
37
 import org.openzen.zenscript.parser.BracketExpressionParser;
61
 import org.openzen.zenscript.parser.expression.ParsedExpression;
38
 import org.openzen.zenscript.parser.expression.ParsedExpression;
62
 import org.openzen.zenscript.parser.type.IParsedType;
39
 import org.openzen.zenscript.parser.type.IParsedType;
77
 	private final GlobalTypeRegistry registry;
54
 	private final GlobalTypeRegistry registry;
78
 	private final PackageDefinitions definitions = new PackageDefinitions();
55
 	private final PackageDefinitions definitions = new PackageDefinitions();
79
 	private final JavaCompiledModule compiled;
56
 	private final JavaCompiledModule compiled;
80
-	
57
+
81
 	private final Map<Class<?>, HighLevelDefinition> definitionByClass = new HashMap<>();
58
 	private final Map<Class<?>, HighLevelDefinition> definitionByClass = new HashMap<>();
82
 	private final Map<Class<?>, TypeID> typeByClass = new HashMap<>();
59
 	private final Map<Class<?>, TypeID> typeByClass = new HashMap<>();
83
 	private final Map<Class<?>, TypeID> unsignedByClass = new HashMap<>();
60
 	private final Map<Class<?>, TypeID> unsignedByClass = new HashMap<>();
84
 	private final TypeVariableContext context = new TypeVariableContext();
61
 	private final TypeVariableContext context = new TypeVariableContext();
85
-	
62
+
86
 	public final Map<String, ISymbol> globals = new HashMap<>();
63
 	public final Map<String, ISymbol> globals = new HashMap<>();
87
 	private BracketExpressionParser bep;
64
 	private BracketExpressionParser bep;
88
 
65
 
96
 		this.basePackage = basePackage;
73
 		this.basePackage = basePackage;
97
 		module = new Module(name);
74
 		module = new Module(name);
98
 		this.registry = registry;
75
 		this.registry = registry;
99
-		
76
+
100
 		for (JavaNativeModule dependency : dependencies) {
77
 		for (JavaNativeModule dependency : dependencies) {
101
 			definitionByClass.putAll(dependency.definitionByClass);
78
 			definitionByClass.putAll(dependency.definitionByClass);
102
 		}
79
 		}
103
-		
80
+
104
 		compiled = new JavaCompiledModule(module, FunctionParameter.NONE);
81
 		compiled = new JavaCompiledModule(module, FunctionParameter.NONE);
105
-		
82
+
106
 		typeByClass.put(void.class, BasicTypeID.VOID);
83
 		typeByClass.put(void.class, BasicTypeID.VOID);
107
 		typeByClass.put(boolean.class, BasicTypeID.BOOL);
84
 		typeByClass.put(boolean.class, BasicTypeID.BOOL);
108
 		typeByClass.put(byte.class, BasicTypeID.SBYTE);
85
 		typeByClass.put(byte.class, BasicTypeID.SBYTE);
119
 		typeByClass.put(Long.class, registry.getOptional(BasicTypeID.LONG));
96
 		typeByClass.put(Long.class, registry.getOptional(BasicTypeID.LONG));
120
 		typeByClass.put(Float.class, registry.getOptional(BasicTypeID.FLOAT));
97
 		typeByClass.put(Float.class, registry.getOptional(BasicTypeID.FLOAT));
121
 		typeByClass.put(Double.class, registry.getOptional(BasicTypeID.DOUBLE));
98
 		typeByClass.put(Double.class, registry.getOptional(BasicTypeID.DOUBLE));
122
-		
99
+
123
 		unsignedByClass.put(byte.class, BasicTypeID.BYTE);
100
 		unsignedByClass.put(byte.class, BasicTypeID.BYTE);
124
 		unsignedByClass.put(short.class, BasicTypeID.USHORT);
101
 		unsignedByClass.put(short.class, BasicTypeID.USHORT);
125
 		unsignedByClass.put(int.class, BasicTypeID.UINT);
102
 		unsignedByClass.put(int.class, BasicTypeID.UINT);
129
 		unsignedByClass.put(Integer.class, registry.getOptional(BasicTypeID.INT));
106
 		unsignedByClass.put(Integer.class, registry.getOptional(BasicTypeID.INT));
130
 		unsignedByClass.put(Long.class, registry.getOptional(BasicTypeID.LONG));
107
 		unsignedByClass.put(Long.class, registry.getOptional(BasicTypeID.LONG));
131
 	}
108
 	}
132
-	
109
+
133
 	public SemanticModule toSemantic(ModuleSpace space) {
110
 	public SemanticModule toSemantic(ModuleSpace space) {
134
 		return new SemanticModule(
111
 		return new SemanticModule(
135
 				module,
112
 				module,
145
 				space.getAnnotations(),
122
 				space.getAnnotations(),
146
 				space.getStorageTypes());
123
 				space.getStorageTypes());
147
 	}
124
 	}
148
-	
125
+
149
 	public JavaCompiledModule getCompiled() {
126
 	public JavaCompiledModule getCompiled() {
150
 		return compiled;
127
 		return compiled;
151
 	}
128
 	}
152
-	
129
+
153
 	public HighLevelDefinition addClass(Class<?> cls) {
130
 	public HighLevelDefinition addClass(Class<?> cls) {
154
-		if (definitionByClass.containsKey(cls))
131
+		if (definitionByClass.containsKey(cls)) {
155
 			return definitionByClass.get(cls);
132
 			return definitionByClass.get(cls);
156
-        
133
+		}
157
         return convertClass(cls);
134
         return convertClass(cls);
158
 	}
135
 	}
159
-	
136
+
160
 	public void addGlobals(Class<?> cls) {
137
 	public void addGlobals(Class<?> cls) {
161
 		HighLevelDefinition definition = new ClassDefinition(CodePosition.NATIVE, module, pkg, "__globals__", Modifiers.PUBLIC);
138
 		HighLevelDefinition definition = new ClassDefinition(CodePosition.NATIVE, module, pkg, "__globals__", Modifiers.PUBLIC);
162
 		JavaClass jcls = JavaClass.fromInternalName(getInternalName(cls), JavaClass.Kind.CLASS);
139
 		JavaClass jcls = JavaClass.fromInternalName(getInternalName(cls), JavaClass.Kind.CLASS);
163
 		compiled.setClassInfo(definition, jcls);
140
 		compiled.setClassInfo(definition, jcls);
164
 		StoredType thisType = registry.getForMyDefinition(definition).stored();
141
 		StoredType thisType = registry.getForMyDefinition(definition).stored();
165
 		//TypeVariableContext context = new TypeVariableContext();
142
 		//TypeVariableContext context = new TypeVariableContext();
166
-		
143
+
167
 		for (Field field : cls.getDeclaredFields()) {
144
 		for (Field field : cls.getDeclaredFields()) {
168
 			if (!field.isAnnotationPresent(ZenCodeGlobals.Global.class))
145
 			if (!field.isAnnotationPresent(ZenCodeGlobals.Global.class))
169
 				continue;
146
 				continue;
170
 			if (!isStatic(field.getModifiers()))
147
 			if (!isStatic(field.getModifiers()))
171
 				continue;
148
 				continue;
172
-			
149
+
173
 			ZenCodeGlobals.Global global = field.getAnnotation(ZenCodeGlobals.Global.class);
150
 			ZenCodeGlobals.Global global = field.getAnnotation(ZenCodeGlobals.Global.class);
174
 			StoredType type = loadStoredType(context, field.getAnnotatedType());
151
 			StoredType type = loadStoredType(context, field.getAnnotatedType());
175
 			String name = global.value().isEmpty() ? field.getName() : global.value();
152
 			String name = global.value().isEmpty() ? field.getName() : global.value();
180
 			compiled.setFieldInfo(fieldMember.autoGetter, javaField);
157
 			compiled.setFieldInfo(fieldMember.autoGetter, javaField);
181
 			globals.put(name, new ExpressionSymbol((position, scope) -> new StaticGetterExpression(CodePosition.BUILTIN, fieldMember.autoGetter.ref(thisType, GenericMapper.EMPTY))));
158
 			globals.put(name, new ExpressionSymbol((position, scope) -> new StaticGetterExpression(CodePosition.BUILTIN, fieldMember.autoGetter.ref(thisType, GenericMapper.EMPTY))));
182
 		}
159
 		}
183
-		
160
+
184
 		for (Method method : cls.getDeclaredMethods()) {
161
 		for (Method method : cls.getDeclaredMethods()) {
185
 			if (!method.isAnnotationPresent(ZenCodeGlobals.Global.class))
162
 			if (!method.isAnnotationPresent(ZenCodeGlobals.Global.class))
186
 				continue;
163
 				continue;
187
 			if (!isStatic(method.getModifiers()))
164
 			if (!isStatic(method.getModifiers()))
188
 				continue;
165
 				continue;
189
-			
166
+
190
 			ZenCodeGlobals.Global global = method.getAnnotation(ZenCodeGlobals.Global.class);
167
 			ZenCodeGlobals.Global global = method.getAnnotation(ZenCodeGlobals.Global.class);
191
 			String name = global.value().isEmpty() ? method.getName() : global.value();
168
 			String name = global.value().isEmpty() ? method.getName() : global.value();
192
 			MethodMember methodMember = new MethodMember(CodePosition.NATIVE, definition, Modifiers.PUBLIC | Modifiers.STATIC, name, getHeader(context, method), null);
169
 			MethodMember methodMember = new MethodMember(CodePosition.NATIVE, definition, Modifiers.PUBLIC | Modifiers.STATIC, name, getHeader(context, method), null);
193
 			definition.addMember(methodMember);
170
 			definition.addMember(methodMember);
194
-			
171
+
195
 			boolean isGenericResult = methodMember.header.getReturnType().isGeneric();
172
 			boolean isGenericResult = methodMember.header.getReturnType().isGeneric();
196
 			compiled.setMethodInfo(methodMember, new JavaMethod(jcls, JavaMethod.Kind.STATIC, method.getName(), false, getMethodDescriptor(method), method.getModifiers(), isGenericResult));
173
 			compiled.setMethodInfo(methodMember, new JavaMethod(jcls, JavaMethod.Kind.STATIC, method.getName(), false, getMethodDescriptor(method), method.getModifiers(), isGenericResult));
197
 			globals.put(name, new ExpressionSymbol((position, scope) -> {
174
 			globals.put(name, new ExpressionSymbol((position, scope) -> {
200
 			}));
177
 			}));
201
 		}
178
 		}
202
 	}
179
 	}
203
-	
180
+
204
 	public FunctionalMemberRef loadStaticMethod(Method method) {
181
 	public FunctionalMemberRef loadStaticMethod(Method method) {
205
 		if (!isStatic(method.getModifiers()))
182
 		if (!isStatic(method.getModifiers()))
206
 			throw new IllegalArgumentException("Method \"" + method.toString() + "\" is not static");
183
 			throw new IllegalArgumentException("Method \"" + method.toString() + "\" is not static");
207
-		
184
+
208
 		HighLevelDefinition definition = addClass(method.getDeclaringClass());
185
 		HighLevelDefinition definition = addClass(method.getDeclaringClass());
209
 		JavaClass jcls = JavaClass.fromInternalName(getInternalName(method.getDeclaringClass()), JavaClass.Kind.CLASS);
186
 		JavaClass jcls = JavaClass.fromInternalName(getInternalName(method.getDeclaringClass()), JavaClass.Kind.CLASS);
210
-		
187
+
211
 		//TypeVariableContext context = new TypeVariableContext();
188
 		//TypeVariableContext context = new TypeVariableContext();
212
 		MethodMember methodMember = new MethodMember(CodePosition.NATIVE, definition, Modifiers.PUBLIC | Modifiers.STATIC, method.getName(), getHeader(context, method), null);
189
 		MethodMember methodMember = new MethodMember(CodePosition.NATIVE, definition, Modifiers.PUBLIC | Modifiers.STATIC, method.getName(), getHeader(context, method), null);
213
 		definition.addMember(methodMember);
190
 		definition.addMember(methodMember);
219
 	private boolean isInBasePackage(String className) {
196
 	private boolean isInBasePackage(String className) {
220
 		return className.startsWith(basePackage + ".");
197
 		return className.startsWith(basePackage + ".");
221
 	}
198
 	}
222
-	
199
+
223
 	private ZSPackage getPackage(String className) {
200
 	private ZSPackage getPackage(String className) {
224
 		//TODO validate
201
 		//TODO validate
225
 		if(this.basePackage == null || this.basePackage.isEmpty())
202
 		if(this.basePackage == null || this.basePackage.isEmpty())
227
 		//TODO make a lang package?
204
 		//TODO make a lang package?
228
 		if (!className.contains(".") || className.startsWith("java.lang"))
205
 		if (!className.contains(".") || className.startsWith("java.lang"))
229
 			return pkg;
206
 			return pkg;
230
-		
207
+
231
 		if (className.startsWith("."))
208
 		if (className.startsWith("."))
232
 			className = className.substring(1);
209
 			className = className.substring(1);
233
 		else if (className.startsWith(basePackage + "."))
210
 		else if (className.startsWith(basePackage + "."))
234
 			className = className.substring(basePackage.length() + 1);
211
 			className = className.substring(basePackage.length() + 1);
235
 		else
212
 		else
236
             throw new IllegalArgumentException("Invalid class name: \"" + className + "\" not in the given base package: \"" + basePackage + "\"");
213
             throw new IllegalArgumentException("Invalid class name: \"" + className + "\" not in the given base package: \"" + basePackage + "\"");
237
-		
214
+
238
 		String[] classNameParts = Strings.split(className, '.');
215
 		String[] classNameParts = Strings.split(className, '.');
239
 		ZSPackage classPkg = pkg;
216
 		ZSPackage classPkg = pkg;
240
 		for (int i = 0; i < classNameParts.length - 1; i++)
217
 		for (int i = 0; i < classNameParts.length - 1; i++)
241
 			classPkg = classPkg.getOrCreatePackage(classNameParts[i]);
218
 			classPkg = classPkg.getOrCreatePackage(classNameParts[i]);
242
-		
219
+
243
 		return classPkg;
220
 		return classPkg;
244
 	}
221
 	}
245
-	
222
+
223
+	private <T> HighLevelDefinition checkRegistry(Class<T> cls) {
224
+		String name = cls.getCanonicalName();
225
+		if (!name.startsWith("java.lang.") && !name.startsWith("java.util.")) {
226
+			return null;
227
+		}
228
+
229
+		name = name.substring("java.lang.".length());
230
+		for (DefinitionTypeID definition : registry.getDefinitions()) {
231
+			final HighLevelDefinition highLevelDefinition = definition.definition;
232
+			for (DefinitionAnnotation annotation : highLevelDefinition.annotations) {
233
+				if (annotation instanceof NativeDefinitionAnnotation) {
234
+					final String identifier = ((NativeDefinitionAnnotation) annotation).getIdentifier();
235
+					if (identifier.equals(name) || identifier.equals("stdlib::" + name)) {
236
+						return highLevelDefinition;
237
+					}
238
+				}
239
+			}
240
+		}
241
+
242
+		return null;
243
+	}
244
+
246
 	private <T> HighLevelDefinition convertClass(Class<T> cls) {
245
 	private <T> HighLevelDefinition convertClass(Class<T> cls) {
247
 		if ((cls.getModifiers() & Modifier.PUBLIC) == 0)
246
 		if ((cls.getModifiers() & Modifier.PUBLIC) == 0)
248
 			throw new IllegalArgumentException("Class \" " + cls.getName() + "\" must be public");
247
 			throw new IllegalArgumentException("Class \" " + cls.getName() + "\" must be public");
253
 
252
 
254
 		String className = cls.getName();
253
 		String className = cls.getName();
255
         boolean isStruct = cls.isAnnotationPresent(ZenCodeType.Struct.class);
254
         boolean isStruct = cls.isAnnotationPresent(ZenCodeType.Struct.class);
256
-        
257
-        ZSPackage classPkg;
258
-        ZenCodeType.Name nameAnnotation = cls.getDeclaredAnnotation(ZenCodeType.Name.class);
259
-		className = className.contains(".") ? className.substring(className.lastIndexOf('.') + 1) : className;
260
-        if (nameAnnotation == null) {
261
-            classPkg = getPackage(className);
262
-        } else {
263
-            String specifiedName = nameAnnotation.value();
264
-			if (specifiedName.startsWith(".")) {
265
-				classPkg = getPackage(specifiedName);
266
-				className = specifiedName.substring(specifiedName.lastIndexOf('.') + 1);
267
-			} else if (specifiedName.indexOf('.') >= 0) {
268
-				if (!specifiedName.startsWith(pkg.fullName))
269
-					throw new IllegalArgumentException("Specified @Name as \"" + specifiedName + "\" for class: \"" + cls.toString() + "\" but it's not in the module root package");
270
-
271
-				classPkg = getPackage(basePackage + specifiedName.substring(pkg.fullName.length()));
272
-				className = specifiedName.substring(specifiedName.lastIndexOf('.') + 1);
273
-			} else {
274
-                classPkg = getPackage(specifiedName);
275
-                className = nameAnnotation.value();
276
-			}
277
-		}
278
-
279
 
255
 
280
-		
281
-		HighLevelDefinition definition;
256
+		HighLevelDefinition definition = checkRegistry(cls);
257
+		final boolean foundRegistry = definition != null;
282
 		String internalName = getInternalName(cls);
258
 		String internalName = getInternalName(cls);
283
 		JavaClass javaClass;
259
 		JavaClass javaClass;
284
-		if (cls.isInterface()) {
285
-			definition = new InterfaceDefinition(CodePosition.NATIVE, module, classPkg, className, Modifiers.PUBLIC, null);
286
-			javaClass = JavaClass.fromInternalName(internalName, JavaClass.Kind.INTERFACE);
287
-		} else if (cls.isEnum()) {
288
-			definition = new EnumDefinition(CodePosition.NATIVE, module, classPkg, className, Modifiers.PUBLIC, null);
289
-			javaClass = JavaClass.fromInternalName(internalName, JavaClass.Kind.ENUM);
290
-		} else if (isStruct) {
291
-			definition = new StructDefinition(CodePosition.NATIVE, module, classPkg, className, Modifiers.PUBLIC, null);
292
-			javaClass = JavaClass.fromInternalName(internalName, JavaClass.Kind.CLASS);
260
+
261
+		if (foundRegistry) {
262
+			javaClass = JavaClass.fromInternalName(internalName, definition.isInterface() ? JavaClass.Kind.INTERFACE : JavaClass.Kind.CLASS);
293
 		} else {
263
 		} else {
294
-			definition = new ClassDefinition(CodePosition.NATIVE, module, classPkg, className, Modifiers.PUBLIC);
295
-			javaClass = JavaClass.fromInternalName(internalName, JavaClass.Kind.CLASS);
264
+			ZSPackage classPkg;
265
+			ZenCodeType.Name nameAnnotation = cls.getDeclaredAnnotation(ZenCodeType.Name.class);
266
+			className = className.contains(".") ? className.substring(className.lastIndexOf('.') + 1) : className;
267
+			if (nameAnnotation == null) {
268
+				classPkg = getPackage(className);
269
+			} else {
270
+				String specifiedName = nameAnnotation.value();
271
+				if (specifiedName.startsWith(".")) {
272
+					classPkg = getPackage(specifiedName);
273
+					className = specifiedName.substring(specifiedName.lastIndexOf('.') + 1);
274
+				} else if (specifiedName.indexOf('.') >= 0) {
275
+					if (!specifiedName.startsWith(pkg.fullName))
276
+						throw new IllegalArgumentException("Specified @Name as \"" + specifiedName + "\" for class: \"" + cls
277
+								.toString() + "\" but it's not in the module root package");
278
+
279
+					classPkg = getPackage(basePackage + specifiedName.substring(pkg.fullName.length()));
280
+					className = specifiedName.substring(specifiedName.lastIndexOf('.') + 1);
281
+				} else {
282
+					classPkg = getPackage(specifiedName);
283
+					className = nameAnnotation.value();
284
+				}
285
+			}
286
+
287
+
288
+			if (cls.isInterface()) {
289
+				definition = new InterfaceDefinition(CodePosition.NATIVE, module, classPkg, className, Modifiers.PUBLIC, null);
290
+				javaClass = JavaClass.fromInternalName(internalName, JavaClass.Kind.INTERFACE);
291
+			} else if (cls.isEnum()) {
292
+				definition = new EnumDefinition(CodePosition.NATIVE, module, classPkg, className, Modifiers.PUBLIC, null);
293
+				javaClass = JavaClass.fromInternalName(internalName, JavaClass.Kind.ENUM);
294
+			} else if (isStruct) {
295
+				definition = new StructDefinition(CodePosition.NATIVE, module, classPkg, className, Modifiers.PUBLIC, null);
296
+				javaClass = JavaClass.fromInternalName(internalName, JavaClass.Kind.CLASS);
297
+			} else {
298
+				definition = new ClassDefinition(CodePosition.NATIVE, module, classPkg, className, Modifiers.PUBLIC);
299
+				javaClass = JavaClass.fromInternalName(internalName, JavaClass.Kind.CLASS);
296
 
300
 
301
+			}
297
 		}
302
 		}
298
 
303
 
299
 		//Moved up here so that circular dependencies are caught (hopefully)
304
 		//Moved up here so that circular dependencies are caught (hopefully)
322
 			typeParameters[i] = parameter;
327
 			typeParameters[i] = parameter;
323
 		}
328
 		}
324
 
329
 
325
-		if (definition instanceof ClassDefinition && cls.getAnnotatedSuperclass() != null && shouldLoadType(cls.getAnnotatedSuperclass().getType())) {
330
+		if (!foundRegistry && definition instanceof ClassDefinition && cls.getAnnotatedSuperclass() != null && shouldLoadType(cls.getAnnotatedSuperclass().getType())) {
326
 			definition.setSuperType(loadType(context, cls.getAnnotatedSuperclass()).type);
331
 			definition.setSuperType(loadType(context, cls.getAnnotatedSuperclass()).type);
327
 		}
332
 		}
328
 
333
 
329
-		if (definition.getSuperType() == null && cls != Object.class) {
334
+		if (!foundRegistry && definition.getSuperType() == null && cls != Object.class) {
330
 			definition.setSuperType(loadType(context, Object.class, false, false).type);
335
 			definition.setSuperType(loadType(context, Object.class, false, false).type);
331
 		}
336
 		}
332
 
337
 
340
 		}
345
 		}
341
 
346
 
342
 		compiled.setClassInfo(definition, javaClass);
347
 		compiled.setClassInfo(definition, javaClass);
343
-		
348
+
344
 		StoredType thisType = new StoredType(registry.getForMyDefinition(definition), AutoStorageTag.INSTANCE);
349
 		StoredType thisType = new StoredType(registry.getForMyDefinition(definition), AutoStorageTag.INSTANCE);
345
 		for (Field field : cls.getDeclaredFields()) {
350
 		for (Field field : cls.getDeclaredFields()) {
346
 			ZenCodeType.Field annotation = field.getAnnotation(ZenCodeType.Field.class);
351
 			ZenCodeType.Field annotation = field.getAnnotation(ZenCodeType.Field.class);
348
 				continue;
353
 				continue;
349
 			if (!isPublic(field.getModifiers()))
354
 			if (!isPublic(field.getModifiers()))
350
 				continue;
355
 				continue;
351
-			
356
+
352
 			final String fieldName = annotation.value().isEmpty() ? field.getName() : annotation.value();
357
 			final String fieldName = annotation.value().isEmpty() ? field.getName() : annotation.value();
353
-			
358
+
354
 			StoredType fieldType = loadStoredType(context, field.getAnnotatedType());
359
 			StoredType fieldType = loadStoredType(context, field.getAnnotatedType());
355
 			FieldMember member = new FieldMember(CodePosition.NATIVE, definition, getMethodModifiers(field), fieldName, thisType, fieldType, registry, 0, 0, null);
360
 			FieldMember member = new FieldMember(CodePosition.NATIVE, definition, getMethodModifiers(field), fieldName, thisType, fieldType, registry, 0, 0, null);
356
 			definition.addMember(member);
361
 			definition.addMember(member);
357
 			compiled.setFieldInfo(member, new JavaField(javaClass, field.getName(), getDescriptor(field.getType())));
362
 			compiled.setFieldInfo(member, new JavaField(javaClass, field.getName(), getDescriptor(field.getType())));
358
 		}
363
 		}
359
-		
364
+
360
 		boolean hasConstructor = false;
365
 		boolean hasConstructor = false;
361
 		for (java.lang.reflect.Constructor<?> constructor : cls.getConstructors()) {
366
 		for (java.lang.reflect.Constructor<?> constructor : cls.getConstructors()) {
362
 			ZenCodeType.Constructor constructorAnnotation = (ZenCodeType.Constructor) constructor.getAnnotation(ZenCodeType.Constructor.class);
367
 			ZenCodeType.Constructor constructorAnnotation = (ZenCodeType.Constructor) constructor.getAnnotation(ZenCodeType.Constructor.class);
367
 				hasConstructor = true;
372
 				hasConstructor = true;
368
 			}
373
 			}
369
 		}
374
 		}
370
-		
371
-		if (!hasConstructor) {
375
+
376
+		if (!hasConstructor && !foundRegistry) {
372
 			// no constructor! make a private constructor so the compiler doesn't add one
377
 			// no constructor! make a private constructor so the compiler doesn't add one
373
 			ConstructorMember member = new ConstructorMember(CodePosition.BUILTIN, definition, Modifiers.PRIVATE, new FunctionHeader(BasicTypeID.VOID), BuiltinID.CLASS_DEFAULT_CONSTRUCTOR);
378
 			ConstructorMember member = new ConstructorMember(CodePosition.BUILTIN, definition, Modifiers.PRIVATE, new FunctionHeader(BasicTypeID.VOID), BuiltinID.CLASS_DEFAULT_CONSTRUCTOR);
374
 			definition.addMember(member);
379
 			definition.addMember(member);
375
 		}
380
 		}
376
-		
381
+
377
 		for (Method method : cls.getDeclaredMethods()) {
382
 		for (Method method : cls.getDeclaredMethods()) {
378
 			ZenCodeType.Method methodAnnotation = method.getAnnotation(ZenCodeType.Method.class);
383
 			ZenCodeType.Method methodAnnotation = method.getAnnotation(ZenCodeType.Method.class);
379
 			if (methodAnnotation != null) {
384
 			if (methodAnnotation != null) {
382
 				compiled.setMethodInfo(member, getMethod(javaClass, method, member.header.getReturnType()));
387
 				compiled.setMethodInfo(member, getMethod(javaClass, method, member.header.getReturnType()));
383
 				continue;
388
 				continue;
384
 			}
389
 			}
385
-			
390
+
386
 			ZenCodeType.Getter getter = method.getAnnotation(ZenCodeType.Getter.class);
391
 			ZenCodeType.Getter getter = method.getAnnotation(ZenCodeType.Getter.class);
387
 			if (getter != null) {
392
 			if (getter != null) {
388
 				GetterMember member = asGetter(context, definition, method, getter);
393
 				GetterMember member = asGetter(context, definition, method, getter);
389
 				definition.addMember(member);
394
 				definition.addMember(member);
390
 				compiled.setMethodInfo(member, getMethod(javaClass, method, member.getType()));
395
 				compiled.setMethodInfo(member, getMethod(javaClass, method, member.getType()));
391
 			}
396
 			}
392
-			
397
+
393
 			ZenCodeType.Setter setter = method.getAnnotation(ZenCodeType.Setter.class);
398
 			ZenCodeType.Setter setter = method.getAnnotation(ZenCodeType.Setter.class);
394
 			if (setter != null) {
399
 			if (setter != null) {
395
 				SetterMember member = asSetter(context, definition, method, setter);
400
 				SetterMember member = asSetter(context, definition, method, setter);
396
 				definition.addMember(member);
401
 				definition.addMember(member);
397
 				compiled.setMethodInfo(member, getMethod(javaClass, method, BasicTypeID.VOID.stored));
402
 				compiled.setMethodInfo(member, getMethod(javaClass, method, BasicTypeID.VOID.stored));
398
 			}
403
 			}
399
-			
404
+
400
 			ZenCodeType.Operator operator = method.getAnnotation(ZenCodeType.Operator.class);
405
 			ZenCodeType.Operator operator = method.getAnnotation(ZenCodeType.Operator.class);
401
 			if (operator != null) {
406
 			if (operator != null) {
402
 				OperatorMember member = asOperator(context, definition, method, operator);
407
 				OperatorMember member = asOperator(context, definition, method, operator);
403
 				definition.addMember(member);
408
 				definition.addMember(member);
404
 				compiled.setMethodInfo(member, getMethod(javaClass, method, member.header.getReturnType()));
409
 				compiled.setMethodInfo(member, getMethod(javaClass, method, member.header.getReturnType()));
405
 			}
410
 			}
406
-			
411
+
407
 			ZenCodeType.Caster caster = method.getAnnotation(ZenCodeType.Caster.class);
412
 			ZenCodeType.Caster caster = method.getAnnotation(ZenCodeType.Caster.class);
408
 			if (caster != null) {
413
 			if (caster != null) {
409
 				CasterMember member = asCaster(context, definition, method, caster);
414
 				CasterMember member = asCaster(context, definition, method, caster);
410
 				definition.addMember(member);
415
 				definition.addMember(member);
411
 				compiled.setMethodInfo(member, getMethod(javaClass, method, member.toType));
416
 				compiled.setMethodInfo(member, getMethod(javaClass, method, member.toType));
412
 			}
417
 			}
413
-			
418
+
414
 			/*if (!annotated) {
419
 			/*if (!annotated) {
415
 				MethodMember member = asMethod(definition, method, null);
420
 				MethodMember member = asMethod(definition, method, null);
416
 				definition.addMember(member);
421
 				definition.addMember(member);
417
 				compiled.setMethodInfo(member, getMethod(javaClass, method, member.header.getReturnType()));
422
 				compiled.setMethodInfo(member, getMethod(javaClass, method, member.header.getReturnType()));
418
 			}*/
423
 			}*/
419
 		}
424
 		}
420
-		
425
+
421
 		return definition;
426
 		return definition;
422
 	}
427
 	}
423
 
428
 
580
 		return null;
585
 		return null;
581
 	}
586
 	}
582
 
587
 
583
-	
588
+
584
 	private boolean shouldLoadType(Type type) {
589
 	private boolean shouldLoadType(Type type) {
585
 		if (type instanceof Class)
590
 		if (type instanceof Class)
586
 			return definitionByClass.containsKey(type) || shouldLoadClass((Class<?>)type);
591
 			return definitionByClass.containsKey(type) || shouldLoadClass((Class<?>)type);
587
 		if (type instanceof ParameterizedType)
592
 		if (type instanceof ParameterizedType)
588
 			return shouldLoadType(((ParameterizedType)type).getRawType());
593
 			return shouldLoadType(((ParameterizedType)type).getRawType());
589
-		
594
+
590
 		return false;
595
 		return false;
591
 	}
596
 	}
592
-	
597
+
593
 	private String getClassName(Class<?> cls) {
598
 	private String getClassName(Class<?> cls) {
594
 	    return cls.isAnnotationPresent(ZenCodeType.Name.class) ? cls.getAnnotation(ZenCodeType.Name.class).value() : cls.getName();
599
 	    return cls.isAnnotationPresent(ZenCodeType.Name.class) ? cls.getAnnotation(ZenCodeType.Name.class).value() : cls.getName();
595
     }
600
     }
597
 	private boolean shouldLoadClass(Class<?> cls) {
602
 	private boolean shouldLoadClass(Class<?> cls) {
598
 	    return isInBasePackage(getClassName(cls));
603
 	    return isInBasePackage(getClassName(cls));
599
     }
604
     }
600
-	
605
+
601
 	private boolean isGetterName(String name) {
606
 	private boolean isGetterName(String name) {
602
 		return name.startsWith("get") || name.startsWith("is") || name.startsWith("has");
607
 		return name.startsWith("get") || name.startsWith("is") || name.startsWith("has");
603
 	}
608
 	}
604
-	
609
+
605
 	private String translateGetterName(String name) {
610
 	private String translateGetterName(String name) {
606
 		if (name.startsWith("get"))
611
 		if (name.startsWith("get"))
607
 			return name.substring(3, 4).toLowerCase() + name.substring(4);
612
 			return name.substring(3, 4).toLowerCase() + name.substring(4);
608
-		
613
+
609
 		return name;
614
 		return name;
610
 	}
615
 	}
611
-	
616
+
612
 	private String translateSetterName(String name) {
617
 	private String translateSetterName(String name) {
613
 		if (name.startsWith("set"))
618
 		if (name.startsWith("set"))
614
 			return name.substring(3, 4).toLowerCase() + name.substring(4);
619
 			return name.substring(3, 4).toLowerCase() + name.substring(4);
615
-		
620
+
616
 		return name;
621
 		return name;
617
 	}
622
 	}
618
-	
623
+
619
 	private ConstructorMember asConstructor(TypeVariableContext context, HighLevelDefinition definition, java.lang.reflect.Constructor method) {
624
 	private ConstructorMember asConstructor(TypeVariableContext context, HighLevelDefinition definition, java.lang.reflect.Constructor method) {
620
 		FunctionHeader header = getHeader(context, method);
625
 		FunctionHeader header = getHeader(context, method);
621
 		return new ConstructorMember(
626
 		return new ConstructorMember(
625
 				header,
630
 				header,
626
 				null);
631
 				null);
627
 	}
632
 	}
628
-	
633
+
629
 	private MethodMember asMethod(TypeVariableContext context, HighLevelDefinition definition, Method method, ZenCodeType.Method annotation) {
634
 	private MethodMember asMethod(TypeVariableContext context, HighLevelDefinition definition, Method method, ZenCodeType.Method annotation) {
630
 		String name = annotation != null && !annotation.value().isEmpty() ? annotation.value() : method.getName();
635
 		String name = annotation != null && !annotation.value().isEmpty() ? annotation.value() : method.getName();
631
 		FunctionHeader header = getHeader(context, method);
636
 		FunctionHeader header = getHeader(context, method);
637
 				header,
642
 				header,
638
 				null);
643
 				null);
639
 	}
644
 	}
640
-	
645
+
641
 	private OperatorMember asOperator(TypeVariableContext context, HighLevelDefinition definition, Method method, ZenCodeType.Operator annotation) {
646
 	private OperatorMember asOperator(TypeVariableContext context, HighLevelDefinition definition, Method method, ZenCodeType.Operator annotation) {
642
 		FunctionHeader header = getHeader(context, method);
647
 		FunctionHeader header = getHeader(context, method);
643
 		if (isStatic(method.getModifiers()))
648
 		if (isStatic(method.getModifiers()))
644
 			throw new IllegalArgumentException("operator method \"" + method.toString() + "\"cannot be static");
649
 			throw new IllegalArgumentException("operator method \"" + method.toString() + "\"cannot be static");
645
-		
650
+
646
 		// TODO: check number of parameters
651
 		// TODO: check number of parameters
647
 		//if (header.parameters.length != annotation.value().parameters)
652
 		//if (header.parameters.length != annotation.value().parameters)
648
-		
653
+
649
 		return new OperatorMember(
654
 		return new OperatorMember(
650
 				CodePosition.NATIVE,
655
 				CodePosition.NATIVE,
651
 				definition,
656
 				definition,
654
 				header,
659
 				header,
655
 				null);
660
 				null);
656
 	}
661
 	}
657
-	
662
+
658
 	private GetterMember asGetter(TypeVariableContext context, HighLevelDefinition definition, Method method, ZenCodeType.Getter annotation) {
663
 	private GetterMember asGetter(TypeVariableContext context, HighLevelDefinition definition, Method method, ZenCodeType.Getter annotation) {
659
 		StoredType type = loadStoredType(context, method.getAnnotatedReturnType());
664
 		StoredType type = loadStoredType(context, method.getAnnotatedReturnType());
660
 		String name = null;
665
 		String name = null;
662
 			name = annotation.value();
667
 			name = annotation.value();
663
 		if (name == null)
668
 		if (name == null)
664
 			name = translateGetterName(method.getName());
669
 			name = translateGetterName(method.getName());
665
-		
670
+
666
 		return new GetterMember(CodePosition.NATIVE, definition, getMethodModifiers(method), name, type, null);
671
 		return new GetterMember(CodePosition.NATIVE, definition, getMethodModifiers(method), name, type, null);
667
 	}
672
 	}
668
-	
673
+
669
 	private SetterMember asSetter(TypeVariableContext context, HighLevelDefinition definition, Method method, ZenCodeType.Setter annotation) {
674
 	private SetterMember asSetter(TypeVariableContext context, HighLevelDefinition definition, Method method, ZenCodeType.Setter annotation) {
670
 		if (method.getParameterCount() != 1)
675
 		if (method.getParameterCount() != 1)
671
 			throw new IllegalArgumentException("Illegal setter: \"" + method.toString() + "\"must have exactly 1 parameter");
676
 			throw new IllegalArgumentException("Illegal setter: \"" + method.toString() + "\"must have exactly 1 parameter");
672
-		
677
+
673
 		StoredType type = loadStoredType(context, method.getAnnotatedParameterTypes()[0]);
678
 		StoredType type = loadStoredType(context, method.getAnnotatedParameterTypes()[0]);
674
 		String name = null;
679
 		String name = null;
675
 		if (annotation != null && !annotation.value().isEmpty())
680
 		if (annotation != null && !annotation.value().isEmpty())
676
 			name = annotation.value();
681
 			name = annotation.value();
677
 		if (name == null)
682
 		if (name == null)
678
 			name = translateSetterName(method.getName());
683
 			name = translateSetterName(method.getName());
679
-		
684
+
680
 		return new SetterMember(CodePosition.NATIVE, definition, getMethodModifiers(method), name, type, null);
685
 		return new SetterMember(CodePosition.NATIVE, definition, getMethodModifiers(method), name, type, null);
681
 	}
686
 	}
682
-	
687
+
683
 	private CasterMember asCaster(TypeVariableContext context, HighLevelDefinition definition, Method method, ZenCodeType.Caster annotation) {
688
 	private CasterMember asCaster(TypeVariableContext context, HighLevelDefinition definition, Method method, ZenCodeType.Caster annotation) {
684
 		boolean implicit = annotation != null && annotation.implicit();
689
 		boolean implicit = annotation != null && annotation.implicit();
685
 		int modifiers = Modifiers.PUBLIC;
690
 		int modifiers = Modifiers.PUBLIC;
686
 		if (implicit)
691
 		if (implicit)
687
 			modifiers |= Modifiers.IMPLICIT;
692
 			modifiers |= Modifiers.IMPLICIT;
688
-		
693
+
689
 		StoredType toType = loadStoredType(context, method.getAnnotatedReturnType());
694
 		StoredType toType = loadStoredType(context, method.getAnnotatedReturnType());
690
 		return new CasterMember(CodePosition.NATIVE, definition, modifiers, toType, null);
695
 		return new CasterMember(CodePosition.NATIVE, definition, modifiers, toType, null);
691
 	}
696
 	}
692
-	
697
+
693
 	private FunctionHeader getHeader(TypeVariableContext context, java.lang.reflect.Constructor constructor) {
698
 	private FunctionHeader getHeader(TypeVariableContext context, java.lang.reflect.Constructor constructor) {
694
 		return getHeader(
699
 		return getHeader(
695
 				context,
700
 				context,
698
 				constructor.getTypeParameters(),
703
 				constructor.getTypeParameters(),
699
 				constructor.getAnnotatedExceptionTypes());
704
 				constructor.getAnnotatedExceptionTypes());
700
 	}
705
 	}
701
-	
706
+
702
 	private FunctionHeader getHeader(TypeVariableContext context, Method method) {
707
 	private FunctionHeader getHeader(TypeVariableContext context, Method method) {
703
 		return getHeader(
708
 		return getHeader(
704
 				context,
709
 				context,
707
 				method.getTypeParameters(),
712
 				method.getTypeParameters(),
708
 				method.getAnnotatedExceptionTypes());
713
 				method.getAnnotatedExceptionTypes());
709
 	}
714
 	}
710
-	
715
+
711
 	protected Expression getDefaultValue(Parameter parameter, StoredType type) {
716
 	protected Expression getDefaultValue(Parameter parameter, StoredType type) {
712
 		if (parameter.isAnnotationPresent(ZenCodeType.Optional.class)) {
717
 		if (parameter.isAnnotationPresent(ZenCodeType.Optional.class)) {
713
 				final String s = parameter.getAnnotation(ZenCodeType.Optional.class).value();
718
 				final String s = parameter.getAnnotation(ZenCodeType.Optional.class).value();
785
 			TypeVariable<Method>[] javaTypeParameters,
790
 			TypeVariable<Method>[] javaTypeParameters,
786
 			AnnotatedType[] exceptionTypes) {
791
 			AnnotatedType[] exceptionTypes) {
787
 		StoredType returnType = javaReturnType == null ? BasicTypeID.VOID.stored : loadStoredType(context, javaReturnType);
792
 		StoredType returnType = javaReturnType == null ? BasicTypeID.VOID.stored : loadStoredType(context, javaReturnType);
788
-		
793
+
789
 
794
 
790
 		TypeParameter[] typeParameters = new TypeParameter[javaTypeParameters.length];
795
 		TypeParameter[] typeParameters = new TypeParameter[javaTypeParameters.length];
791
 		for (int i = 0; i < javaTypeParameters.length; i++) {
796
 		for (int i = 0; i < javaTypeParameters.length; i++) {
798
 
803
 
799
 		for (int i = 0; i < javaTypeParameters.length; i++) {
804
 		for (int i = 0; i < javaTypeParameters.length; i++) {
800
 			TypeVariable<Method> javaTypeParameter = javaTypeParameters[i];
805
 			TypeVariable<Method> javaTypeParameter = javaTypeParameters[i];
801
-			
806
+
802
 			for (AnnotatedType bound : javaTypeParameter.getAnnotatedBounds())
807
 			for (AnnotatedType bound : javaTypeParameter.getAnnotatedBounds())
803
 				typeParameters[i].addBound(new ParameterTypeBound(CodePosition.NATIVE, loadType(context, bound).type));
808
 				typeParameters[i].addBound(new ParameterTypeBound(CodePosition.NATIVE, loadType(context, bound).type));
804
 		}
809
 		}
812
 			Expression defaultValue = getDefaultValue(parameter, type);
817
 			Expression defaultValue = getDefaultValue(parameter, type);
813
 			parameters[i] = new FunctionParameter(type, parameter.getName(), defaultValue, parameter.isVarArgs());
818
 			parameters[i] = new FunctionParameter(type, parameter.getName(), defaultValue, parameter.isVarArgs());
814
 		}
819
 		}
815
-		
820
+
816
 		if (exceptionTypes.length > 1)
821
 		if (exceptionTypes.length > 1)
817
 			throw new IllegalArgumentException("A method can only throw a single exception type!");
822
 			throw new IllegalArgumentException("A method can only throw a single exception type!");
818
-		
823
+
819
 		StoredType thrownType = exceptionTypes.length == 0 ? null : loadStoredType(context, exceptionTypes[0]);
824
 		StoredType thrownType = exceptionTypes.length == 0 ? null : loadStoredType(context, exceptionTypes[0]);
820
 		return new FunctionHeader(typeParameters, returnType, thrownType, AutoStorageTag.INSTANCE, parameters);
825
 		return new FunctionHeader(typeParameters, returnType, thrownType, AutoStorageTag.INSTANCE, parameters);
821
 	}
826
 	}
822
-	
827
+
823
 	private StoredType loadStoredType(TypeVariableContext context, AnnotatedType annotatedType) {
828
 	private StoredType loadStoredType(TypeVariableContext context, AnnotatedType annotatedType) {
824
 		return loadType(context, annotatedType);
829
 		return loadType(context, annotatedType);
825
 	}
830
 	}
831
 			return new StoredType(registry.getOptional(type.type), type.getSpecifiedStorage());
836
 			return new StoredType(registry.getOptional(type.type), type.getSpecifiedStorage());
832
 		return type;
837
 		return type;
833
 	}
838
 	}
834
-	
839
+
835
 	private StoredType loadType(TypeVariableContext context, AnnotatedType annotatedType) {
840
 	private StoredType loadType(TypeVariableContext context, AnnotatedType annotatedType) {
836
 		if (annotatedType.isAnnotationPresent(ZenCodeType.USize.class))
841
 		if (annotatedType.isAnnotationPresent(ZenCodeType.USize.class))
837
 			return BasicTypeID.USIZE.stored;
842
 			return BasicTypeID.USIZE.stored;
838
 		else if (annotatedType.isAnnotationPresent(ZenCodeType.NullableUSize.class))
843
 		else if (annotatedType.isAnnotationPresent(ZenCodeType.NullableUSize.class))
839
 			return registry.getOptional(BasicTypeID.USIZE).stored();
844
 			return registry.getOptional(BasicTypeID.USIZE).stored();
840
-		
845
+
841
 		boolean nullable = annotatedType.isAnnotationPresent(ZenCodeType.Nullable.class);
846
 		boolean nullable = annotatedType.isAnnotationPresent(ZenCodeType.Nullable.class);
842
 		boolean unsigned = annotatedType.isAnnotationPresent(ZenCodeType.Unsigned.class);
847
 		boolean unsigned = annotatedType.isAnnotationPresent(ZenCodeType.Unsigned.class);
843
-		
848
+
844
 		return loadType(context, annotatedType, nullable, unsigned);
849
 		return loadType(context, annotatedType, nullable, unsigned);
845
 	}
850
 	}
846
-	
851
+
847
 	private StoredType loadType(TypeVariableContext context, AnnotatedElement type, boolean nullable, boolean unsigned) {
852
 	private StoredType loadType(TypeVariableContext context, AnnotatedElement type, boolean nullable, boolean unsigned) {
848
 		StoredType result = loadType(context, type, unsigned);
853
 		StoredType result = loadType(context, type, unsigned);
849
 		if (nullable)
854
 		if (nullable)
850
 			result = new StoredType(registry.getOptional(result.type), result.getSpecifiedStorage());
855
 			result = new StoredType(registry.getOptional(result.type), result.getSpecifiedStorage());
851
-		
856
+
852
 		return result;
857
 		return result;
853
 	}
858
 	}
854
-	
859
+
855
 	@SuppressWarnings("ChainOfInstanceofChecks")
860
 	@SuppressWarnings("ChainOfInstanceofChecks")
856
     private StoredType loadType(TypeVariableContext context, AnnotatedElement type, boolean unsigned) {
861
     private StoredType loadType(TypeVariableContext context, AnnotatedElement type, boolean unsigned) {
857
 		if (type instanceof Class) {
862
 		if (type instanceof Class) {
867
 			} else if (classType.isAnnotationPresent(FunctionalInterface.class)) {
872
 			} else if (classType.isAnnotationPresent(FunctionalInterface.class)) {
868
 				return loadFunctionalInterface(context, classType, new AnnotatedElement[0]);
873
 				return loadFunctionalInterface(context, classType, new AnnotatedElement[0]);
869
 			}
874
 			}
870
-			
875
+
871
 			if (typeByClass.containsKey(classType))
876
 			if (typeByClass.containsKey(classType))
872
 				return typeByClass.get(classType).stored();
877
 				return typeByClass.get(classType).stored();
873
-			
878
+
874
 			HighLevelDefinition definition = addClass(classType);
879
 			HighLevelDefinition definition = addClass(classType);
875
 			final List<StoredType> s = new ArrayList<>();
880
 			final List<StoredType> s = new ArrayList<>();
876
 			for (TypeVariable<? extends Class<?>> typeParameter : classType.getTypeParameters()) {
881
 			for (TypeVariable<? extends Class<?>> typeParameter : classType.getTypeParameters()) {
883
 			Class<?> rawType = (Class<?>) parameterizedType.getRawType();
888
 			Class<?> rawType = (Class<?>) parameterizedType.getRawType();
884
 			if (rawType.isAnnotationPresent(FunctionalInterface.class))
889
 			if (rawType.isAnnotationPresent(FunctionalInterface.class))
885
 				return loadFunctionalInterface(context, rawType, (AnnotatedElement[]) parameterizedType.getActualTypeArguments());
890
 				return loadFunctionalInterface(context, rawType, (AnnotatedElement[]) parameterizedType.getActualTypeArguments());
886
-			
891
+
887
 			Type[] parameters = parameterizedType.getActualTypeArguments();
892
 			Type[] parameters = parameterizedType.getActualTypeArguments();
888
 			StoredType[] codeParameters = new StoredType[parameters.length];
893
 			StoredType[] codeParameters = new StoredType[parameters.length];
889
 			for (int i = 0; i < parameters.length; i++)
894
 			for (int i = 0; i < parameters.length; i++)
890
 			    codeParameters[i] = loadType(context, (AnnotatedElement) parameters[i], false, false);
895
 			    codeParameters[i] = loadType(context, (AnnotatedElement) parameters[i], false, false);
891
-       
896
+
892
 			if(rawType == Map.class) {
897
 			if(rawType == Map.class) {
893
                 return registry.getAssociative(codeParameters[0], codeParameters[1]).stored();
898
                 return registry.getAssociative(codeParameters[0], codeParameters[1]).stored();
894
             }
899
             }
895
-            
900
+
896
             HighLevelDefinition definition = addClass(rawType);
901
             HighLevelDefinition definition = addClass(rawType);
897
             return registry.getForDefinition(definition, codeParameters).stored();
902
             return registry.getForDefinition(definition, codeParameters).stored();
898
 		} else if (type instanceof TypeVariable<?>) {
903
 		} else if (type instanceof TypeVariable<?>) {
909
                 for(int i = 0; i < actualTypeArguments.length; i++) {
914
                 for(int i = 0; i < actualTypeArguments.length; i++) {
910
                     codeParameters[i] = loadType(context, actualTypeArguments[i], false, false);
915
                     codeParameters[i] = loadType(context, actualTypeArguments[i], false, false);
911
                 }
916
                 }
912
-            
917
+
913
                 if(rawType == Map.class) {
918
                 if(rawType == Map.class) {
914
                     storedType = registry.getAssociative(codeParameters[0], codeParameters[1]).stored();
919
                     storedType = registry.getAssociative(codeParameters[0], codeParameters[1]).stored();
915
                 } else if(rawType instanceof Class<?>){
920
                 } else if(rawType instanceof Class<?>){
931
 					storedType = loadType(context, (AnnotatedElement) ((AnnotatedType) type).getType(), unsigned);
936
 					storedType = loadType(context, (AnnotatedElement) ((AnnotatedType) type).getType(), unsigned);
932
 				}
937
 				}
933
             }
938
             }
934
-            
939
+
935
 		    if(type.isAnnotationPresent(ZenCodeStorageTag.class)) {
940
 		    if(type.isAnnotationPresent(ZenCodeStorageTag.class)) {
936
 		        //Replace with switch if more StorageTagTypes are added
941
 		        //Replace with switch if more StorageTagTypes are added
937
                 if(type.getAnnotation(ZenCodeStorageTag.class).value() == StorageTagType.STATIC) {
942
                 if(type.getAnnotation(ZenCodeStorageTag.class).value() == StorageTagType.STATIC) {
939
                 }
944
                 }
940
             }
945
             }
941
 		    return storedType;
946
 		    return storedType;
942
-		    
947
+
943
         } else {
948
         } else {
944
 			throw new IllegalArgumentException("Could not analyze type: " + type);
949
 			throw new IllegalArgumentException("Could not analyze type: " + type);
945
 		}
950
 		}
946
 	}
951
 	}
947
-	
952
+
948
 	private StoredType loadFunctionalInterface(TypeVariableContext loadContext, Class<?> cls, AnnotatedElement[] parameters) {
953
 	private StoredType loadFunctionalInterface(TypeVariableContext loadContext, Class<?> cls, AnnotatedElement[] parameters) {
949
 		Method functionalInterfaceMethod = getFunctionalInterfaceMethod(cls);
954
 		Method functionalInterfaceMethod = getFunctionalInterfaceMethod(cls);
950
 		TypeVariableContext context = convertTypeParameters(cls);
955
 		TypeVariableContext context = convertTypeParameters(cls);
951
 		FunctionHeader header = getHeader(context, functionalInterfaceMethod);
956
 		FunctionHeader header = getHeader(context, functionalInterfaceMethod);
952
-		
957
+
953
 		Map<TypeParameter, StoredType> mapping = new HashMap<>();
958
 		Map<TypeParameter, StoredType> mapping = new HashMap<>();
954
 		TypeVariable[] javaParameters = cls.getTypeParameters();
959
 		TypeVariable[] javaParameters = cls.getTypeParameters();
955
 		for (int i = 0; i < parameters.length; i++)
960
 		for (int i = 0; i < parameters.length; i++)
956
 			mapping.put(context.get(javaParameters[i]), loadType(loadContext, parameters[i], false, false));
961
 			mapping.put(context.get(javaParameters[i]), loadType(loadContext, parameters[i], false, false));
957
-		
962
+
958
 		JavaMethod method = new JavaMethod(
963
 		JavaMethod method = new JavaMethod(
959
 				JavaClass.fromInternalName(getInternalName(cls), JavaClass.Kind.INTERFACE),
964
 				JavaClass.fromInternalName(getInternalName(cls), JavaClass.Kind.INTERFACE),
960
 				JavaMethod.Kind.INTERFACE,
965
 				JavaMethod.Kind.INTERFACE,
966
 		StorageTag tag = new JavaFunctionalInterfaceStorageTag(functionalInterfaceMethod, method);
971
 		StorageTag tag = new JavaFunctionalInterfaceStorageTag(functionalInterfaceMethod, method);
967
 		return registry.getFunction(header).stored(tag);
972
 		return registry.getFunction(header).stored(tag);
968
 	}
973
 	}
969
-	
974
+
970
 	private <T> TypeVariableContext convertTypeParameters(Class<T> cls) {
975
 	private <T> TypeVariableContext convertTypeParameters(Class<T> cls) {
971
 		//TypeVariableContext context = new TypeVariableContext();
976
 		//TypeVariableContext context = new TypeVariableContext();
972
 		TypeVariable<Class<T>>[] javaTypeParameters = cls.getTypeParameters();
977
 		TypeVariable<Class<T>>[] javaTypeParameters = cls.getTypeParameters();
989
 		}
994
 		}
990
 		return context;
995
 		return context;
991
 	}
996
 	}
992
-	
997
+
993
 	private Method getFunctionalInterfaceMethod(Class<?> functionalInterface) {
998
 	private Method getFunctionalInterfaceMethod(Class<?> functionalInterface) {
994
 		for (Method method : functionalInterface.getDeclaredMethods()) {
999
 		for (Method method : functionalInterface.getDeclaredMethods()) {
995
 			if (!method.isDefault())
1000
 			if (!method.isDefault())
996
 				return method;
1001
 				return method;
997
 		}
1002
 		}
998
-		
1003
+
999
 		return null;
1004
 		return null;
1000
 	}
1005
 	}
1001
-	
1006
+
1002
 	private int getMethodModifiers(Member method) {
1007
 	private int getMethodModifiers(Member method) {
1003
 		int result = Modifiers.PUBLIC;
1008
 		int result = Modifiers.PUBLIC;
1004
 		if (isStatic(method.getModifiers()))
1009
 		if (isStatic(method.getModifiers()))
1005
 			result |= Modifiers.STATIC;
1010
 			result |= Modifiers.STATIC;
1006
 		if (isFinal(method.getModifiers()))
1011
 		if (isFinal(method.getModifiers()))
1007
 			result |= Modifiers.FINAL;
1012
 			result |= Modifiers.FINAL;
1008
-		
1013
+
1009
 		return result;
1014
 		return result;
1010
 	}
1015
 	}
1011
-	
1016
+
1012
 	private static boolean isPublic(int modifiers) {
1017
 	private static boolean isPublic(int modifiers) {
1013
 		return (modifiers & Modifier.PUBLIC) > 0;
1018
 		return (modifiers & Modifier.PUBLIC) > 0;
1014
 	}
1019
 	}
1015
-	
1020
+
1016
 	private static boolean isStatic(int modifiers) {
1021
 	private static boolean isStatic(int modifiers) {
1017
 		return (modifiers & Modifier.STATIC) > 0;
1022
 		return (modifiers & Modifier.STATIC) > 0;
1018
 	}
1023
 	}
1019
-	
1024
+
1020
 	private static boolean isFinal(int modifiers) {
1025
 	private static boolean isFinal(int modifiers) {
1021
 		return (modifiers & Modifier.FINAL) > 0;
1026
 		return (modifiers & Modifier.FINAL) > 0;
1022
 	}
1027
 	}
1023
-	
1028
+
1024
 	private static String getInternalName(Class<?> cls) {
1029
 	private static String getInternalName(Class<?> cls) {
1025
 		return org.objectweb.asm.Type.getInternalName(cls);
1030
 		return org.objectweb.asm.Type.getInternalName(cls);
1026
 	}
1031
 	}
1027
-	
1032
+
1028
 	private static String getDescriptor(Class<?> cls) {
1033
 	private static String getDescriptor(Class<?> cls) {
1029
 		return org.objectweb.asm.Type.getDescriptor(cls);
1034
 		return org.objectweb.asm.Type.getDescriptor(cls);
1030
 	}
1035
 	}
1031
-	
1036
+
1032
 	private static String getMethodDescriptor(java.lang.reflect.Constructor constructor) {
1037
 	private static String getMethodDescriptor(java.lang.reflect.Constructor constructor) {
1033
 		return org.objectweb.asm.Type.getConstructorDescriptor(constructor);
1038
 		return org.objectweb.asm.Type.getConstructorDescriptor(constructor);
1034
 	}
1039
 	}
1035
-	
1040
+
1036
 	private static String getMethodDescriptor(Method method) {
1041
 	private static String getMethodDescriptor(Method method) {
1037
 		return org.objectweb.asm.Type.getMethodDescriptor(method);
1042
 		return org.objectweb.asm.Type.getMethodDescriptor(method);
1038
 	}
1043
 	}
1039
-	
1044
+
1040
 	private static JavaMethod getMethod(JavaClass cls, java.lang.reflect.Constructor constructor) {
1045
 	private static JavaMethod getMethod(JavaClass cls, java.lang.reflect.Constructor constructor) {
1041
 		return new JavaMethod(
1046
 		return new JavaMethod(
1042
 				cls,
1047
 				cls,
1047
 				constructor.getModifiers(),
1052
 				constructor.getModifiers(),
1048
 				false);
1053
 				false);
1049
 	}
1054
 	}
1050
-	
1055
+
1051
 	private static JavaMethod getMethod(JavaClass cls, Method method, StoredType result) {
1056
 	private static JavaMethod getMethod(JavaClass cls, Method method, StoredType result) {
1052
 		JavaMethod.Kind kind;
1057
 		JavaMethod.Kind kind;
1053
 		if (method.getName().equals("<init>"))
1058
 		if (method.getName().equals("<init>"))
1058
 			kind = JavaMethod.Kind.STATIC;
1063
 			kind = JavaMethod.Kind.STATIC;
1059
 		else
1064
 		else
1060
 			kind = JavaMethod.Kind.INSTANCE;
1065
 			kind = JavaMethod.Kind.INSTANCE;
1061
-		
1066
+
1062
 		return new JavaMethod(cls, kind, method.getName(), false, getMethodDescriptor(method), method.getModifiers(), result.isGeneric());
1067
 		return new JavaMethod(cls, kind, method.getName(), false, getMethodDescriptor(method), method.getModifiers(), result.isGeneric());
1063
 	}
1068
 	}
1064
 
1069
 
1068
 
1073
 
1069
 	private static class TypeVariableContext {
1074
 	private static class TypeVariableContext {
1070
 		private final Map<TypeVariable, TypeParameter> typeVariables = new HashMap<>();
1075
 		private final Map<TypeVariable, TypeParameter> typeVariables = new HashMap<>();
1071
-		
1076
+
1072
 		public void put(TypeVariable variable, TypeParameter parameter) {
1077
 		public void put(TypeVariable variable, TypeParameter parameter) {
1073
 			typeVariables.put(variable, parameter);
1078
 			typeVariables.put(variable, parameter);
1074
 		}
1079
 		}
1075
-		
1080
+
1076
 		public TypeParameter get(TypeVariable variable) {
1081
 		public TypeParameter get(TypeVariable variable) {
1077
 			if (!typeVariables.containsKey(variable))
1082
 			if (!typeVariables.containsKey(variable))
1078
 				throw new IllegalStateException("Could not find type variable " + variable.getName());
1083
 				throw new IllegalStateException("Could not find type variable " + variable.getName());
1079
-			
1084
+
1080
 			return typeVariables.get(variable);
1085
 			return typeVariables.get(variable);
1081
 		}
1086
 		}
1082
 	}
1087
 	}

Loading…
Cancel
Save