1 package org.simantics.scl.compiler.compilation;
3 import java.util.ArrayList;
4 import java.util.Iterator;
7 import org.cojen.classfile.TypeDesc;
8 import org.simantics.scl.compiler.common.datatypes.Constructor;
9 import org.simantics.scl.compiler.common.names.Name;
10 import org.simantics.scl.compiler.constants.JavaTypeInstanceConstructor;
11 import org.simantics.scl.compiler.constants.SCLConstructor;
12 import org.simantics.scl.compiler.constants.StringConstant;
13 import org.simantics.scl.compiler.constants.generic.CallJava;
14 import org.simantics.scl.compiler.constants.generic.ClassRef;
15 import org.simantics.scl.compiler.constants.generic.ConvertToListFilter;
16 import org.simantics.scl.compiler.constants.generic.MethodRef;
17 import org.simantics.scl.compiler.constants.generic.OutputFilter;
18 import org.simantics.scl.compiler.constants.generic.ParameterStackItem;
19 import org.simantics.scl.compiler.constants.generic.Pop2OutputFilter;
20 import org.simantics.scl.compiler.constants.generic.PopOutputFilter;
21 import org.simantics.scl.compiler.constants.generic.StackItem;
22 import org.simantics.scl.compiler.constants.generic.ThreadLocalStackItem;
23 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
24 import org.simantics.scl.compiler.elaboration.contexts.TypeTranslationContext;
25 import org.simantics.scl.compiler.elaboration.errors.NotPatternException;
26 import org.simantics.scl.compiler.elaboration.expressions.EApply;
27 import org.simantics.scl.compiler.elaboration.expressions.EGetConstraint;
28 import org.simantics.scl.compiler.elaboration.expressions.EIntegerLiteral;
29 import org.simantics.scl.compiler.elaboration.expressions.EListLiteral;
30 import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
31 import org.simantics.scl.compiler.elaboration.expressions.EVar;
32 import org.simantics.scl.compiler.elaboration.expressions.Expression;
33 import org.simantics.scl.compiler.elaboration.expressions.Variable;
34 import org.simantics.scl.compiler.elaboration.expressions.annotations.AnnotationUtils;
35 import org.simantics.scl.compiler.elaboration.fundeps.Fundep;
36 import org.simantics.scl.compiler.elaboration.java.JavaMethodDeclaration;
37 import org.simantics.scl.compiler.elaboration.macros.StandardMacroRule;
38 import org.simantics.scl.compiler.elaboration.modules.DeprecatedProperty;
39 import org.simantics.scl.compiler.elaboration.modules.InlineProperty;
40 import org.simantics.scl.compiler.elaboration.modules.MethodImplementation;
41 import org.simantics.scl.compiler.elaboration.modules.PrivateProperty;
42 import org.simantics.scl.compiler.elaboration.modules.SCLValue;
43 import org.simantics.scl.compiler.elaboration.modules.TypeAlias;
44 import org.simantics.scl.compiler.elaboration.modules.TypeClass;
45 import org.simantics.scl.compiler.elaboration.modules.TypeClassInstance;
46 import org.simantics.scl.compiler.elaboration.modules.TypeClassMethod;
47 import org.simantics.scl.compiler.elaboration.query.Query;
48 import org.simantics.scl.compiler.elaboration.query.pre.QPreGuard;
49 import org.simantics.scl.compiler.elaboration.relations.ConcreteRelation;
50 import org.simantics.scl.compiler.elaboration.rules.MappingRelation;
51 import org.simantics.scl.compiler.elaboration.rules.SectionName;
52 import org.simantics.scl.compiler.elaboration.rules.TransformationRule;
53 import org.simantics.scl.compiler.environment.AmbiguousNameException;
54 import org.simantics.scl.compiler.environment.Environment;
55 import org.simantics.scl.compiler.environment.EnvironmentFactory;
56 import org.simantics.scl.compiler.environment.Environments;
57 import org.simantics.scl.compiler.errors.ErrorLog;
58 import org.simantics.scl.compiler.errors.Locations;
59 import org.simantics.scl.compiler.internal.codegen.effects.EffectConstructor;
60 import org.simantics.scl.compiler.internal.codegen.effects.ThreadLocalVariable;
61 import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidator;
62 import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator;
63 import org.simantics.scl.compiler.internal.codegen.types.StandardTypeConstructor;
64 import org.simantics.scl.compiler.internal.codegen.utils.Constants;
65 import org.simantics.scl.compiler.internal.codegen.utils.JavaNamingPolicy;
66 import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilderBase;
67 import org.simantics.scl.compiler.internal.deriving.InstanceDeriver;
68 import org.simantics.scl.compiler.internal.deriving.InstanceDerivers;
69 import org.simantics.scl.compiler.internal.elaboration.profiling.BranchPointInjector;
70 import org.simantics.scl.compiler.internal.elaboration.utils.StronglyConnectedComponents;
71 import org.simantics.scl.compiler.internal.parsing.declarations.ConstructorAst;
72 import org.simantics.scl.compiler.internal.parsing.declarations.DAnnotationAst;
73 import org.simantics.scl.compiler.internal.parsing.declarations.DClassAst;
74 import org.simantics.scl.compiler.internal.parsing.declarations.DDataAst;
75 import org.simantics.scl.compiler.internal.parsing.declarations.DDerivingInstanceAst;
76 import org.simantics.scl.compiler.internal.parsing.declarations.DEffectAst;
77 import org.simantics.scl.compiler.internal.parsing.declarations.DFixityAst;
78 import org.simantics.scl.compiler.internal.parsing.declarations.DInstanceAst;
79 import org.simantics.scl.compiler.internal.parsing.declarations.DMappingRelationAst;
80 import org.simantics.scl.compiler.internal.parsing.declarations.DRelationAst;
81 import org.simantics.scl.compiler.internal.parsing.declarations.DRuleAst;
82 import org.simantics.scl.compiler.internal.parsing.declarations.DTypeAst;
83 import org.simantics.scl.compiler.internal.parsing.declarations.DValueAst;
84 import org.simantics.scl.compiler.internal.parsing.declarations.DValueTypeAst;
85 import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException;
86 import org.simantics.scl.compiler.internal.parsing.translation.ProcessedDClassAst;
87 import org.simantics.scl.compiler.internal.parsing.translation.ProcessedDInstanceAst;
88 import org.simantics.scl.compiler.internal.parsing.translation.RelationRepository;
89 import org.simantics.scl.compiler.internal.parsing.translation.ValueRepository;
90 import org.simantics.scl.compiler.internal.parsing.types.TypeAst;
91 import org.simantics.scl.compiler.module.ConcreteModule;
92 import org.simantics.scl.compiler.module.ImportDeclaration;
93 import org.simantics.scl.compiler.module.repository.ImportFailure;
94 import org.simantics.scl.compiler.module.repository.ImportFailureException;
95 import org.simantics.scl.compiler.types.TCon;
96 import org.simantics.scl.compiler.types.TForAll;
97 import org.simantics.scl.compiler.types.TFun;
98 import org.simantics.scl.compiler.types.TPred;
99 import org.simantics.scl.compiler.types.TVar;
100 import org.simantics.scl.compiler.types.Type;
101 import org.simantics.scl.compiler.types.Types;
102 import org.simantics.scl.compiler.types.kinds.Kind;
103 import org.simantics.scl.compiler.types.kinds.Kinds;
104 import org.simantics.scl.compiler.types.util.MultiFunction;
105 import org.simantics.scl.runtime.profiling.BranchPoint;
107 import gnu.trove.list.array.TIntArrayList;
108 import gnu.trove.map.hash.THashMap;
109 import gnu.trove.map.hash.TObjectIntHashMap;
110 import gnu.trove.procedure.TObjectObjectProcedure;
111 import gnu.trove.set.hash.THashSet;
112 import gnu.trove.set.hash.TIntHashSet;
114 public class Elaboration {
116 private final CompilationContext compilationContext;
117 private final ErrorLog errorLog;
118 private final String moduleName;
119 private final ArrayList<ImportDeclaration> importsAst;
120 final JavaReferenceValidator<Object, Object, Object, Object> javaReferenceValidator;
121 private final ValueRepository valueDefinitionsAst;
122 private final RelationRepository relationDefinitionsAst;
125 ConcreteModule module;
126 Environment importedEnvironment;
127 ArrayList<SupplementedValueType> supplementedTypeAnnotations = new ArrayList<SupplementedValueType>();
129 JavaTypeTranslator javaTypeTranslator;
130 ArrayList<StandardTypeConstructor> dataTypes = new ArrayList<StandardTypeConstructor>();
131 THashMap<String, ClassRef> classRefs = new THashMap<String, ClassRef>();
132 THashMap<String, BranchPoint[]> branchPoints;
134 @SuppressWarnings("unchecked")
135 public Elaboration(CompilationContext compilationContext, CompilationTimer timer, EnvironmentFactory localEnvironmentFactory,
136 String moduleName, ArrayList<ImportDeclaration> importsAst,
137 JavaReferenceValidator<?, ?, ?, ?> javaReferenceValidator,
138 ValueRepository valueDefinitionsAst,
139 RelationRepository relationDefinitionsAst) {
140 this.compilationContext = compilationContext;
141 this.errorLog = compilationContext.errorLog;
142 this.moduleName = moduleName;
143 importsAst = processRelativeImports(importsAst);
144 this.importsAst = importsAst;
145 this.javaReferenceValidator = (JavaReferenceValidator<Object, Object, Object, Object>)javaReferenceValidator;
146 this.valueDefinitionsAst = valueDefinitionsAst;
147 this.relationDefinitionsAst = relationDefinitionsAst;
149 module = new ConcreteModule(moduleName);
150 compilationContext.module = module;
153 timer.suspendTimer();
154 importedEnvironment = localEnvironmentFactory.createEnvironment(
155 importsAst.toArray(new ImportDeclaration[importsAst.size()]));
157 timer.continueTimer();
158 compilationContext.environment = new EnvironmentOfModule(importedEnvironment, module);
159 } catch (ImportFailureException e) {
160 for(ImportFailure failure : e.failures)
161 errorLog.log(failure.location, failure.toString());
164 for(ImportDeclaration importAst : importsAst)
165 this.module.addDependency(new ImportDeclaration(
166 importAst.moduleName,
167 importAst.reexport ? importAst.localName : null,
170 localEnvironmentFactory.addBuiltinDependencies(module);
171 compilationContext.namingPolicy = new JavaNamingPolicy(moduleName);
174 private ArrayList<ImportDeclaration> processRelativeImports(ArrayList<ImportDeclaration> relativeImports) {
175 ArrayList<ImportDeclaration> absoluteImports = new ArrayList<ImportDeclaration>(relativeImports.size());
176 for(ImportDeclaration relativeImport : relativeImports) {
177 if(relativeImport.moduleName.startsWith(".")) {
178 String absoluteModuleName = convertRelativeModulePath(relativeImport.location, relativeImport.moduleName);
179 if(absoluteModuleName != null) {
180 ImportDeclaration absoluteImport = new ImportDeclaration(
181 absoluteModuleName, relativeImport.localName,
182 relativeImport.reexport, relativeImport.spec);
183 absoluteImport.location = relativeImport.location;
184 absoluteImports.add(absoluteImport);
188 absoluteImports.add(relativeImport);
190 return absoluteImports;
193 private String convertRelativeModulePath(long location, String relativeModuleName) {
194 String originalRelativeModuleName = relativeModuleName;
195 int p = moduleName.lastIndexOf('/');
196 String parentPackage = p < 0 ? "" : moduleName.substring(0, p);
197 while(relativeModuleName.startsWith(".")) {
198 if(relativeModuleName.startsWith("./")) {
199 relativeModuleName = relativeModuleName.substring(2);
201 else if(relativeModuleName.startsWith("../")) {
202 relativeModuleName = relativeModuleName.substring(3);
203 if(parentPackage.isEmpty()) {
204 errorLog.log(location, "Couldn't resolve the relative module name " + originalRelativeModuleName + " when the current module name is " + moduleName + ".");
207 p = parentPackage.lastIndexOf('/');
208 parentPackage = p < 0 ? "" : parentPackage.substring(0, p);
211 errorLog.log(location, "Couldn't resolve the relative module name " + originalRelativeModuleName + ". It has an invalid syntax.");
215 return parentPackage + "/" + relativeModuleName;
218 public void addTypesToEnvironment(
219 ArrayList<DDataAst> dataTypesAst,
220 ArrayList<DTypeAst> typeAliasesAst,
221 ArrayList<DEffectAst> effectsAst) {
222 for(DDataAst dataType : dataTypesAst) {
223 dataType.parameterKinds = new Kind[dataType.parameters.length];
224 Kind constructorKind = Kinds.STAR;
225 for(int i=dataType.parameters.length-1;i>=0;--i) {
226 Kind kind = Kinds.metaVar();
227 dataType.parameterKinds[i] = kind;
228 constructorKind = Kinds.arrow(kind, constructorKind);
231 StandardTypeConstructor typeConstructor = new StandardTypeConstructor(
232 Types.con(moduleName, dataType.name), constructorKind);
234 NameExistenceChecks.checkIfTypeExists(errorLog,
235 dataType.location, importedEnvironment, dataType.name);
236 if(module.addTypeDescriptor(dataType.name, typeConstructor))
237 errorLog.log(dataType.location, "Type "+dataType.name+" has already been defined in this module.");
238 dataType.typeConstructor = typeConstructor;
241 for(DTypeAst typeAlias : typeAliasesAst) {
242 TypeAlias alias = new TypeAlias(Types.con(moduleName, typeAlias.name), typeAlias.parameters.length);
243 NameExistenceChecks.checkIfTypeExists(errorLog,
244 typeAlias.location, importedEnvironment, typeAlias.name);
245 if(module.addTypeDescriptor(typeAlias.name, alias)) {
246 errorLog.log(typeAlias.location, "Type alias "+typeAlias.name+" has already been defined in this module.");
250 for(DEffectAst effect : effectsAst) {
251 EffectConstructor effectConstructor = new EffectConstructor(Types.con(moduleName, effect.name));
252 effectConstructor.addThreadLocalVariable(
253 new ThreadLocalVariable(
255 TypeDesc.forClass(effect.threadLocalType)
257 if(module.addEffectConstructor(effect.name, effectConstructor))
258 errorLog.log(effect.location, "Type "+effect.name+" has already been defined in this module.");
260 javaTypeTranslator = new JavaTypeTranslator(compilationContext.environment);
261 compilationContext.javaTypeTranslator = javaTypeTranslator;
264 private static final int[] EMPTY_INT_ARRAY = new int[0];
266 public void processTypeAliases(ArrayList<DTypeAst> typeAliasesAst) {
267 TObjectIntHashMap<String> typeAliasMap = new TObjectIntHashMap<String>();
268 for(int i=0;i<typeAliasesAst.size();++i)
269 typeAliasMap.put(typeAliasesAst.get(i).name, i);
270 TIntHashSet tempIntSet = new TIntHashSet();
271 ArrayList<DTypeAst> orderedTypeAliases = new ArrayList<DTypeAst>(typeAliasesAst.size());
272 //for(int i=0;i<typeAliasesAst.size();++i)
273 // System.out.println(i + "# " + typeAliasesAst.get(i).name);
274 new StronglyConnectedComponents(typeAliasesAst.size()) {
276 protected int[] findDependencies(int u) {
277 typeAliasesAst.get(u).type.collectReferences(typeAliasMap, tempIntSet);
278 if(tempIntSet.isEmpty())
279 return EMPTY_INT_ARRAY;
280 if(tempIntSet.contains(u)) {
281 errorLog.log(typeAliasesAst.get(u).location, "Type alias has a self reference.");
282 tempIntSet.remove(u);
284 int[] result = tempIntSet.toArray();
286 //System.out.println(u + " -> " + Arrays.toString(result));
290 protected void reportComponent(int[] component) {
291 //System.out.println("component: " + Arrays.toString(component));
292 if(component.length > 1) {
293 StringBuilder b = new StringBuilder();
294 b.append("Recursively defined type alias (");
295 long minLocation = typeAliasesAst.get(component[0]).location;
296 boolean first = true;
297 for(int u : component) {
298 DTypeAst typeAlias = typeAliasesAst.get(u);
303 b.append(typeAlias.name);
304 if(Locations.beginOf(typeAlias.location) < Locations.beginOf(minLocation))
305 minLocation = typeAlias.location;
308 errorLog.log(minLocation, b.toString());
311 orderedTypeAliases.add(typeAliasesAst.get(component[0]));
315 if(errorLog.hasNoErrors()) {
316 for(DTypeAst typeAlias : orderedTypeAliases) {
317 TypeAlias alias = (TypeAlias)module.getTypeDescriptor(typeAlias.name);
318 TypeTranslationContext context = createTypeTranslationContext();
319 for(int i=0;i<typeAlias.parameters.length;++i)
320 context.pushTypeVar(typeAlias.parameters[i]);
321 alias.body = typeAlias.type.toType(context, Kinds.metaVar());
322 for(int i=0;i<typeAlias.parameters.length;++i)
323 alias.parameters[i] = context.popTypeVar(typeAlias.parameters[i], null);
328 public void processDataTypes(ArrayList<DDataAst> dataTypesAst) {
329 for(DDataAst dataTypeAst : dataTypesAst) {
330 TypeTranslationContext context = createTypeTranslationContext();
331 TVar[] typeParameters = new TVar[dataTypeAst.parameters.length];
332 for(int i=0;i<dataTypeAst.parameters.length;++i)
333 typeParameters[i] = context.addTypeVar(dataTypeAst.parameters[i]);
334 Constructor[] constructors = new Constructor[dataTypeAst.constructors.length];
335 String className = null;
336 boolean external = false;
337 for(DAnnotationAst annotation : dataTypeAst.getAnnotations()) {
338 if(annotation.id.text.equals("@JavaType")) {
339 if(annotation.parameters.length != 1 ||
340 !(annotation.parameters[0] instanceof ELiteral) ||
341 !(((ELiteral)annotation.parameters[0]).getValue() instanceof StringConstant))
342 errorLog.log(annotation.location, "Invalid parameters. Expected @JavaType \"className\".");
344 className = ((StringConstant)((ELiteral)annotation.parameters[0]).getValue()).getValue().replace('.', '/');
351 boolean trivialDataType = dataTypeAst.constructors.length == 1 &&
352 dataTypeAst.constructors[0].parameters.length == 1;
353 if(className == null && !trivialDataType)
354 className = compilationContext.namingPolicy.getDataTypeClassName(dataTypeAst.name);
356 StandardTypeConstructor dataType = dataTypeAst.typeConstructor;
358 dataType.setType(Types.con(moduleName, dataTypeAst.name), typeParameters);
359 dataType.setConstructors(constructors);
361 dataType.setTypeDesc(TypeDesc.forClass(className));
362 if(!external || dataTypeAst.constructors.length > 0) {
363 dataType.isOpen = false;
365 dataType.external = external;
366 dataTypes.add(dataType);
367 for(int j=0;j<constructors.length;++j) {
368 ConstructorAst constructor = dataTypeAst.constructors[j];
369 String name = constructor.name;
370 Type[] parameterTypes = new Type[constructor.parameters.length];
371 for(int i=constructor.parameters.length-1;i>=0;--i)
372 parameterTypes[i] = context.toType(constructor.parameters[i]);
373 String javaName = constructors.length == 1 ? className
374 : compilationContext.namingPolicy.getConstructorClassName(name);
375 String[] fieldNames = null;
376 for(DAnnotationAst annotation : constructor.annotations)
377 if(annotation.id.text.equals("@JavaType")) {
379 javaName = ((StringConstant)((ELiteral)annotation.parameters[0])
380 .getValue()).getValue();
381 } catch(Exception e) {
382 errorLog.log(annotation.parameters[0].location, "Invalid annotation parameter.");
385 else if(annotation.id.text.equals("@FieldNames")) {
387 EListLiteral literal = (EListLiteral)annotation.parameters[0];
388 fieldNames = new String[literal.getComponents().length];
389 for(int i=0;i<fieldNames.length;++i) {
390 Expression component = literal.getComponents()[i];
391 if(component instanceof EVar)
392 fieldNames[i] = ((EVar)component).name;
393 else if(component instanceof ELiteral)
394 fieldNames[i] = ((StringConstant)((ELiteral)component).getValue()).getValue();
396 } catch(Exception e) {
397 errorLog.log(annotation.parameters[0].location, "Invalid annotation parameter.");
402 constructors[j] = new Constructor(constructor.location, dataType,
403 Name.create(moduleName, name),
404 parameterTypes, javaName);
405 constructors[j].fieldNames = fieldNames;
406 constructors[j].recordFieldNames = constructor.fieldNames;
411 public void processTypeClasses(ArrayList<ProcessedDClassAst> typeClassesAst) {
412 for(ProcessedDClassAst pClassAst : typeClassesAst) {
413 DClassAst classAst = pClassAst.orig;
415 if(module.getTypeClass(classAst.name) != null) {
416 errorLog.log(classAst.location, "Class "+classAst.name+" has already been defined in this module.");
420 TypeTranslationContext context = createTypeTranslationContext();
422 TPred[] classContext = new TPred[classAst.context.length];
423 for(int i=0;i<classContext.length;++i)
424 classContext[i] = context.toTFuncApply(classAst.context[i]);
426 TVar[] parameters = new TVar[classAst.parameters.length];
428 if(classAst.name.equals("Functor") || classAst.name.equals("Monad")) {
430 parameters[0] = context.resolveTypeVariable(pClassAst.orig.location, classAst.parameters[0], Kinds.STAR_TO_STAR);
433 for(int i=0;i<parameters.length;++i)
434 parameters[i] = context.resolveTypeVariable(pClassAst.orig.location, classAst.parameters[i], Kinds.metaVar());
437 TCon con = Types.con(moduleName, classAst.name);
438 TypeClass typeClass = new TypeClass(classAst.location,
441 compilationContext.namingPolicy.getTypeClassInterfaceName(con),
443 Fundep.mapFundeps(classAst.parameters, classAst.fundeps));
445 THashMap<String, TypeClassMethod> methods = typeClass.methods;
446 for(DValueTypeAst methodDecl : pClassAst.typeDeclarations) {
450 type = context.toType(methodDecl.type);
451 } catch(SCLSyntaxErrorException e) {
452 errorLog.log(e.location, e.getMessage());
455 for(EVar name : methodDecl.names) {
456 typeClass.methodNames.add(name.name);
457 methods.put(name.name,
458 new TypeClassMethod(typeClass, name.name,
459 compilationContext.namingPolicy.getMethodName(name.name),
460 type, Types.getArity(type),
464 } catch(RuntimeException e) {
465 errorLog.setExceptionPosition(methodDecl.location);
470 for(String methodName : pClassAst.defaultImplementations.getValueNames()) {
471 String fullName = "_" + classAst.name + "_default_" + methodName;
472 ArrayList<DValueAst> defs = pClassAst.defaultImplementations.getDefinition(methodName);
474 TypeClassMethod method = typeClass.methods.get(methodName);
476 errorLog.log(defs.get(0).location, "Method " + methodName + " is not defined in this class.");
479 method.setDefaultImplementation(Name.create(moduleName, fullName));
481 valueDefinitionsAst.addDefinitions(fullName, defs);
482 /*valueDefinitionsAst.addAnnotation(fullName, new DAnnotationAst(new EVar("@private"),
483 Collections.<Expression>emptyList()));*/
484 supplementedTypeAnnotations.add(new SupplementedValueType(defs.get(0).location, fullName, method.getType()));
487 module.addTypeClass(classAst.name, typeClass);
491 private TypeTranslationContext createTypeTranslationContext() {
492 return new TypeTranslationContext(compilationContext);
495 public void processDerivingInstances(ArrayList<DDerivingInstanceAst> derivingInstancesAst,
496 ArrayList<ProcessedDInstanceAst> instancesAst) {
497 for(DDerivingInstanceAst derivingInstance : derivingInstancesAst) {
498 String name = derivingInstance.name.name;
501 con = Environments.getTypeClassName(compilationContext.environment, name);
502 } catch (AmbiguousNameException e) {
503 errorLog.log(derivingInstance.name.location, e.getMessage());
507 errorLog.log(derivingInstance.name.location, "Couldn't resolve class " + name + ".");
510 InstanceDeriver deriver = InstanceDerivers.get(con);
512 errorLog.log(derivingInstance.location, "Doesn't know how to derive " + name + ".");
514 deriver.derive(errorLog, compilationContext.environment, instancesAst, derivingInstance);
518 public void processInstances(ArrayList<ProcessedDInstanceAst> instancesAst) {
519 THashSet<TPred> instanceClashCheckSet = new THashSet<TPred>();
520 for(ProcessedDInstanceAst pInstanceAst : instancesAst) {
521 DInstanceAst instanceAst = pInstanceAst.orig;
523 TypeTranslationContext context = createTypeTranslationContext();
525 String name = instanceAst.name.name;
528 typeClassCon = Environments.getTypeClassName(compilationContext.environment, name);
529 } catch (AmbiguousNameException e) {
530 errorLog.log(instanceAst.name.location, e.getMessage());
533 if(typeClassCon == null) {
534 errorLog.log(instanceAst.name.location, "Couldn't resolve class " + name + ".");
537 TypeClass typeClass = compilationContext.environment.getTypeClass(typeClassCon);
538 pInstanceAst.typeClass = typeClass;
540 if(instanceAst.types.length != typeClass.parameters.length) {
541 errorLog.log(instanceAst.location, "Wrong number of parameters to type class " + typeClassCon.name + ".");
544 Type[] parameters = new Type[instanceAst.types.length];
545 for(int i=0;i<parameters.length;++i)
546 parameters[i] = context.toType(instanceAst.types[i], typeClass.parameters[i].getKind() /* FIXME */);
547 TPred instance = Types.pred(typeClassCon, parameters);
549 if(!instanceClashCheckSet.add(instance)) {
550 errorLog.log(instanceAst.location, "Duplicate definition of the instance " + instance + ".");
554 TPred[] instanceContext = new TPred[instanceAst.context.length];
555 for(int i=0;i<instanceContext.length;++i)
556 instanceContext[i] = context.toTFuncApply(instanceAst.context[i]);
558 String javaName = compilationContext.namingPolicy.getInstanceClassName(instance);
559 String instancePrefix = instance.toName() + "$";
561 ValueRepository valueDefs = pInstanceAst.valueDefs;
563 THashMap<String, MethodImplementation> methodImplementations =
564 new THashMap<String, MethodImplementation>();
565 for(String valueName : valueDefs.getValueNames()) {
566 String fullName = instancePrefix + valueName;
567 long loc = valueDefs.getDefinition(valueName).get(0).location;
568 valueDefinitionsAst.addFrom(valueDefs, valueName, fullName);
569 /*valueDefinitionsAst.addAnnotation(fullName, new DAnnotationAst(new EVar("@private"),
570 Collections.<Expression>emptyList()));*/
571 TypeClassMethod method = typeClass.methods.get(valueName);
573 errorLog.log(loc, "Method " + valueName + " is not defined in the type class " + typeClass.name.name + ".");
576 Type type = method.getBaseType().replace(typeClass.parameters, parameters);
577 for(int i=instanceContext.length-1;i>=0;--i)
578 type = Types.constrained(instanceContext[i], type);
579 //System.out.println(valueName + " :: " + type);
580 supplementedTypeAnnotations.add(
581 new SupplementedValueType(loc, fullName, type));
582 methodImplementations.put(valueName,
583 new MethodImplementation(Name.create(moduleName, fullName), false));
586 // Are all necessary methods defined
587 for(String methodName : typeClass.methods.keySet())
588 if(!methodImplementations.containsKey(methodName)) {
589 Name defaultImplementation = typeClass.methods.get(methodName).getDefaultImplementation();
590 if(defaultImplementation == null)
591 errorLog.log(instanceAst.location, "Method " + methodName + " is not defined.");
593 methodImplementations.put(methodName,
594 new MethodImplementation(defaultImplementation, true));
597 JavaTypeInstanceConstructor generator = new JavaTypeInstanceConstructor(javaName, instance, instanceContext);
598 if(instanceContext.length == 0)
599 generator.setHasStaticInstance(true);
601 TypeClassInstance typeClassInstance =
602 new TypeClassInstance(instanceAst.location, typeClass, generator,
603 generator.getTypeParameters(),
604 instanceContext, instance, methodImplementations,
607 generator.setInstance(typeClassInstance);
609 module.addTypeClassInstance(typeClassCon, typeClassInstance);
610 } catch(RuntimeException e) {
611 errorLog.setExceptionPosition(instanceAst.location);
616 // Generate superclass functions
617 for(ArrayList<TypeClassInstance> instanceArray : module.getTypeInstances().values())
618 for(TypeClassInstance instance : instanceArray) {
620 TypeClass typeClass = instance.typeClass;
621 int superCount = typeClass.context.length;
623 instance.superExpressions = new SCLValue[superCount];
624 for(int i=0;i<superCount;++i) {
625 TPred type = (TPred)typeClass.context[i]
626 .replace(typeClass.parameters, instance.instance.parameters);
627 SCLValue value = new SCLValue(Name.create(moduleName,
628 instance.javaName.substring(instance.javaName.indexOf('$')+1) + "_super" + i));
629 //value.addProperty(PrivateProperty.INSTANCE);
630 module.addValue(value);
631 Expression expression = new EGetConstraint(instance.location, type);
632 value.setExpression(expression);
633 value.setType(Types.forAll(instance.generatorParameters, Types.constrained(instance.context, type)));
634 value.getProperties().add(new InlineProperty(instance.context.length, 0xffffffff));
635 //TypeUnparsingContext tuc = new TypeUnparsingContext();
636 // TODO error handling
637 instance.superExpressions[i] = value;
639 } catch(RuntimeException e) {
640 errorLog.setExceptionPosition(instance.getLocation());
646 public void processJavaMethods(ArrayList<JavaMethodDeclaration> javaMethodDeclarations) {
647 for(JavaMethodDeclaration javaMethod : javaMethodDeclarations) {
648 String name = javaMethod.methodName.name;
649 String javaName = name;
650 ArrayList<DAnnotationAst> annotations =
651 valueDefinitionsAst.getAnnotations(name);
652 boolean isPrivate = false;
653 if(annotations != null) {
654 for(DAnnotationAst annotation : annotations)
655 if(annotation.id.text.equals("@JavaName")) {
656 Expression p0 = annotation.parameters[0];
657 if(p0 instanceof EVar)
658 javaName = ((EVar)p0).name;
659 else if(p0 instanceof ELiteral) {
660 ELiteral lit = (ELiteral)p0;
661 javaName = ((StringConstant)lit.getValue()).getValue();
664 else if(annotation.id.text.equals("@private")) {
669 Type type = createTypeTranslationContext().toType(javaMethod.type);
671 CallJava callJava = resolveMethod(
673 javaMethod.className,
676 if(callJava != null) {
677 NameExistenceChecks.checkIfValueExists(errorLog, javaMethod.location,
678 importedEnvironment, name);
679 SCLValue value = module.addValue(name, callJava);
680 value.definitionLocation = javaMethod.methodName.location;
682 value.addProperty(PrivateProperty.INSTANCE);
688 * Convert a java class method into a {@link CallJava} instance.
689 * Compilation errors are logged for failures in finding the named class or in accessing the method.
690 * The return value for errors is {@code null}.
692 * @param loc SCL source location
693 * @param className Name of the class
694 * @param methodName Name of the method
695 * @param type The expected SCL type of the method
696 * @return A new JavaCall instance, or null if the given method can not be instantiated.
698 private CallJava resolveMethod(long loc,
699 String className, String methodName, Type type) {
701 ClassRef classRef = classRefs.get(className);
702 if(classRef == null) {
703 if(classRefs.containsKey(className))
705 classRef = javaReferenceValidator.getClassRef(className);
706 classRefs.put(className, classRef);
707 if(classRef == null) {
708 errorLog.log(loc, "Didn't find class " + className + ".");
711 if(!javaReferenceValidator.isPublic(classRef.getClass())) {
712 errorLog.log(loc, "Class " + className + " is not public.");
719 List<MethodRef> methodRefs = classRef.getMethodRefs(methodName);
720 if(methodRefs.isEmpty()) {
721 errorLog.log(loc, "Didn't find any public method or field with name '" + methodName + "' from class " + className + ".");
725 ArrayList<CallJava> candidates = new ArrayList<CallJava>(2);
726 for(MethodRef methodRef : methodRefs) {
727 CallJava candidate = matchType(methodRef, type);
728 if(candidate != null)
729 candidates.add(candidate);
732 if(candidates.isEmpty()) {
733 StringBuilder b = new StringBuilder();
734 b.append("Didn't find any public method or field matching the type " + type + ". The following methods and fields were tried:");
735 for(MethodRef methodRef : methodRefs) {
739 b.append("\nbut expected something like:");
741 MultiFunction mFun = Types.matchFunction(type);
742 b.append("\n public static ");
743 b.append(javaTypeTranslator.toTypeDesc(mFun.returnType).getFullName()).append(' ').append(methodName).append('(');
744 boolean first = true;
745 for(Type parameter : mFun.parameterTypes) {
750 b.append(javaTypeTranslator.toTypeDesc(parameter).getFullName());
754 errorLog.log(loc, b.toString());
757 else if(candidates.size() == 1)
758 return candidates.get(0);
760 // Try to find the best match
761 ArrayList<CallJava> bestCandidates = new ArrayList<CallJava>(candidates.size());
762 loop: for(CallJava candidate : candidates) {
763 Iterator<CallJava> it = bestCandidates.iterator();
764 while(it.hasNext()) {
765 CallJava b = it.next();
766 switch(candidate.compareTo(javaReferenceValidator, b)) {
770 case CallJava.GREATER:
773 case CallJava.INCOMPARABLE:
777 bestCandidates.add(candidate);
780 if(bestCandidates.size() == 1) {
781 // System.out.println("Choose: " + bestCandidates.get(0).getMethodRef());
782 return bestCandidates.get(0);
785 StringBuilder b = new StringBuilder();
786 b.append("Found more than one incomparable public methods the type " + type + ":");
787 for(CallJava callJava : bestCandidates) {
789 b.append(callJava.getMethodRef());
791 errorLog.log(loc, b.toString());
797 private CallJava matchType(MethodRef methodRef, Type type) {
798 //System.out.println("-----------------------------------------------------");
799 //System.out.println("method: " + methodRef);
800 //System.out.println("type: " + type);
802 type = Types.canonical(type);
803 while(type instanceof TForAll)
804 type = Types.canonical(((TForAll)type).type);
806 TypeDesc[] expectedParameterTypes = methodRef.getParameterTypes();
808 ArrayList<Type> parameterTypes = new ArrayList<Type>();
809 Type effect = Types.NO_EFFECTS;
810 Type returnType = type;
812 StackItem[] stackItems = new StackItem[expectedParameterTypes.length];
813 TIntArrayList unresolvedItems = new TIntArrayList();
816 for(int i=0;i<expectedParameterTypes.length;++i) {
818 TypeDesc providedParameterType;
820 if(effect != Types.NO_EFFECTS || !(returnType instanceof TFun)) {
821 while(i < expectedParameterTypes.length)
822 unresolvedItems.add(i++);
825 TFun fun = (TFun)returnType;
826 parameterType = Types.canonical(fun.domain);
827 parameterTypes.add(parameterType);
828 effect = Types.canonical(fun.effect);
829 returnType = Types.canonical(fun.range);
830 providedParameterType = javaTypeTranslator.toTypeDesc(parameterType);
831 } while(providedParameterType.equals(TypeDesc.VOID));
834 TypeDesc expectedParameterType = expectedParameterTypes[i];
835 if(javaReferenceValidator.isAssignableFrom(expectedParameterType,
836 providedParameterType)) {
837 stackItems[i] = new ParameterStackItem(
838 parameterTypes.size()-1,
843 unresolvedItems.add(i++);
844 if(i == expectedParameterTypes.length) {
845 parameterTypes.remove(parameterTypes.size()-1);
846 returnType = Types.functionE(parameterType, effect, returnType);
851 //System.out.println("returnType: " + returnType);
852 if(!unresolvedItems.isEmpty()) {
853 ArrayList<TCon> concreteEffects = new ArrayList<TCon>();
854 effect.collectConcreteEffects(concreteEffects);
856 for(TCon eff : concreteEffects) {
857 EffectConstructor effC = compilationContext.environment.getEffectConstructor(eff);
858 for(ThreadLocalVariable var : effC.getThreadLocalVariables()) {
859 for(int i=0;i<unresolvedItems.size();++i) {
860 int id = unresolvedItems.get(i);
861 if(!expectedParameterTypes[id].equals(TypeDesc.OBJECT) &&
862 javaReferenceValidator.isAssignableFrom(expectedParameterTypes[id], var.type)) {
863 stackItems[id] = new ThreadLocalStackItem(var.variableName, var.type);
864 unresolvedItems.removeAt(i);
871 if(!unresolvedItems.isEmpty())
873 /*System.out.print("Unresolved: ");
874 boolean first = true;
875 for(int i=0;i<unresolvedItems.size();++i) {
879 System.out.print(", ");
880 System.out.print(expectedParameterTypes[unresolvedItems.get(i)]);
882 System.out.println();*/
884 OutputFilter filter = null;
886 TypeDesc providedReturnType = methodRef.getReturnType();
887 if(!providedReturnType.equals(Constants.FUNCTION)) {
888 while(returnType instanceof TFun && effect == Types.NO_EFFECTS) {
889 TFun fun = (TFun)returnType;
890 Type parameterType = Types.canonical(fun.domain);
891 if(!javaTypeTranslator.toTypeDesc(parameterType).equals(TypeDesc.VOID))
893 parameterTypes.add(parameterType);
894 effect = Types.canonical(fun.effect);
895 returnType = Types.canonical(fun.range);
898 TypeDesc expectedReturnType =
899 javaTypeTranslator.toTypeDesc(returnType);
900 if(!javaReferenceValidator.isAssignableFrom(expectedReturnType,
901 providedReturnType)) {
902 if(expectedReturnType.equals(TypeDesc.VOID)) {
903 if(providedReturnType.equals(TypeDesc.DOUBLE) || providedReturnType.equals(TypeDesc.LONG))
904 filter = Pop2OutputFilter.INSTANCE;
906 filter = PopOutputFilter.INSTANCE;
908 else if(expectedReturnType.equals(Constants.LIST)
909 && providedReturnType.equals(Constants.COLLECTION))
910 filter = ConvertToListFilter.INSTANCE;
916 CallJava result = new CallJava(
917 Types.freeVarsArray(type),
920 parameterTypes.toArray(new Type[parameterTypes.size()]),
924 //System.out.println(result.getType());
928 public void processMappingRelations(ArrayList<DMappingRelationAst> mappingRelationsAst) {
929 for(DMappingRelationAst mappingRelation : mappingRelationsAst) {
930 TypeAst[] parameterTypesAst = mappingRelation.parameterTypes;
931 Type[] parameterTypes = new Type[parameterTypesAst.length];
932 TypeTranslationContext typeTranslationContext = createTypeTranslationContext();
933 for(int i=0;i<parameterTypes.length;++i)
934 parameterTypes[i] = parameterTypesAst[i].toType(typeTranslationContext, Kinds.STAR);
935 MappingRelation mRel =
936 new MappingRelation(Name.create(moduleName, mappingRelation.name), parameterTypes);
937 mRel.location = mappingRelation.location;
938 if(module.addMappingRelation(mRel))
939 errorLog.log(mappingRelation.location, "Mapping relation " + mappingRelation.name +
940 " has already been defined.");
944 THashMap<String, DRuleAst> ruleAstMap = new THashMap<String, DRuleAst>();
946 public void processRules(ArrayList<DRuleAst> rulesAst) {
947 // Find implied mapping relations
948 for(DRuleAst ruleA : rulesAst) {
949 ArrayList<Query> whereSection = ruleA.getSections().get("where");
950 if(whereSection != null)
951 for(Query query : whereSection) {
952 if(!(query instanceof QPreGuard))
954 QPreGuard guard = (QPreGuard)query;
955 if(!(guard.guard instanceof EApply))
957 EApply apply = (EApply)guard.guard;
958 if(!(apply.getFunction() instanceof EVar))
961 String name = ((EVar)apply.getFunction()).name;
962 if(module.getMappingRelation(name) != null)
965 int arity = apply.getParameters().length;
966 Type[] parameterTypes = new Type[arity];
967 for(int i=0;i<arity;++i)
968 parameterTypes[i] = Types.metaVar(Kinds.STAR);
969 MappingRelation mRel =
970 new MappingRelation(Name.create(moduleName, name), parameterTypes);
971 mRel.location = query.location;
972 module.addMappingRelation(mRel);
974 if(ruleAstMap.put(ruleA.name, ruleA) != null)
975 errorLog.log(ruleA.location, "Rule " + ruleA.name +
976 " has already been defined.");
980 for(String ruleName : ruleAstMap.keySet())
981 processRule(ruleName);
984 private TransformationRule processRule(String ruleName) {
985 TransformationRule rule = module.getRule(ruleName);
989 DRuleAst ruleAst = ruleAstMap.get(ruleName);
990 if(ruleAst.alreadyProcessing) {
991 errorLog.log(ruleAst.location, "Cyclic chain of rule extensions.");
995 TransformationRule[] extendsRules;
996 int length = ruleAst.extendsNames.length;
998 extendsRules = TransformationRule.EMPTY_ARRAY;
1000 extendsRules = new TransformationRule[length];
1001 for(int i=0;i<length;++i) {
1003 String extendsName = ruleAst.extendsNames[i];
1004 TransformationRule extendsRule;
1005 if(ruleAstMap.containsKey(extendsName))
1006 extendsRule = processRule(extendsName);
1008 extendsRule = Environments.getRule(compilationContext.environment, extendsName);
1009 if(extendsRule == null)
1010 errorLog.log(ruleAst.location,
1011 "Couldn't resolve rule name " + extendsName + ".");
1013 extendsRules[i] = extendsRule;
1014 } catch(AmbiguousNameException e) {
1015 errorLog.log(ruleAst.location, e.getMessage());
1020 final THashMap<SectionName, Query[]> sections = new THashMap<SectionName, Query[]>();
1022 final TranslationContext context = createTranslationContext();
1024 THashMap<String, Variable> variables = context.getVariables();
1025 for(TransformationRule extendsRule : extendsRules) {
1026 if(extendsRule == null)
1028 for(Variable var : extendsRule.variables)
1029 if(variables.put(var.getName(), var) != null) {
1030 errorLog.log(ruleAst.location,
1031 "Variable " + var.getName() + " is defined in more than one base rule, which is not currently allowed.");
1035 context.pushExistentialFrame();
1036 ruleAst.getSections().forEachEntry(new TObjectObjectProcedure<String, ArrayList<Query>>() {
1038 public boolean execute(String sectionNameString, ArrayList<Query> queries) {
1039 Query[] resolvedQueries = new Query[queries.size()];
1040 for(int i=0;i<resolvedQueries.length;++i)
1041 resolvedQueries[i] = queries.get(i).resolve(context);
1043 SectionName sectionName = SectionName.getSectionName(sectionNameString);
1044 if(sectionName == null)
1045 context.getErrorLog().log(queries.get(0).location,
1046 "Invalid section name " + sectionNameString + ".");
1048 sections.put(sectionName, resolvedQueries);
1053 Variable[] variables = context.getVariables().values().toArray(new Variable[context.getVariables().size()]);
1055 rule = new TransformationRule(ruleAst.isAbstract,
1056 Name.create(moduleName, ruleAst.name),
1058 sections, variables);
1059 rule.location = ruleAst.location;
1060 module.addRule(rule);
1064 public void addDataTypesToEnvironment() {
1065 for(StandardTypeConstructor dataType : dataTypes) {
1066 int constructorTag = 0;
1067 for(Constructor constructor : dataType.constructors) {
1068 SCLValue value = new SCLValue(constructor.name);
1069 SCLConstructor sclConstructor =
1071 constructor.name.name,
1072 constructor.javaName,
1073 constructor.getTypeVariables(),
1075 constructor.getReturnType(),
1076 constructor.fieldNames == null
1077 ? SCLConstructor.DEFAULT_FIELD_NAMES[constructor.getParameterTypes().length]
1078 : constructor.fieldNames,
1079 constructor.recordFieldNames,
1080 constructor.getParameterTypes());
1081 if(dataType.constructors.length == 1 && (
1082 dataType.getTypeDesc() == null ||
1083 dataType.constructors[0].javaName.equals(MethodBuilderBase.getClassName(dataType.getTypeDesc()))))
1084 sclConstructor.setOnlyConstructor(true);
1085 value.setValue(sclConstructor);
1086 value.setType(constructor.getType());
1088 NameExistenceChecks.checkIfValueExists(errorLog, constructor.loc,
1089 importedEnvironment, constructor.name.name);
1090 if(module.addValue(value)) {
1091 errorLog.log(constructor.loc,
1092 "Value " + constructor.name.name + " is already defined.");
1098 public void addTypeClassesToEnvironment() {
1099 for(TypeClass typeClass : module.getTypeClasses()) {
1100 for(TypeClassMethod method : typeClass.methods.values()) {
1101 SCLValue value = method.createValue();
1102 value.definitionLocation = method.location;
1103 NameExistenceChecks.checkIfValueExists(errorLog, Locations.NO_LOCATION,
1104 importedEnvironment, value.getName().name);
1106 if(module.addValue(value)) {
1107 String name = method.getName();
1108 long location = Locations.NO_LOCATION;
1109 ArrayList<DValueAst> definitions = valueDefinitionsAst.getDefinition(name);
1110 if(definitions != null && !definitions.isEmpty())
1111 location = definitions.get(0).location;
1112 errorLog.log(location, "Value " + name + " is already defined.");
1118 public void preprocessValueDefinitions(ArrayList<DValueTypeAst> typeAnnotationsAst) {
1119 for(String name : valueDefinitionsAst.getValueNames()) {
1120 SCLValue value = new SCLValue(Name.create(moduleName, name));
1122 long location = valueDefinitionsAst.getLocation(name);
1123 NameExistenceChecks.checkIfValueExists(errorLog, location,
1124 importedEnvironment, value.getName().name);
1125 value.definitionLocation = location;
1126 if(module.addValue(value))
1127 errorLog.log(location, "Value " + name + " is already defined.");
1129 for(DValueTypeAst valueTypeAst : typeAnnotationsAst)
1130 for(EVar name : valueTypeAst.names) {
1131 SCLValue value = module.getValue(name.name);
1133 errorLog.log(valueTypeAst.location, name.name + " is not defined.");
1134 value = new SCLValue(Name.create(moduleName, name.name));
1135 module.addValue(value);
1137 value.definitionLocation = name.location;
1139 for(String name : relationDefinitionsAst.getRelationNames()) {
1140 ConcreteRelation relation = new ConcreteRelation(name);
1141 module.addRelation(name, relation);
1145 public void addValueDefinitionsToEnvironment(ArrayList<DValueTypeAst> typeAnnotationsAst) {
1146 THashMap<String, DValueTypeAst> typeMap = new THashMap<String, DValueTypeAst>();
1147 for(DValueTypeAst valueTypeAst : typeAnnotationsAst)
1148 for(EVar name : valueTypeAst.names) {
1149 if(typeMap.containsKey(name.name))
1150 errorLog.log(valueTypeAst.location, "Type of "+name.name+" has already been declared in this module.");
1152 typeMap.put(name.name, valueTypeAst);
1155 for(String name : valueDefinitionsAst.getValueNames()) {
1156 ArrayList<DValueAst> defs = valueDefinitionsAst.getDefinition(name);
1158 SCLValue value = module.getValue(name);
1159 TranslationContext context = createTranslationContext();
1160 Expression expression = context.translateCases2(defs);
1161 value.setExpression(expression);
1163 DValueTypeAst valueTypeAst = typeMap.remove(name);
1164 if(valueTypeAst != null)
1165 value.setType(Types.closure(context.toType(valueTypeAst.type)));
1167 ArrayList<DAnnotationAst> annotations = valueDefinitionsAst.getAnnotations(name);
1168 if(annotations != null)
1169 for(DAnnotationAst annotation : annotations) {
1170 handleAnnotation(value, defs, annotation);
1172 } catch(RuntimeException e) {
1173 errorLog.setExceptionPosition(defs.get(0).location);
1177 for(String name : relationDefinitionsAst.getRelationNames()) {
1178 ArrayList<DRelationAst> definitions = relationDefinitionsAst.getDefinition(name);
1179 if(definitions.size() > 1) {
1180 errorLog.log(definitions.get(1).location,
1181 "Does not yet support definition of relations by more than one rule.");
1185 DRelationAst definition = definitions.get(0);
1186 ConcreteRelation relation = (ConcreteRelation)module.getRelation(name);
1187 relation.location = definition.location;
1188 TranslationContext context = createTranslationContext();
1189 definition.translateTo(context, relation);
1193 private TranslationContext createTranslationContext() {
1194 return new TranslationContext(compilationContext, null);
1197 private void handleAnnotation(SCLValue value, ArrayList<DValueAst> defs, DAnnotationAst annotation) {
1198 if(annotation.id.text.equals("@macro")) {
1199 value.setMacroRule(new StandardMacroRule());
1201 else if(annotation.id.text.equals("@inline")) {
1203 int arity = defs.get(0).lhs.getFunctionDefinitionPatternArity();
1204 int phaseMask = 0xffffffff;
1205 if(annotation.parameters.length > 0) {
1206 phaseMask = Integer.parseInt(((EIntegerLiteral)annotation.parameters[0]).getValue());
1208 value.addProperty(new InlineProperty(arity, phaseMask));
1209 } catch(NotPatternException e) {
1210 errorLog.log(annotation.location, "Inline annotation is invalid: this is not a function.");
1213 else if(annotation.id.text.equals("@private")) {
1214 value.addProperty(PrivateProperty.INSTANCE);
1216 else if(annotation.id.text.equals("@deprecated")) {
1217 String description = "";
1218 if(annotation.parameters.length > 0) {
1219 if(annotation.parameters.length > 1)
1220 errorLog.log(annotation.location, "Invalid number of parameters, expected one string.");
1222 String temp = AnnotationUtils.extractString(annotation.parameters[0]);
1224 errorLog.log(annotation.location, "Invalid parameter, expected one string.");
1229 value.addProperty(new DeprecatedProperty(description));
1232 errorLog.log(annotation.location, "Unknown annotation.");
1235 public void addSupplementedTypeAnnotationsToEnvironment() {
1236 for(SupplementedValueType valueType : supplementedTypeAnnotations) {
1237 Type type = Types.closure(valueType.type);
1238 String name = valueType.name;
1239 SCLValue value = module.getValue(name);
1241 errorLog.log(valueType.position,
1242 name + " is not defined.");
1243 else if(value.getType()==null)
1244 value.setType(type);
1246 errorLog.log(valueType.position,
1247 "Type of "+name+" has already been declared in this module.");
1251 public void addFixityToEnvironment(ArrayList<DFixityAst> fixityAst) {
1252 for(DFixityAst fixity : fixityAst) {
1253 for(EVar symbol : fixity.symbols) {
1254 String name = symbol.name;
1255 SCLValue value = module.getValue(name);
1257 errorLog.log(symbol.location,
1258 name + " is not defined.");
1260 value.setPrecedence(fixity.precedence);
1265 public void addCoverageBranchPoints() {
1266 branchPoints = new THashMap<String, BranchPoint[]>();
1267 BranchPointInjector injector = new BranchPointInjector();
1268 for(String valueName : valueDefinitionsAst.getValueNames()) {
1269 for(DValueAst valueAst : valueDefinitionsAst.getDefinition(valueName))
1270 valueAst.value = injector.injectBranchPoint(valueAst.value);
1271 branchPoints.put(valueName, injector.getAndClearBranchPoints());