package scotch.util; import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static java.util.stream.Collectors.toList; import static scotch.compiler.Compiler.compiler; import static scotch.compiler.syntax.reference.DefinitionReference.moduleRef; import static scotch.compiler.text.SourceLocation.NULL_SOURCE; import static scotch.symbol.Symbol.symbol; import static scotch.compiler.syntax.type.Types.sum; import java.util.List; import java.util.Optional; import scotch.compiler.ClassLoaderResolver; import scotch.compiler.output.GeneratedClass; import scotch.compiler.syntax.definition.ClassDefinition; import scotch.compiler.syntax.definition.DataConstructorDefinition; import scotch.compiler.syntax.definition.DataFieldDefinition; import scotch.compiler.syntax.definition.DataTypeDefinition; import scotch.compiler.syntax.definition.Definitions; import scotch.compiler.syntax.definition.Import; import scotch.compiler.syntax.definition.ModuleImport; import scotch.compiler.syntax.definition.OperatorDefinition; import scotch.compiler.syntax.definition.RootDefinition; import scotch.compiler.syntax.definition.UnshuffledDefinition; import scotch.compiler.syntax.definition.ValueDefinition; import scotch.compiler.syntax.pattern.CaptureMatch; import scotch.compiler.syntax.pattern.EqualMatch; import scotch.compiler.syntax.pattern.IgnorePattern; import scotch.compiler.syntax.pattern.PatternCase; import scotch.compiler.syntax.pattern.PatternMatch; import scotch.compiler.syntax.pattern.Patterns; import scotch.compiler.syntax.pattern.StructField; import scotch.compiler.syntax.pattern.StructMatch; import scotch.compiler.syntax.pattern.UnshuffledStructMatch; import scotch.compiler.syntax.reference.ClassReference; import scotch.compiler.syntax.reference.DataReference; import scotch.compiler.syntax.reference.DefinitionReference; import scotch.compiler.syntax.reference.InstanceReference; import scotch.compiler.syntax.reference.OperatorReference; import scotch.compiler.syntax.reference.ScopeReference; import scotch.compiler.syntax.reference.SignatureReference; import scotch.compiler.syntax.reference.ValueReference; import scotch.compiler.syntax.value.Accessor; import scotch.compiler.syntax.value.Argument; import scotch.compiler.syntax.value.BoolLiteral; import scotch.compiler.syntax.value.CharLiteral; import scotch.compiler.syntax.value.Conditional; import scotch.compiler.syntax.value.DataConstructor; import scotch.compiler.syntax.value.DoubleLiteral; import scotch.compiler.syntax.value.FunctionValue; import scotch.compiler.syntax.value.Identifier; import scotch.compiler.syntax.value.Initializer; import scotch.compiler.syntax.value.InitializerField; import scotch.compiler.syntax.value.Instance; import scotch.compiler.syntax.value.IntLiteral; import scotch.compiler.syntax.value.IsConstructor; import scotch.compiler.syntax.value.Let; import scotch.compiler.syntax.value.PatternMatcher; import scotch.compiler.syntax.value.Raise; import scotch.compiler.syntax.value.StringLiteral; import scotch.compiler.syntax.value.UnshuffledValue; import scotch.compiler.syntax.value.Value; import scotch.compiler.syntax.value.ValueScope; import scotch.compiler.syntax.value.Values; import scotch.symbol.FieldSignature; import scotch.symbol.MethodSignature; import scotch.symbol.Symbol; import scotch.symbol.Value.Fixity; import scotch.symbol.descriptor.DataConstructorDescriptor; import scotch.symbol.descriptor.DataFieldDescriptor; import scotch.symbol.descriptor.DataTypeDescriptor; import scotch.symbol.descriptor.TypeClassDescriptor; import scotch.symbol.descriptor.TypeInstanceDescriptor; import scotch.symbol.descriptor.TypeParameterDescriptor; import scotch.compiler.syntax.type.Type; public class TestUtil { public static Accessor access(Value target, String field, Type type) { return Values.access(NULL_SOURCE, target, field, type, Optional.empty()); } public static Accessor access(Value target, String field, Type type, String tag) { return Values.access(NULL_SOURCE, target, field, type, Optional.of(symbol(tag))); } public static Argument arg(String name, Type type) { return Values.arg(NULL_SOURCE, name, type, Optional.empty()); } public static Argument arg(String name, Type type, String tag) { return Values.arg(NULL_SOURCE, name, type, Optional.of(symbol(tag))); } public static Type boolType() { return sum("scotch.data.bool.Bool"); } public static CaptureMatch capture(String name, Type type) { return Patterns.capture(NULL_SOURCE, Optional.empty(), symbol(name), type); } public static CaptureMatch capture(Value argument, String name, Type type) { return Patterns.capture(NULL_SOURCE, Optional.of(argument), symbol(name), type); } public static ClassDefinition classDef(String name, List<Type> arguments, List<DefinitionReference> members) { return Definitions.classDef(NULL_SOURCE, symbol(name), arguments, members); } public static ClassReference classRef(String className) { return DefinitionReference.classRef(symbol(className)); } public static Conditional conditional(Value condition, Value whenTrue, Value whenFalse, Type type) { return Values.conditional(NULL_SOURCE, condition, whenTrue, whenFalse, type); } public static Value constantRef(String name, String dataType, FieldSignature fieldSignature, Type type) { return Values.constantRef(NULL_SOURCE, symbol(name), symbol(dataType), fieldSignature, type); } public static Value constantValue(String name, String dataType, Type type) { return Values.constantValue(NULL_SOURCE, symbol(name), symbol(dataType), type); } public static DataConstructor construct(String name, Type type, List<Value> arguments) { return Values.construct(NULL_SOURCE, symbol(name), type, arguments); } public static DataConstructorDescriptor constructor(int ordinal, String dataType, String name, String className) { return constructor(ordinal, dataType, name, className, emptyList()); } public static DataConstructorDescriptor constructor(int ordinal, String dataType, String name, String className, List<DataFieldDescriptor> fields) { return DataConstructorDescriptor.builder(ordinal, symbol(dataType), symbol(name), className) .withFields(fields) .build(); } public static DataConstructorDefinition ctorDef(int ordinal, String dataType, String name) { return ctorDef(ordinal, dataType, name, emptyList()); } public static DataConstructorDefinition ctorDef(int ordinal, String dataType, String name, List<DataFieldDefinition> fields) { return DataConstructorDefinition.builder() .withSourceLocation(NULL_SOURCE) .withOrdinal(ordinal) .withDataType(symbol(dataType)) .withSymbol(symbol(name)) .withFields(fields) .build(); } public static DataTypeDefinition dataDef(String name, List<Type> parameters, List<DataConstructorDefinition> constructors) { return DataTypeDefinition.builder() .withSourceLocation(NULL_SOURCE) .withSymbol(symbol(name)) .withParameters(parameters) .withConstructors(constructors) .build(); } public static DataReference dataRef(String name) { return DefinitionReference.dataRef(symbol(name)); } public static DataTypeDescriptor dataType(String name, List<Type> parameters, List<DataConstructorDescriptor> constructors) { return DataTypeDescriptor.builder(symbol(name)) .withParameters(parameters.stream() .map(Type::toDescriptor) .collect(toList())) .withConstructors(constructors) .build(); } public static EqualMatch equal(Value value) { return Patterns.equal(NULL_SOURCE, Optional.empty(), value); } public static EqualMatch equal(Value argument, Value value) { return Patterns.equal(NULL_SOURCE, Optional.of(argument), value); } public static InitializerField field(String name, Value value) { return InitializerField.field(NULL_SOURCE, name, value); } public static StructField field(String field, Type type, PatternMatch patternMatch) { return Patterns.field(NULL_SOURCE, field, type, patternMatch); } public static DataFieldDefinition fieldDef(int ordinal, String name, Type type) { return DataFieldDefinition.builder() .withSourceLocation(NULL_SOURCE) .withOrdinal(ordinal) .withName(name) .withType(type) .build(); } public static FunctionValue fn(String name, Argument argument, Value body) { return fn(name, asList(argument), body); } public static FunctionValue fn(String name, List<Argument> arguments, Value body) { return Values.fn(NULL_SOURCE, symbol(name), arguments, body); } public static List<GeneratedClass> generateBytecode(ClassLoaderResolver resolver, String... lines) { return compiler(resolver, lines).generateBytecode(); } public static Identifier id(String name, Type type) { return Values.id(NULL_SOURCE, symbol(name), type); } public static IgnorePattern ignore(Type type) { return Patterns.ignore(NULL_SOURCE, type); } public static Initializer initializer(Type type, Value value, List<InitializerField> fields) { return Values.initializer(NULL_SOURCE, type, value, fields); } public static Instance instance(InstanceReference reference, Type type) { return Values.instance(NULL_SOURCE, reference, type); } public static InstanceReference instanceRef(String moduleName, String className, List<TypeParameterDescriptor> parameters) { return DefinitionReference.instanceRef(classRef(className), moduleRef(moduleName), parameters); } public static Type intType() { return sum("scotch.data.int.Int"); } public static IsConstructor isConstructor(Value value, String constructor) { return Values.isConstructor(NULL_SOURCE, value, symbol(constructor)); } public static Let let(Type type, String name, Value value, Value scope) { return Values.let(NULL_SOURCE, type, name, value, scope); } public static BoolLiteral literal(boolean value) { return Values.literal(NULL_SOURCE, value); } public static CharLiteral literal(char value) { return Values.literal(NULL_SOURCE, value); } public static DoubleLiteral literal(double value) { return Values.literal(NULL_SOURCE, value); } public static IntLiteral literal(int value) { return Values.literal(NULL_SOURCE, value); } public static StringLiteral literal(String value) { return Values.literal(NULL_SOURCE, value); } public static PatternMatcher matcher(String symbol, Type type, Argument argument, PatternCase... matchers) { return matcher(symbol, type, asList(argument), matchers); } public static PatternMatcher matcher(String symbol, Type type, List<Argument> arguments, PatternCase... matchers) { return Values.matcher(NULL_SOURCE, symbol(symbol), type, arguments, asList(matchers)); } public static Value method(String name, List<Type> instances, Type type) { return Values.method(NULL_SOURCE, valueRef(name), instances, type); } public static ModuleImport moduleImport(String moduleName) { return Import.moduleImport(NULL_SOURCE, moduleName); } public static OperatorDefinition operatorDef(String name, Fixity fixity, int precedence) { return Definitions.operatorDef(NULL_SOURCE, symbol(name), fixity, precedence); } public static OperatorReference operatorRef(String name) { return DefinitionReference.operatorRef(symbol(name)); } public static PatternCase pattern(String name, List<PatternMatch> matches, Value body) { return Patterns.pattern(NULL_SOURCE, symbol(name), matches, body); } public static Raise raise(String message, Type type) { return Values.raise(NULL_SOURCE, message, type); } public static RootDefinition root(List<DefinitionReference> definitions) { return Definitions.root(NULL_SOURCE, definitions); } public static ValueScope scope(String symbol, Value value) { return Values.scope(NULL_SOURCE, symbol(symbol), value); } public static ScopeReference scopeRef(String name) { return DefinitionReference.scopeRef(symbol(name)); } public static SignatureReference signatureRef(String name) { return DefinitionReference.signatureRef(symbol(name)); } public static StructMatch struct(String dataType, Type type, List<StructField> fields) { return Patterns.struct(NULL_SOURCE, Optional.empty(), symbol(dataType), type, fields); } public static StructMatch struct(Value argument, String dataType, Type type, List<StructField> fields) { return Patterns.struct(NULL_SOURCE, Optional.of(argument), symbol(dataType), type, fields); } public static TypeClassDescriptor typeClass(String name, List<Type> parameters, List<String> members) { return TypeClassDescriptor.typeClass(symbol(name), parameters.stream().map(Type::toDescriptor).collect(toList()), members.stream() .map(Symbol::symbol) .collect(toList())); } public static TypeInstanceDescriptor typeInstance(String moduleName, String typeClass, List<Type> parameters, MethodSignature instanceGetter) { return TypeInstanceDescriptor.typeInstance(moduleName, symbol(typeClass), parameters.stream().map(Type::toDescriptor).collect(toList()), instanceGetter); } public static UnshuffledValue unshuffled(Value... members) { return Values.unshuffled(NULL_SOURCE, asList(members)); } public static UnshuffledDefinition unshuffled(String name, List<PatternMatch> matches, Value body) { return Definitions.unshuffled(NULL_SOURCE, symbol(name), matches, body); } public static UnshuffledStructMatch unshuffledMatch(Type type, PatternMatch... matches) { return Patterns.unshuffledMatch(NULL_SOURCE, type, asList(matches)); } public static ValueDefinition value(String name, Value value) { return Definitions.value(NULL_SOURCE, symbol(name), value); } public static ValueReference valueRef(String name) { return DefinitionReference.valueRef(symbol(name)); } private TestUtil() { // intentionally empty } }