org.babyfish.jimmer.dto.compiler.Importing Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jimmer-dto-compiler Show documentation
Show all versions of jimmer-dto-compiler Show documentation
A revolutionary ORM framework for both java and kotlin
package org.babyfish.jimmer.dto.compiler;
import org.antlr.v4.runtime.Token;
import java.util.*;
import java.util.stream.Collectors;
class Importing {
private static final Set AUTO_IMPORTED_TYPES;
private static final Map STANDARD_TYPES;
private static final Map ILLEGAL_TYPES;
private final CompilerContext, ?> ctx;
private final Map typeMap = new HashMap<>();
Importing(CompilerContext, ?> ctx) {
this.ctx = ctx;
}
public void add(DtoParser.ImportStatementContext ctx) {
String path = ctx.parts.stream().map(Token::getText).collect(Collectors.joining("."));
if (ctx.alias != null) {
Token lastPart = ctx.parts.get(ctx.parts.size() - 1);
add0(ctx.alias, path, lastPart.getLine(), lastPart.getCharPositionInLine());
} else if (!ctx.importedTypes.isEmpty()) {
for (DtoParser.ImportedTypeContext importedType : ctx.importedTypes) {
add0(
importedType.alias != null ? importedType.alias : importedType.name,
path + '.' + importedType.name.getText(),
importedType.name.getLine(),
importedType.name.getCharPositionInLine()
);
}
} else {
Token lastPart = ctx.parts.get(ctx.parts.size() - 1);
add0(lastPart, path, lastPart.getLine(), lastPart.getCharPositionInLine());
}
}
private void add0(Token alias, String qualifiedName, int qualifiedNameLine, int qualifiedNameCol) {
if (AUTO_IMPORTED_TYPES.contains(qualifiedName)) {
throw ctx.exception(
qualifiedNameLine,
qualifiedNameCol,
"\"" +
qualifiedName +
"\" cannot be imported because it is built-in type"
);
}
if (typeMap.put(alias.getText(), qualifiedName) != null) {
throw ctx.exception(
alias.getLine(),
alias.getCharPositionInLine(),
"Duplicated imported alias \"" +
alias.getText() +
"\""
);
}
}
public TypeRef resolve(DtoParser.TypeRefContext ctx, DtoCompiler, ?> compiler) {
String name = resolve(ctx.qualifiedName());
Integer expectedArgumentCount = STANDARD_TYPES.get(name);
if (expectedArgumentCount == null) {
expectedArgumentCount = compiler.getGenericTypeCount(name);
if (expectedArgumentCount == null) {
throw this.ctx.exception(
ctx.qualifiedName().stop.getLine(),
ctx.qualifiedName().stop.getCharPositionInLine(),
"Illegal type \"" +
ctx.getText() +
"\", it cannot be found"
);
}
}
if (expectedArgumentCount != ctx.genericArguments.size()) {
throw this.ctx.exception(
ctx.qualifiedName().stop.getLine(),
ctx.qualifiedName().stop.getCharPositionInLine(),
"Illegal type \"" +
ctx.getText() +
"\", the expected generic argument count is " +
expectedArgumentCount +
", but the actual generic argument count is " +
ctx.genericArguments.size()
);
}
List arguments = null;
if (!ctx.genericArguments.isEmpty()) {
arguments = new ArrayList<>(ctx.genericArguments.size());
for (DtoParser.GenericArgumentContext arg : ctx.genericArguments) {
if (arg.wildcard != null) {
arguments.add(
new TypeRef.Argument(
null,
false,
false
)
);
} else {
boolean in = false;
boolean out = false;
if (arg.modifier != null) {
switch (arg.modifier.getText()) {
case "in":
in = true;
break;
case "out":
out = true;
break;
default:
throw this.ctx.exception(
arg.modifier.getLine(),
arg.modifier.getCharPositionInLine(),
"The generic argument modifier is neither \"in\" nor \"out\""
);
}
if (expectedArgumentCount != null) {
throw this.ctx.exception(
arg.modifier.getLine(),
arg.modifier.getCharPositionInLine(),
"The modifier \"" +
arg.modifier.getText() +
"\" of the generic argument of standard collection cannot be specified"
);
}
}
TypeRef bound = resolve(arg.typeRef(), compiler);
arguments.add(
new TypeRef.Argument(
bound,
in,
out
)
);
}
}
}
return new TypeRef(
name,
arguments,
ctx.optional != null,
ctx.stop.getLine(),
ctx.stop.getCharPositionInLine()
);
}
public String resolve(DtoParser.QualifiedNameContext ctx) {
String qualifiedName = ctx.parts.stream().map(Token::getText).collect(Collectors.joining("."));
return resolve(qualifiedName, ctx.stop.getLine(), ctx.stop.getCharPositionInLine());
}
public String resolve(String qualifiedName, int qualifiedNameLine, int qualifiedNameCol) {
if (STANDARD_TYPES.containsKey(qualifiedName)) {
return qualifiedName;
}
String suggested = ILLEGAL_TYPES.get(qualifiedName);
if (suggested != null) {
throw this.ctx.exception(
qualifiedNameLine,
qualifiedNameCol,
"Illegal type \"" +
qualifiedName +
"\", please use \"" +
suggested +
"\""
);
}
String imported;
int index = qualifiedName.indexOf('.');
if (index == -1) {
imported = typeMap.get(qualifiedName);
} else {
imported = typeMap.get(qualifiedName.substring(0, index));
if (imported != null) {
imported += qualifiedName.substring(index);
}
}
if (imported != null) {
return imported;
}
if (Character.isLowerCase(qualifiedName.charAt(0))) {
return qualifiedName;
}
String pkg = this.ctx.getBaseType().getPackageName();
if (pkg.isEmpty()) {
return qualifiedName;
}
return pkg + '.' + qualifiedName;
}
static {
Set autoImportedTypes = new HashSet<>();
autoImportedTypes.add(void.class.getName());
autoImportedTypes.add(boolean.class.getName());
autoImportedTypes.add(char.class.getName());
autoImportedTypes.add(byte.class.getName());
autoImportedTypes.add(short.class.getName());
autoImportedTypes.add(int.class.getName());
autoImportedTypes.add(long.class.getName());
autoImportedTypes.add(float.class.getName());
autoImportedTypes.add(double.class.getName());
autoImportedTypes.add(Boolean.class.getName());
autoImportedTypes.add(Character.class.getName());
autoImportedTypes.add(Void.class.getName());
autoImportedTypes.add(Byte.class.getName());
autoImportedTypes.add(Short.class.getName());
autoImportedTypes.add(Integer.class.getName());
autoImportedTypes.add(Long.class.getName());
autoImportedTypes.add(Float.class.getName());
autoImportedTypes.add(Double.class.getName());
autoImportedTypes.add(Object.class.getName());
autoImportedTypes.add(String.class.getName());
autoImportedTypes.add(Iterable.class.getName());
autoImportedTypes.add(Collection.class.getName());
autoImportedTypes.add(List.class.getName());
autoImportedTypes.add(Set.class.getName());
autoImportedTypes.add(Map.class.getName());
autoImportedTypes.add("kotlin.Unit");
autoImportedTypes.add("kotlin.Boolean");
autoImportedTypes.add("kotlin.Char");
autoImportedTypes.add("kotlin.Byte");
autoImportedTypes.add("kotlin.Short");
autoImportedTypes.add("kotlin.Int");
autoImportedTypes.add("kotlin.Long");
autoImportedTypes.add("kotlin.Float");
autoImportedTypes.add("kotlin.Double");
autoImportedTypes.add("kotlin.Any");
autoImportedTypes.add("kotlin.String");
autoImportedTypes.add("kotlin.Array");
autoImportedTypes.add("kotlin.BooleanArray");
autoImportedTypes.add("kotlin.CharArray");
autoImportedTypes.add("kotlin.ByteArray");
autoImportedTypes.add("kotlin.ShortArray");
autoImportedTypes.add("kotlin.IntArray");
autoImportedTypes.add("kotlin.LongArray");
autoImportedTypes.add("kotlin.FloatArray");
autoImportedTypes.add("kotlin.DoubleArray");
autoImportedTypes.add("kotlin.collections.Iterable");
autoImportedTypes.add("kotlin.collections.Collection");
autoImportedTypes.add("kotlin.collections.List");
autoImportedTypes.add("kotlin.collections.Set");
autoImportedTypes.add("kotlin.collections.Map");
autoImportedTypes.add("kotlin.collections.MutableIterable");
autoImportedTypes.add("kotlin.collections.MutableCollection");
autoImportedTypes.add("kotlin.collections.MutableList");
autoImportedTypes.add("kotlin.collections.MutableSet");
autoImportedTypes.add("kotlin.collections.MutableMap");
AUTO_IMPORTED_TYPES = autoImportedTypes;
Map standardTypes = new HashMap<>();
standardTypes.put(TypeRef.TN_BOOLEAN, 0);
standardTypes.put(TypeRef.TN_CHAR, 0);
standardTypes.put(TypeRef.TN_BYTE, 0);
standardTypes.put(TypeRef.TN_SHORT, 0);
standardTypes.put(TypeRef.TN_INT, 0);
standardTypes.put(TypeRef.TN_LONG, 0);
standardTypes.put(TypeRef.TN_FLOAT, 0);
standardTypes.put(TypeRef.TN_DOUBLE, 0);
standardTypes.put(TypeRef.TN_ANY, 0);
standardTypes.put(TypeRef.TN_STRING, 0);
standardTypes.put(TypeRef.TN_ARRAY, 1);
standardTypes.put(TypeRef.TN_ITERABLE, 1);
standardTypes.put(TypeRef.TN_MUTABLE_ITERABLE, 1);
standardTypes.put(TypeRef.TN_COLLECTION, 1);
standardTypes.put(TypeRef.TN_MUTABLE_COLLECTION, 1);
standardTypes.put(TypeRef.TN_LIST, 1);
standardTypes.put(TypeRef.TN_MUTABLE_LIST, 1);
standardTypes.put(TypeRef.TN_SET, 1);
standardTypes.put(TypeRef.TN_MUTABLE_SET, 1);
standardTypes.put(TypeRef.TN_MAP, 2);
standardTypes.put(TypeRef.TN_MUTABLE_MAP, 2);
STANDARD_TYPES = standardTypes;
Map illegalTypes = new HashMap<>();
illegalTypes.put("boolean", TypeRef.TN_BOOLEAN);
illegalTypes.put(Boolean.class.getName(), TypeRef.TN_BOOLEAN + '?');
illegalTypes.put("kotlin.Boolean", TypeRef.TN_BOOLEAN);
illegalTypes.put("char", TypeRef.TN_CHAR);
illegalTypes.put(Character.class.getName(), TypeRef.TN_CHAR + '?');
illegalTypes.put(Character.class.getSimpleName(), TypeRef.TN_CHAR + '?');
illegalTypes.put("kotlin.Char", TypeRef.TN_CHAR);
illegalTypes.put("byte", TypeRef.TN_BYTE);
illegalTypes.put(Byte.class.getName(), TypeRef.TN_BYTE + '?');
illegalTypes.put("kotlin.Byte", TypeRef.TN_BYTE);
illegalTypes.put("short", TypeRef.TN_SHORT);
illegalTypes.put(Short.class.getName(), TypeRef.TN_SHORT + '?');
illegalTypes.put("kotlin.Short", TypeRef.TN_SHORT);
illegalTypes.put("int", TypeRef.TN_INT);
illegalTypes.put(Integer.class.getName(), TypeRef.TN_INT + '?');
illegalTypes.put(Integer.class.getSimpleName(), TypeRef.TN_INT + '?');
illegalTypes.put("kotlin.Int", TypeRef.TN_INT);
illegalTypes.put("long", TypeRef.TN_LONG);
illegalTypes.put(Long.class.getName(), TypeRef.TN_LONG + '?');
illegalTypes.put("kotlin.Long", TypeRef.TN_LONG);
illegalTypes.put("float", TypeRef.TN_FLOAT);
illegalTypes.put(Float.class.getName(), TypeRef.TN_FLOAT + '?');
illegalTypes.put("kotlin.Float", TypeRef.TN_FLOAT);
illegalTypes.put("double", TypeRef.TN_DOUBLE);
illegalTypes.put(Double.class.getName(), TypeRef.TN_DOUBLE + '?');
illegalTypes.put("kotlin.Double", TypeRef.TN_DOUBLE);
illegalTypes.put("string", TypeRef.TN_STRING);
illegalTypes.put(String.class.getName(), TypeRef.TN_STRING);
illegalTypes.put("kotlin.String", TypeRef.TN_STRING);
illegalTypes.put("kotlin.Array", TypeRef.TN_ARRAY);
illegalTypes.put("kotlin.BooleanArray", TypeRef.TN_ARRAY + "");
illegalTypes.put("kotlin.CharArray", TypeRef.TN_ARRAY + "");
illegalTypes.put("kotlin.ByteArray", TypeRef.TN_ARRAY + "");
illegalTypes.put("kotlin.ShortArray", TypeRef.TN_ARRAY + "");
illegalTypes.put("kotlin.IntArray", TypeRef.TN_ARRAY + "");
illegalTypes.put("kotlin.LongArray", TypeRef.TN_ARRAY + "");
illegalTypes.put("kotlin.FloatArray", TypeRef.TN_ARRAY + "");
illegalTypes.put("kotlin.DoubleArray", TypeRef.TN_ARRAY + "");
illegalTypes.put(Iterable.class.getName(), TypeRef.TN_ITERABLE + '/' + TypeRef.TN_MUTABLE_ITERABLE);
illegalTypes.put("kotlin.collections.Iterable", TypeRef.TN_ITERABLE);
illegalTypes.put("kotlin.collections.MutableIterable", TypeRef.TN_MUTABLE_ITERABLE);
illegalTypes.put(Collection.class.getName(), TypeRef.TN_COLLECTION + '/' + TypeRef.TN_MUTABLE_COLLECTION);
illegalTypes.put("kotlin.collections.Collection", TypeRef.TN_COLLECTION);
illegalTypes.put("kotlin.collections.MutableCollection", TypeRef.TN_MUTABLE_COLLECTION);
illegalTypes.put(List.class.getName(), TypeRef.TN_LIST + '/' + TypeRef.TN_MUTABLE_LIST);
illegalTypes.put("kotlin.collections.List", TypeRef.TN_LIST);
illegalTypes.put("kotlin.collections.MutableList", TypeRef.TN_MUTABLE_LIST);
illegalTypes.put(Set.class.getName(), TypeRef.TN_SET + '/' + TypeRef.TN_MUTABLE_SET);
illegalTypes.put("kotlin.collections.Set", TypeRef.TN_SET);
illegalTypes.put("kotlin.collections.MutableSet", TypeRef.TN_MUTABLE_SET);
illegalTypes.put(Map.class.getName(), TypeRef.TN_MAP + '/' + TypeRef.TN_MUTABLE_MAP);
illegalTypes.put("kotlin.collections.Map", TypeRef.TN_MAP);
illegalTypes.put("kotlin.collections.MutableMap", TypeRef.TN_MUTABLE_MAP);
ILLEGAL_TYPES = illegalTypes;
}
}