package org.simantics.scl.compiler.compilation;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.simantics.scl.compiler.constants.generic.MethodRef;
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.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.InlineProperty;
import org.simantics.scl.compiler.elaboration.modules.MethodImplementation;
import org.simantics.scl.compiler.elaboration.modules.PrivateProperty;
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;
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.declarations.ConstructorAst;
import org.simantics.scl.compiler.internal.parsing.declarations.DAnnotationAst;
import org.simantics.scl.compiler.internal.parsing.declarations.DClassAst;
public class Elaboration {
// inputs
- ErrorLog errorLog;
- String moduleName;
- ArrayList<ImportDeclaration> importsAst;
- JavaReferenceValidator<Object, Object, Object, Object> javaReferenceValidator;
- ValueRepository valueDefinitionsAst;
- RelationRepository relationDefinitionsAst;
+ private final CompilationContext compilationContext;
+ private final ErrorLog errorLog;
+ private final String moduleName;
+ private final ModuleHeader moduleHeader;
+ private final ArrayList<ImportDeclaration> importsAst;
+ private final JavaReferenceValidatorFactory jrvFactory;
+ final JavaReferenceValidator<Object, Object, Object, Object> javaReferenceValidator;
+ private final ValueRepository valueDefinitionsAst;
+ private final RelationRepository relationDefinitionsAst;
// creates
ConcreteModule module;
Environment importedEnvironment;
- Environment environment;
- JavaNamingPolicy namingPolicy;
ArrayList<SupplementedValueType> supplementedTypeAnnotations = new ArrayList<SupplementedValueType>();
JavaTypeTranslator javaTypeTranslator;
THashMap<String, ClassRef> classRefs = new THashMap<String, ClassRef>();
THashMap<String, BranchPoint[]> branchPoints;
- @SuppressWarnings("unchecked")
- public Elaboration(ErrorLog errorLog, CompilationTimer timer, EnvironmentFactory localEnvironmentFactory,
- String moduleName, ArrayList<ImportDeclaration> importsAst,
- JavaReferenceValidator<?, ?, ?, ?> javaReferenceValidator,
+ public Elaboration(CompilationContext compilationContext, CompilationTimer timer, EnvironmentFactory localEnvironmentFactory,
+ String moduleName, ModuleHeader moduleHeader, ArrayList<ImportDeclaration> importsAst,
+ JavaReferenceValidatorFactory jrvFactory,
ValueRepository valueDefinitionsAst,
RelationRepository relationDefinitionsAst) {
- this.errorLog = errorLog;
+ this.compilationContext = compilationContext;
+ this.errorLog = compilationContext.errorLog;
this.moduleName = moduleName;
+ this.moduleHeader = moduleHeader;
importsAst = processRelativeImports(importsAst);
this.importsAst = importsAst;
- this.javaReferenceValidator = (JavaReferenceValidator<Object, Object, Object, Object>)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;
try {
if(timer != null)
timer.suspendTimer();
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());
false,
importAst.spec));
localEnvironmentFactory.addBuiltinDependencies(module);
- namingPolicy = new JavaNamingPolicy(moduleName);
+ compilationContext.namingPolicy = new JavaNamingPolicy(moduleName);
}
private ArrayList<ImportDeclaration> processRelativeImports(ArrayList<ImportDeclaration> relativeImports) {
NameExistenceChecks.checkIfTypeExists(errorLog,
dataType.location, importedEnvironment, dataType.name);
- if(module.addTypeConstructor(dataType.name, typeConstructor))
+ if(module.addTypeDescriptor(dataType.name, typeConstructor))
errorLog.log(dataType.location, "Type "+dataType.name+" has already been defined in this module.");
dataType.typeConstructor = typeConstructor;
}
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)) {
+ if(module.addTypeDescriptor(typeAlias.name, alias)) {
errorLog.log(typeAlias.location, "Type alias "+typeAlias.name+" has already been defined in this module.");
}
}
if(module.addEffectConstructor(effect.name, effectConstructor))
errorLog.log(effect.location, "Type "+effect.name+" has already been defined in this module.");
}
- javaTypeTranslator = new JavaTypeTranslator(environment);
+ javaTypeTranslator = new JavaTypeTranslator(compilationContext.environment);
+ compilationContext.javaTypeTranslator = javaTypeTranslator;
}
private static final int[] EMPTY_INT_ARRAY = new int[0];
}
}.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<typeAlias.parameters.length;++i)
context.pushTypeVar(typeAlias.parameters[i]);
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;
for(int i=constructor.parameters.length-1;i>=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")) {
TypeClass typeClass = new TypeClass(classAst.location,
classContext,
con,
- namingPolicy.getTypeClassInterfaceName(con),
+ compilationContext.namingPolicy.getTypeClassInterfaceName(con),
parameters,
Fundep.mapFundeps(classAst.parameters, classAst.fundeps));
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)
);
}
private TypeTranslationContext createTypeTranslationContext() {
- return new TypeTranslationContext(errorLog, environment);
+ return new TypeTranslationContext(compilationContext);
}
public void processDerivingInstances(ArrayList<DDerivingInstanceAst> derivingInstancesAst,
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;
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);
}
}
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;
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) {
for(int i=0;i<instanceContext.length;++i)
instanceContext[i] = context.toTFuncApply(instanceAst.context[i]);
- String javaName = namingPolicy.getInstanceClassName(instance);
+ String javaName = compilationContext.namingPolicy.getInstanceClassName(instance);
String instancePrefix = instance.toName() + "$";
ValueRepository valueDefs = pInstanceAst.valueDefs;
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;
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;
}
}
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<unresolvedItems.size();++i) {
int id = unresolvedItems.get(i);
javaTypeTranslator.toTypeDesc(returnType);
if(!javaReferenceValidator.isAssignableFrom(expectedReturnType,
providedReturnType)) {
- if(expectedReturnType.equals(TypeDesc.VOID))
- filter = PopOutputFilter.INSTANCE;
+ if(expectedReturnType.equals(TypeDesc.VOID)) {
+ if(providedReturnType.equals(TypeDesc.DOUBLE) || providedReturnType.equals(TypeDesc.LONG))
+ filter = Pop2OutputFilter.INSTANCE;
+ else
+ filter = PopOutputFilter.INSTANCE;
+ }
else if(expectedReturnType.equals(Constants.LIST)
&& providedReturnType.equals(Constants.COLLECTION))
filter = ConvertToListFilter.INSTANCE;
if(ruleAstMap.containsKey(extendsName))
extendsRule = processRule(extendsName);
else {
- extendsRule = Environments.getRule(environment, extendsName);
+ extendsRule = Environments.getRule(compilationContext.environment, extendsName);
if(extendsRule == null)
errorLog.log(ruleAst.location,
"Couldn't resolve rule name " + extendsName + ".");
}
private TranslationContext createTranslationContext() {
- return new TranslationContext(errorLog, environment, null);
+ return new TranslationContext(compilationContext, null);
}
private void handleAnnotation(SCLValue value, ArrayList<DValueAst> defs, DAnnotationAst annotation) {
}
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());
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.");