X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Fcompilation%2FElaboration.java;h=c59df828d93a852cf6c5b03d848f8cad9b3f3792;hp=d331283fd76f3ddfd624f65a4fc7c03e288379a5;hb=a2abb6355b3b4d25ce92b313a457f0a8c4326c54;hpb=eecd74faded034bd067094b42bbac0d286d8d9fa diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/Elaboration.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/Elaboration.java index d331283fd..c59df828d 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/Elaboration.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/Elaboration.java @@ -6,7 +6,9 @@ import java.util.List; import org.cojen.classfile.TypeDesc; import org.simantics.scl.compiler.common.datatypes.Constructor; +import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; 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; @@ -14,11 +16,14 @@ import org.simantics.scl.compiler.constants.generic.CallJava; 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; @@ -27,12 +32,16 @@ import org.simantics.scl.compiler.elaboration.expressions.EGetConstraint; import org.simantics.scl.compiler.elaboration.expressions.EIntegerLiteral; import org.simantics.scl.compiler.elaboration.expressions.EListLiteral; import org.simantics.scl.compiler.elaboration.expressions.ELiteral; +import org.simantics.scl.compiler.elaboration.expressions.EPreCHRRulesetConstructor; import org.simantics.scl.compiler.elaboration.expressions.EVar; import org.simantics.scl.compiler.elaboration.expressions.Expression; import org.simantics.scl.compiler.elaboration.expressions.Variable; +import org.simantics.scl.compiler.elaboration.expressions.annotations.AnnotationUtils; import org.simantics.scl.compiler.elaboration.fundeps.Fundep; import org.simantics.scl.compiler.elaboration.java.JavaMethodDeclaration; import org.simantics.scl.compiler.elaboration.macros.StandardMacroRule; +import org.simantics.scl.compiler.elaboration.modules.DeprecatedProperty; +import org.simantics.scl.compiler.elaboration.modules.DerivedProperty; import org.simantics.scl.compiler.elaboration.modules.InlineProperty; import org.simantics.scl.compiler.elaboration.modules.MethodImplementation; import org.simantics.scl.compiler.elaboration.modules.PrivateProperty; @@ -41,6 +50,7 @@ import org.simantics.scl.compiler.elaboration.modules.TypeAlias; import org.simantics.scl.compiler.elaboration.modules.TypeClass; import org.simantics.scl.compiler.elaboration.modules.TypeClassInstance; import org.simantics.scl.compiler.elaboration.modules.TypeClassMethod; +import org.simantics.scl.compiler.elaboration.modules.TypeDescriptor; import org.simantics.scl.compiler.elaboration.query.Query; import org.simantics.scl.compiler.elaboration.query.pre.QPreGuard; import org.simantics.scl.compiler.elaboration.relations.ConcreteRelation; @@ -51,11 +61,14 @@ import org.simantics.scl.compiler.environment.AmbiguousNameException; import org.simantics.scl.compiler.environment.Environment; import org.simantics.scl.compiler.environment.EnvironmentFactory; import org.simantics.scl.compiler.environment.Environments; +import org.simantics.scl.compiler.errors.CompilationError; import org.simantics.scl.compiler.errors.ErrorLog; +import org.simantics.scl.compiler.errors.ErrorSeverity; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.codegen.effects.EffectConstructor; import org.simantics.scl.compiler.internal.codegen.effects.ThreadLocalVariable; import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidator; +import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidatorFactory; import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator; import org.simantics.scl.compiler.internal.codegen.types.StandardTypeConstructor; import org.simantics.scl.compiler.internal.codegen.utils.Constants; @@ -65,6 +78,8 @@ import org.simantics.scl.compiler.internal.deriving.InstanceDeriver; import org.simantics.scl.compiler.internal.deriving.InstanceDerivers; import org.simantics.scl.compiler.internal.elaboration.profiling.BranchPointInjector; import org.simantics.scl.compiler.internal.elaboration.utils.StronglyConnectedComponents; +import org.simantics.scl.compiler.internal.header.ModuleHeader; +import org.simantics.scl.compiler.internal.parsing.Token; import org.simantics.scl.compiler.internal.parsing.declarations.ConstructorAst; import org.simantics.scl.compiler.internal.parsing.declarations.DAnnotationAst; import org.simantics.scl.compiler.internal.parsing.declarations.DClassAst; @@ -76,10 +91,12 @@ import org.simantics.scl.compiler.internal.parsing.declarations.DInstanceAst; import org.simantics.scl.compiler.internal.parsing.declarations.DMappingRelationAst; import org.simantics.scl.compiler.internal.parsing.declarations.DRelationAst; import org.simantics.scl.compiler.internal.parsing.declarations.DRuleAst; +import org.simantics.scl.compiler.internal.parsing.declarations.DRulesetAst; import org.simantics.scl.compiler.internal.parsing.declarations.DTypeAst; import org.simantics.scl.compiler.internal.parsing.declarations.DValueAst; import org.simantics.scl.compiler.internal.parsing.declarations.DValueTypeAst; import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException; +import org.simantics.scl.compiler.internal.parsing.parser.SCLTerminals; import org.simantics.scl.compiler.internal.parsing.translation.ProcessedDClassAst; import org.simantics.scl.compiler.internal.parsing.translation.ProcessedDInstanceAst; import org.simantics.scl.compiler.internal.parsing.translation.RelationRepository; @@ -87,8 +104,12 @@ import org.simantics.scl.compiler.internal.parsing.translation.ValueRepository; 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.debug.ModuleDebugInfo; import org.simantics.scl.compiler.module.repository.ImportFailure; import org.simantics.scl.compiler.module.repository.ImportFailureException; +import org.simantics.scl.compiler.top.SCLCompilerConfiguration; import org.simantics.scl.compiler.types.TCon; import org.simantics.scl.compiler.types.TForAll; import org.simantics.scl.compiler.types.TFun; @@ -110,51 +131,71 @@ import gnu.trove.set.hash.TIntHashSet; public class Elaboration { // inputs - ErrorLog errorLog; - String moduleName; - ArrayList importsAst; - JavaReferenceValidator javaReferenceValidator; - ValueRepository valueDefinitionsAst; - RelationRepository relationDefinitionsAst; + private final CompilationContext compilationContext; + private final ErrorLog errorLog; + private final String moduleName; + private final ModuleHeader moduleHeader; + private final ArrayList importsAst; + private final JavaReferenceValidatorFactory jrvFactory; + final JavaReferenceValidator javaReferenceValidator; + private final ValueRepository valueDefinitionsAst; + private final RelationRepository relationDefinitionsAst; // creates ConcreteModule module; Environment importedEnvironment; - Environment environment; - JavaNamingPolicy namingPolicy; ArrayList supplementedTypeAnnotations = new ArrayList(); JavaTypeTranslator javaTypeTranslator; ArrayList dataTypes = new ArrayList(); THashMap classRefs = new THashMap(); THashMap branchPoints; + + THashMap exportMap = null; - @SuppressWarnings("unchecked") - public Elaboration(ErrorLog errorLog, CompilationTimer timer, EnvironmentFactory localEnvironmentFactory, - String moduleName, ArrayList importsAst, - JavaReferenceValidator javaReferenceValidator, + public Elaboration(CompilationContext compilationContext, CompilationTimer timer, EnvironmentFactory localEnvironmentFactory, + String moduleName, ModuleHeader moduleHeader, ArrayList importsAst, + JavaReferenceValidatorFactory jrvFactory, ValueRepository valueDefinitionsAst, RelationRepository relationDefinitionsAst) { - this.errorLog = errorLog; + this.compilationContext = compilationContext; + this.errorLog = compilationContext.errorLog; this.moduleName = moduleName; - importsAst = processRelativeImports(importsAst); + this.moduleHeader = moduleHeader; + if(moduleName != null) + importsAst = processRelativeImports(compilationContext.errorLog, moduleName, importsAst); this.importsAst = importsAst; - this.javaReferenceValidator = (JavaReferenceValidator)javaReferenceValidator; + this.jrvFactory = jrvFactory; + this.javaReferenceValidator = moduleHeader == null || moduleHeader.classLoader == null + ? jrvFactory.getDefaultJavaReferenceValidator() + : jrvFactory.getJavaReferenceValidator(moduleHeader.classLoader); + if(javaReferenceValidator == null) + errorLog.log(moduleHeader.classLoaderLocation, "Didn't find the specified class loader."); this.valueDefinitionsAst = valueDefinitionsAst; this.relationDefinitionsAst = relationDefinitionsAst; module = new ConcreteModule(moduleName); + compilationContext.module = module; + compilationContext.moduleRepository = localEnvironmentFactory.getModuleRepository(); + if(moduleHeader != null) { + if(moduleHeader.defaultLocalName != null) + module.setDefaultLocalName(moduleHeader.defaultLocalName); + if(moduleHeader.deprecated != null) + module.setDeprecation(moduleHeader.deprecated); + } try { if(timer != null) timer.suspendTimer(); importedEnvironment = localEnvironmentFactory.createEnvironment( + compilationContext, importsAst.toArray(new ImportDeclaration[importsAst.size()])); if(timer != null) timer.continueTimer(); - this.environment = new EnvironmentOfModule(importedEnvironment, module); + compilationContext.environment = new EnvironmentOfModule(importedEnvironment, module); } catch (ImportFailureException e) { for(ImportFailure failure : e.failures) - errorLog.log(failure.location, failure.toString()); + errorLog.log(new CompilationError(failure.location, failure.toString(), + failure.reason == ImportFailure.MODULE_DOES_NOT_EXIST_REASON ? ErrorSeverity.ERROR : ErrorSeverity.IMPORT_ERROR)); return; } for(ImportDeclaration importAst : importsAst) @@ -164,21 +205,24 @@ public class Elaboration { false, importAst.spec)); localEnvironmentFactory.addBuiltinDependencies(module); - namingPolicy = new JavaNamingPolicy(moduleName); + compilationContext.namingPolicy = new JavaNamingPolicy(moduleName); } - private ArrayList processRelativeImports(ArrayList relativeImports) { + public static ArrayList processRelativeImports(ErrorLog errorLog, String moduleName, ArrayList relativeImports) { ArrayList absoluteImports = new ArrayList(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( + relativeImport.location, absoluteModuleName, relativeImport.localName, relativeImport.reexport, relativeImport.spec); - absoluteImport.location = relativeImport.location; absoluteImports.add(absoluteImport); - } + } catch (InvalidModulePathException e) { + if(errorLog != null) + errorLog.log(relativeImport.location, e.getMessage()); + } } else absoluteImports.add(relativeImport); @@ -186,35 +230,11 @@ public class Elaboration { 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 dataTypesAst, ArrayList typeAliasesAst, - ArrayList effectsAst) { + ArrayList effectsAst, + ArrayList rulesetsAst) { for(DDataAst dataType : dataTypesAst) { dataType.parameterKinds = new Kind[dataType.parameters.length]; Kind constructorKind = Kinds.STAR; @@ -229,8 +249,7 @@ public class Elaboration { NameExistenceChecks.checkIfTypeExists(errorLog, dataType.location, importedEnvironment, dataType.name); - if(module.addTypeConstructor(dataType.name, typeConstructor)) - errorLog.log(dataType.location, "Type "+dataType.name+" has already been defined in this module."); + addTypeDescriptor(dataType.location, dataType.name, typeConstructor); dataType.typeConstructor = typeConstructor; } @@ -238,9 +257,7 @@ public class Elaboration { TypeAlias alias = new TypeAlias(Types.con(moduleName, typeAlias.name), typeAlias.parameters.length); NameExistenceChecks.checkIfTypeExists(errorLog, typeAlias.location, importedEnvironment, typeAlias.name); - if(module.addTypeAlias(typeAlias.name, alias)) { - errorLog.log(typeAlias.location, "Type alias "+typeAlias.name+" has already been defined in this module."); - } + addTypeDescriptor(typeAlias.location, typeAlias.name, alias); } for(DEffectAst effect : effectsAst) { @@ -251,9 +268,23 @@ public class Elaboration { TypeDesc.forClass(effect.threadLocalType) )); if(module.addEffectConstructor(effect.name, effectConstructor)) - errorLog.log(effect.location, "Type "+effect.name+" has already been defined in this module."); - } - javaTypeTranslator = new JavaTypeTranslator(environment); + errorLog.log(effect.location, "Effect "+effect.name+" has already been defined in this module."); + } + for(DRulesetAst ruleset : rulesetsAst) { + ruleset.type = Types.con(moduleName, ruleset.name); + ruleset.className = compilationContext.namingPolicy.getDataTypeClassName(ruleset.name); + StandardTypeConstructor typeConstructor = new StandardTypeConstructor(ruleset.type, Kinds.STAR, + TypeDesc.forClass(ruleset.className), ruleset.documentation == null ? null : ruleset.documentation.documentation); + typeConstructor.external = true; + addTypeDescriptor(ruleset.location, ruleset.name, typeConstructor); + } + javaTypeTranslator = new JavaTypeTranslator(compilationContext.environment); + compilationContext.javaTypeTranslator = javaTypeTranslator; + } + + private void addTypeDescriptor(long location, String name, TypeDescriptor typeDescriptor) { + if(module.addTypeDescriptor(name, typeDescriptor)) + errorLog.log(location, "Type "+name+" has already been defined in this module."); } private static final int[] EMPTY_INT_ARRAY = new int[0]; @@ -307,9 +338,9 @@ public class Elaboration { } }.findComponents(); - if(errorLog.isEmpty()) { + if(errorLog.hasNoErrors()) { for(DTypeAst typeAlias : orderedTypeAliases) { - TypeAlias alias = module.getTypeAlias(typeAlias.name); + TypeAlias alias = (TypeAlias)module.getTypeDescriptor(typeAlias.name); TypeTranslationContext context = createTypeTranslationContext(); for(int i=0;i dataTypesAst) { + ArrayList fieldAccessorGenerators = new ArrayList(); for(DDataAst dataTypeAst : dataTypesAst) { TypeTranslationContext context = createTypeTranslationContext(); TVar[] typeParameters = new TVar[dataTypeAst.parameters.length]; @@ -346,7 +378,7 @@ public class Elaboration { boolean trivialDataType = dataTypeAst.constructors.length == 1 && dataTypeAst.constructors[0].parameters.length == 1; if(className == null && !trivialDataType) - className = namingPolicy.getDataTypeClassName(dataTypeAst.name); + className = compilationContext.namingPolicy.getDataTypeClassName(dataTypeAst.name); StandardTypeConstructor dataType = dataTypeAst.typeConstructor; @@ -361,12 +393,12 @@ public class Elaboration { dataTypes.add(dataType); for(int j=0;j=0;--i) parameterTypes[i] = context.toType(constructor.parameters[i]); String javaName = constructors.length == 1 ? className - : namingPolicy.getConstructorClassName(name); + : compilationContext.namingPolicy.getConstructorClassName(name); String[] fieldNames = null; for(DAnnotationAst annotation : constructor.annotations) if(annotation.id.text.equals("@JavaType")) { @@ -400,7 +432,34 @@ public class Elaboration { 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 typeClassesAst) { @@ -433,7 +492,7 @@ public class Elaboration { TypeClass typeClass = new TypeClass(classAst.location, classContext, con, - namingPolicy.getTypeClassInterfaceName(con), + compilationContext.namingPolicy.getTypeClassInterfaceName(con), parameters, Fundep.mapFundeps(classAst.parameters, classAst.fundeps)); @@ -451,7 +510,7 @@ public class Elaboration { typeClass.methodNames.add(name.name); methods.put(name.name, new TypeClassMethod(typeClass, name.name, - namingPolicy.getMethodName(name.name), + compilationContext.namingPolicy.getMethodName(name.name), type, Types.getArity(type), name.location) ); @@ -474,9 +533,8 @@ public class Elaboration { method.setDefaultImplementation(Name.create(moduleName, fullName)); valueDefinitionsAst.addDefinitions(fullName, defs); - /*valueDefinitionsAst.addAnnotation(fullName, new DAnnotationAst(new EVar("@private"), - Collections.emptyList()));*/ - supplementedTypeAnnotations.add(new SupplementedValueType(defs.get(0).location, fullName, method.getType())); + supplementedTypeAnnotations.add(new SupplementedValueType(defs.get(0).location, fullName, method.getType())); + valueDefinitionsAst.setDerived(fullName); } module.addTypeClass(classAst.name, typeClass); @@ -484,7 +542,7 @@ public class Elaboration { } private TypeTranslationContext createTypeTranslationContext() { - return new TypeTranslationContext(errorLog, environment); + return new TypeTranslationContext(compilationContext); } public void processDerivingInstances(ArrayList derivingInstancesAst, @@ -493,7 +551,7 @@ public class Elaboration { String name = derivingInstance.name.name; TCon con; try { - con = Environments.getTypeClassName(environment, name); + con = Environments.getTypeClassName(compilationContext.environment, name); } catch (AmbiguousNameException e) { errorLog.log(derivingInstance.name.location, e.getMessage()); continue; @@ -506,7 +564,7 @@ public class Elaboration { if(deriver == null) errorLog.log(derivingInstance.location, "Doesn't know how to derive " + name + "."); else - deriver.derive(errorLog, environment, instancesAst, derivingInstance); + deriver.derive(errorLog, compilationContext.environment, instancesAst, derivingInstance); } } @@ -520,7 +578,7 @@ public class Elaboration { String name = instanceAst.name.name; TCon typeClassCon; try { - typeClassCon = Environments.getTypeClassName(environment, name); + typeClassCon = Environments.getTypeClassName(compilationContext.environment, name); } catch (AmbiguousNameException e) { errorLog.log(instanceAst.name.location, e.getMessage()); continue; @@ -529,7 +587,7 @@ public class Elaboration { errorLog.log(instanceAst.name.location, "Couldn't resolve class " + name + "."); continue; } - TypeClass typeClass = environment.getTypeClass(typeClassCon); + TypeClass typeClass = compilationContext.environment.getTypeClass(typeClassCon); pInstanceAst.typeClass = typeClass; if(instanceAst.types.length != typeClass.parameters.length) { @@ -550,7 +608,7 @@ public class Elaboration { for(int i=0;iemptyList()));*/ TypeClassMethod method = typeClass.methods.get(valueName); @@ -626,6 +685,7 @@ public class Elaboration { Expression expression = new EGetConstraint(instance.location, type); value.setExpression(expression); value.setType(Types.forAll(instance.generatorParameters, Types.constrained(instance.context, type))); + value.getProperties().add(new InlineProperty(instance.context.length, 0xffffffff)); //TypeUnparsingContext tuc = new TypeUnparsingContext(); // TODO error handling instance.superExpressions[i] = value; @@ -647,18 +707,17 @@ public class Elaboration { if(annotations != null) { for(DAnnotationAst annotation : annotations) if(annotation.id.text.equals("@JavaName")) { - Expression p0 = annotation.parameters[0]; - if(p0 instanceof EVar) - javaName = ((EVar)p0).name; - else if(p0 instanceof ELiteral) { - ELiteral lit = (ELiteral)p0; - javaName = ((StringConstant)lit.getValue()).getValue(); - } + String temp = AnnotationUtils.processStringAnnotation(errorLog, annotation); + if(temp != null) + javaName = temp; } else if(annotation.id.text.equals("@private")) { + AnnotationUtils.processTagAnnotation(errorLog, annotation); isPrivate = true; } } + if(exportMap != null) + isPrivate = exportMap.remove(name) == null; Type type = createTypeTranslationContext().toType(javaMethod.type); @@ -669,7 +728,7 @@ public class Elaboration { type); if(callJava != null) { NameExistenceChecks.checkIfValueExists(errorLog, javaMethod.location, - importedEnvironment, name); + importedEnvironment, module, name); SCLValue value = module.addValue(name, callJava); value.definitionLocation = javaMethod.methodName.location; if(isPrivate) @@ -678,6 +737,18 @@ public class Elaboration { } } + public void processRulesets(ArrayList rulesetsAst) { + for(DRulesetAst ruleset : rulesetsAst) { + String constructorName = "create" + ruleset.name; + supplementedTypeAnnotations.add(new SupplementedValueType(ruleset.location, constructorName, Types.functionE(Types.PUNIT, Types.PROC, ruleset.type))); + try { + valueDefinitionsAst.add(new DValueAst(new EVar(constructorName), new EPreCHRRulesetConstructor(ruleset))); + } catch (NotPatternException e) { + throw new InternalCompilerError(ruleset.location, e); + } + } + } + /** * Convert a java class method into a {@link CallJava} instance. * Compilation errors are logged for failures in finding the named class or in accessing the method. @@ -848,7 +919,7 @@ public class Elaboration { effect.collectConcreteEffects(concreteEffects); for(TCon eff : concreteEffects) { - EffectConstructor effC = environment.getEffectConstructor(eff); + EffectConstructor effC = compilationContext.environment.getEffectConstructor(eff); for(ThreadLocalVariable var : effC.getThreadLocalVariables()) { for(int i=0;i sections = new THashMap(); - final TranslationContext context = createTranslationContext(); + final TranslationContext context = createTranslationContext(ruleName); if(length > 0) { THashMap variables = context.getVariables(); for(TransformationRule extendsRule : extendsRules) { @@ -1056,6 +1131,7 @@ public class Elaboration { int constructorTag = 0; for(Constructor constructor : dataType.constructors) { SCLValue value = new SCLValue(constructor.name); + value.definitionLocation = constructor.loc; SCLConstructor sclConstructor = new SCLConstructor( constructor.name.name, @@ -1070,13 +1146,14 @@ public class Elaboration { constructor.getParameterTypes()); if(dataType.constructors.length == 1 && ( dataType.getTypeDesc() == null || - dataType.constructors[0].javaName.equals(MethodBuilderBase.getClassName(dataType.getTypeDesc())))) + (dataType.constructors[0].javaName != null && + dataType.constructors[0].javaName.equals(MethodBuilderBase.getClassName(dataType.getTypeDesc()))))) sclConstructor.setOnlyConstructor(true); value.setValue(sclConstructor); value.setType(constructor.getType()); NameExistenceChecks.checkIfValueExists(errorLog, constructor.loc, - importedEnvironment, constructor.name.name); + importedEnvironment, module, constructor.name.name); if(module.addValue(value)) { errorLog.log(constructor.loc, "Value " + constructor.name.name + " is already defined."); @@ -1091,7 +1168,7 @@ public class Elaboration { SCLValue value = method.createValue(); value.definitionLocation = method.location; NameExistenceChecks.checkIfValueExists(errorLog, Locations.NO_LOCATION, - importedEnvironment, value.getName().name); + importedEnvironment, module, value.getName().name); if(module.addValue(value)) { String name = method.getName(); @@ -1111,10 +1188,12 @@ public class Elaboration { long location = valueDefinitionsAst.getLocation(name); NameExistenceChecks.checkIfValueExists(errorLog, location, - importedEnvironment, value.getName().name); + importedEnvironment, module, value.getName().name); value.definitionLocation = location; if(module.addValue(value)) errorLog.log(location, "Value " + name + " is already defined."); + if(valueDefinitionsAst.isDerived(name)) + value.addProperty(DerivedProperty.INSTANCE); } for(DValueTypeAst valueTypeAst : typeAnnotationsAst) for(EVar name : valueTypeAst.names) { @@ -1144,9 +1223,28 @@ public class Elaboration { for(String name : valueDefinitionsAst.getValueNames()) { ArrayList defs = valueDefinitionsAst.getDefinition(name); + if(defs.size() != 1 || !(defs.get(0).value instanceof EPreCHRRulesetConstructor)) + continue; + try { + SCLValue value = module.getValue(name); + TranslationContext context = createTranslationContext(name); + Expression expression = context.translateCases2(defs); + value.setExpression(expression); + + if(exportMap != null && exportMap.remove(name) == null) + value.addProperty(PrivateProperty.INSTANCE); + } catch(RuntimeException e) { + errorLog.setExceptionPosition(defs.get(0).location); + throw e; + } + } + for(String name : valueDefinitionsAst.getValueNames()) { + ArrayList defs = valueDefinitionsAst.getDefinition(name); + if(defs.size() == 1 && defs.get(0).value instanceof EPreCHRRulesetConstructor) + continue; try { SCLValue value = module.getValue(name); - TranslationContext context = createTranslationContext(); + TranslationContext context = createTranslationContext(name); Expression expression = context.translateCases2(defs); value.setExpression(expression); @@ -1159,6 +1257,8 @@ public class Elaboration { for(DAnnotationAst annotation : annotations) { handleAnnotation(value, defs, annotation); } + if(exportMap != null && exportMap.remove(name) == null) + value.addProperty(PrivateProperty.INSTANCE); } catch(RuntimeException e) { errorLog.setExceptionPosition(defs.get(0).location); throw e; @@ -1175,13 +1275,13 @@ public class Elaboration { DRelationAst definition = definitions.get(0); ConcreteRelation relation = (ConcreteRelation)module.getRelation(name); relation.location = definition.location; - TranslationContext context = createTranslationContext(); + TranslationContext context = createTranslationContext(name); definition.translateTo(context, relation); } } - private TranslationContext createTranslationContext() { - return new TranslationContext(errorLog, environment, null); + private TranslationContext createTranslationContext(String definitionName) { + return new TranslationContext(compilationContext, null, definitionName); } private void handleAnnotation(SCLValue value, ArrayList defs, DAnnotationAst annotation) { @@ -1190,7 +1290,7 @@ public class Elaboration { } else if(annotation.id.text.equals("@inline")) { try { - int arity = defs.get(0).lhs.getFunctionDefinitionArity(); + int arity = defs.get(0).lhs.getFunctionDefinitionPatternArity(); int phaseMask = 0xffffffff; if(annotation.parameters.length > 0) { phaseMask = Integer.parseInt(((EIntegerLiteral)annotation.parameters[0]).getValue()); @@ -1201,10 +1301,24 @@ public class Elaboration { } } else if(annotation.id.text.equals("@private")) { + if(moduleHeader != null && moduleHeader.export != null) + errorLog.log(annotation.location, "Annotation @private is not used when module header contains export property."); value.addProperty(PrivateProperty.INSTANCE); } else if(annotation.id.text.equals("@deprecated")) { - // TODO + String description = ""; + if(annotation.parameters.length > 0) { + if(annotation.parameters.length > 1) + errorLog.log(annotation.location, "Invalid number of parameters, expected one string."); + else { + String temp = AnnotationUtils.extractString(annotation.parameters[0]); + if(temp == null) + errorLog.log(annotation.location, "Invalid parameter, expected one string."); + else + description = temp; + } + } + value.addProperty(new DeprecatedProperty(description)); } else errorLog.log(annotation.location, "Unknown annotation."); @@ -1249,4 +1363,23 @@ public class Elaboration { branchPoints.put(valueName, injector.getAndClearBranchPoints()); } } + + public void collectDebugInfo() { + module.moduleDebugInfo = compilationContext.moduleDebugInfo = new ModuleDebugInfo(); + } + + public void prepareExports() { + if(moduleHeader != null && moduleHeader.export != null) { + exportMap = new THashMap(); + for(EVar export : moduleHeader.export) + if(exportMap.put(export.name, export) != null) + errorLog.log(export.location, "The symbol " + export.name + " is exported multiple times."); + } + } + + public void checkExports() { + if(exportMap != null) + for(EVar export : exportMap.values()) + errorLog.log(export.location, "The symbol " + export.name + " is not defined in the module."); + } }