import org.cojen.classfile.TypeDesc;
import org.simantics.scl.compiler.common.datatypes.Constructor;
import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.constants.Constant;
import org.simantics.scl.compiler.constants.JavaTypeInstanceConstructor;
import org.simantics.scl.compiler.constants.SCLConstructor;
import org.simantics.scl.compiler.constants.StringConstant;
import org.simantics.scl.compiler.constants.generic.ClassRef;
import org.simantics.scl.compiler.constants.generic.ConvertToListFilter;
import org.simantics.scl.compiler.constants.generic.MethodRef;
+import org.simantics.scl.compiler.constants.generic.MethodRef.FieldRef;
import org.simantics.scl.compiler.constants.generic.OutputFilter;
import org.simantics.scl.compiler.constants.generic.ParameterStackItem;
import org.simantics.scl.compiler.constants.generic.Pop2OutputFilter;
import org.simantics.scl.compiler.constants.generic.PopOutputFilter;
import org.simantics.scl.compiler.constants.generic.StackItem;
import org.simantics.scl.compiler.constants.generic.ThreadLocalStackItem;
+import org.simantics.scl.compiler.constants.singletons.SafeCoerce;
import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
import org.simantics.scl.compiler.elaboration.contexts.TypeTranslationContext;
import org.simantics.scl.compiler.elaboration.errors.NotPatternException;
import org.simantics.scl.compiler.internal.parsing.types.TypeAst;
import org.simantics.scl.compiler.module.ConcreteModule;
import org.simantics.scl.compiler.module.ImportDeclaration;
+import org.simantics.scl.compiler.module.InvalidModulePathException;
+import org.simantics.scl.compiler.module.ModuleUtils;
import org.simantics.scl.compiler.module.repository.ImportFailure;
import org.simantics.scl.compiler.module.repository.ImportFailureException;
import org.simantics.scl.compiler.types.TCon;
module = new ConcreteModule(moduleName);
compilationContext.module = module;
+ if(moduleHeader != null && moduleHeader.defaultLocalName != null)
+ module.setDefaultLocalName(moduleHeader.defaultLocalName);
try {
if(timer != null)
timer.suspendTimer();
ArrayList<ImportDeclaration> absoluteImports = new ArrayList<ImportDeclaration>(relativeImports.size());
for(ImportDeclaration relativeImport : relativeImports) {
if(relativeImport.moduleName.startsWith(".")) {
- String absoluteModuleName = convertRelativeModulePath(relativeImport.location, relativeImport.moduleName);
- if(absoluteModuleName != null) {
+ try {
+ String absoluteModuleName = ModuleUtils.resolveAbsolutePath(moduleName, relativeImport.moduleName);
ImportDeclaration absoluteImport = new ImportDeclaration(
absoluteModuleName, relativeImport.localName,
relativeImport.reexport, relativeImport.spec);
absoluteImport.location = relativeImport.location;
absoluteImports.add(absoluteImport);
- }
+ } catch (InvalidModulePathException e) {
+ errorLog.log(relativeImport.location, e.getMessage());
+ }
}
else
absoluteImports.add(relativeImport);
return absoluteImports;
}
- private String convertRelativeModulePath(long location, String relativeModuleName) {
- String originalRelativeModuleName = relativeModuleName;
- int p = moduleName.lastIndexOf('/');
- String parentPackage = p < 0 ? "" : moduleName.substring(0, p);
- while(relativeModuleName.startsWith(".")) {
- if(relativeModuleName.startsWith("./")) {
- relativeModuleName = relativeModuleName.substring(2);
- }
- else if(relativeModuleName.startsWith("../")) {
- relativeModuleName = relativeModuleName.substring(3);
- if(parentPackage.isEmpty()) {
- errorLog.log(location, "Couldn't resolve the relative module name " + originalRelativeModuleName + " when the current module name is " + moduleName + ".");
- return null;
- }
- p = parentPackage.lastIndexOf('/');
- parentPackage = p < 0 ? "" : parentPackage.substring(0, p);
- }
- else {
- errorLog.log(location, "Couldn't resolve the relative module name " + originalRelativeModuleName + ". It has an invalid syntax.");
- return null;
- }
- }
- return parentPackage + "/" + relativeModuleName;
- }
-
public void addTypesToEnvironment(
ArrayList<DDataAst> dataTypesAst,
ArrayList<DTypeAst> typeAliasesAst,
}
public void processDataTypes(ArrayList<DDataAst> dataTypesAst) {
+ ArrayList<Runnable> fieldAccessorGenerators = new ArrayList<Runnable>();
for(DDataAst dataTypeAst : dataTypesAst) {
TypeTranslationContext context = createTypeTranslationContext();
TVar[] typeParameters = new TVar[dataTypeAst.parameters.length];
constructors[j].fieldNames = fieldNames;
constructors[j].recordFieldNames = constructor.fieldNames;
}
+ if(constructors.length == 1) {
+ Constructor constructor = constructors[0];
+ if(constructor.recordFieldNames != null) {
+ fieldAccessorGenerators.add(new Runnable() {
+ @Override
+ public void run() {
+ Type in = Types.apply(dataType.name, dataType.parameters);
+ for(int i=0;i<constructor.recordFieldNames.length;++i) {
+ Type out = constructor.parameterTypes[i];
+ Constant accessor;
+ if(trivialDataType)
+ accessor = new SafeCoerce(dataType.parameters, in, out);
+ else
+ accessor = new CallJava(dataType.parameters, Types.NO_EFFECTS, out,
+ new Type[] {in}, new StackItem[] {new ParameterStackItem(0, in)},
+ new FieldRef(constructor.javaName, constructor.fieldNames != null ? constructor.fieldNames[i] : "c" + i,
+ javaTypeTranslator.toTypeDesc(out)),
+ null);
+ module.addFieldAccessor(constructor.recordFieldNames[i], accessor);
+ }
+ }
+ });
+ }
+ }
}
+
+ for(Runnable fieldAccessorGenerator : fieldAccessorGenerators)
+ fieldAccessorGenerator.run();
}
public void processTypeClasses(ArrayList<ProcessedDClassAst> typeClassesAst) {