org.simantics.scl.compiler.markdown.nodes,
org.simantics.scl.compiler.module,
org.simantics.scl.compiler.module.coverage,
+ org.simantics.scl.compiler.module.debug,
org.simantics.scl.compiler.module.options,
org.simantics.scl.compiler.module.repository,
org.simantics.scl.compiler.runtime,
--- /dev/null
+module {
+ features = [edo],
+ export = [whoCalls, unusedDefinitions]
+}
+
+import "SCL/Reflection"
+
+@JavaType "org.simantics.scl.compiler.module.debug.SymbolReference"
+data SymbolReference =
+ @JavaType "org.simantics.scl.compiler.module.debug.SymbolReference"
+ @FieldNames [referred, referrer, referenceLocation]
+ SymbolReference {referred :: Name, referrer :: String, referenceLocation :: Location}
+
+importJava "org.simantics.scl.compiler.module.debug.ModuleDebugInfo" where
+ data ModuleDebugInfo
+
+ symbolReferences :: ModuleDebugInfo -> [SymbolReference]
+
+importJava "org.simantics.scl.compiler.module.Module" where
+ @JavaName "getModuleDebugInfo"
+
+ debugInfo :: Module -> Maybe ModuleDebugInfo
+
+whoCalls :: String -> String -> <Proc> [(String, String, Long)]
+whoCalls moduleName valueName =
+ [ (callerModuleName, referrer, referenceLocation)
+ | callerModuleName <- sclModuleNames
+ , Just callerModule = moduleByName callerModuleName
+ , Just debugInfo = debugInfo callerModule
+ , SymbolReference {referred, referrer, referenceLocation} <- symbolReferences debugInfo
+ , referred == name
+ ]
+ where
+ name = createName moduleName valueName
+
+unusedDefinitions :: <Proc> [Name]
+unusedDefinitions =
+ [ createName moduleName def
+ | moduleName <- sclModuleNames
+ , Just module = moduleByName moduleName
+ , def <- valueNamesOf module
+ ]
+ \\
+ [ referred
+ | callerModuleName <- sclModuleNames
+ , Just callerModule = moduleByName callerModuleName
+ , Just debugInfo = debugInfo callerModule
+ , SymbolReference {referred} <- symbolReferences debugInfo
+ ]
\ No newline at end of file
module {
- export = [possibleUnsafeSclValueByName, unsafeSclValueByName, sclModuleNames]
+ export = [possibleUnsafeSclValueByName, unsafeSclValueByName, sclModuleNames, moduleByName,
+ moduleOf, nameOf, createName, valueNamesOf]
}
include "SCL/ReflectionJava"
@JavaName getSourceRepository
moduleSourceRepositoryOf :: ModuleRepository -> ModuleSourceRepository
+ @JavaName getModule
+ moduleByName_ :: ModuleRepository -> String -> <Proc> Failable Module
+
importJava "org.simantics.scl.compiler.source.repository.ModuleSourceRepository" where
data ModuleSourceRepository
@JavaName getModuleNames
sclModuleNames_ :: ModuleSourceRepository -> [String]
+
+importJava "org.simantics.scl.compiler.errors.Failable" where
+ data Failable a
+
+ didSucceed :: Failable a -> Boolean
+ getResult :: Failable a -> Maybe a
+
+importJava "org.simantics.scl.compiler.module.Module" where
+ data Module
+
+ @JavaName getValueNames
+ valueNamesOf_ :: Module -> [String]
+
+importJava "org.simantics.scl.compiler.common.names.Name" where
+ data Name
+
+ @JavaName module
+ moduleOf_ :: Name -> String
+ @JavaName name
+ nameOf_ :: Name -> String
+
+ @JavaName create
+ createName_ :: String -> String -> Name
+
+instance Show Name where
+ sb <+ n = sb << moduleOf n << "/" << nameOf n
+
+moduleOf = moduleOf_
+nameOf = nameOf_
+createName = createName_
+valueNamesOf = valueNamesOf_
+
+type Location = Long
unsafeSclValueByName :: String -> <Proc> a
unsafeSclValueByName = unsafeSclValueByName_ MODULE_REPOSITORY
sclModuleNames :: <Proc> [String]
sclModuleNames = sclModuleNames_ (moduleSourceRepositoryOf MODULE_REPOSITORY)
+
+moduleByName :: String -> <Proc> Maybe Module
+moduleByName name = getResult failable
+ where
+ failable = moduleByName_ MODULE_REPOSITORY name
\ No newline at end of file
import org.simantics.scl.compiler.internal.codegen.utils.JavaNamingPolicy;
import org.simantics.scl.compiler.internal.header.ModuleHeader;
import org.simantics.scl.compiler.module.ConcreteModule;
+import org.simantics.scl.compiler.module.debug.ModuleDebugInfo;
import org.simantics.scl.compiler.module.repository.ModuleRepository;
import org.simantics.scl.compiler.types.Type;
public JavaNamingPolicy namingPolicy;
public ConcreteModule module;
public ModuleHeader header;
+ public ModuleDebugInfo moduleDebugInfo;
private THashMap<Name, SCLValue> valueCache = new THashMap<Name, SCLValue>();
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;
final THashMap<SectionName, Query[]> sections = new THashMap<SectionName, Query[]>();
- final TranslationContext context = createTranslationContext();
+ final TranslationContext context = createTranslationContext(ruleName);
if(length > 0) {
THashMap<String, Variable> variables = context.getVariables();
for(TransformationRule extendsRule : extendsRules) {
continue;
try {
SCLValue value = module.getValue(name);
- TranslationContext context = createTranslationContext();
+ TranslationContext context = createTranslationContext(name);
Expression expression = context.translateCases2(defs);
value.setExpression(expression);
continue;
try {
SCLValue value = module.getValue(name);
- TranslationContext context = createTranslationContext();
+ TranslationContext context = createTranslationContext(name);
Expression expression = context.translateCases2(defs);
value.setExpression(expression);
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(compilationContext, null);
+ private TranslationContext createTranslationContext(String definitionName) {
+ return new TranslationContext(compilationContext, null, definitionName);
}
private void handleAnnotation(SCLValue value, ArrayList<DValueAst> defs, DAnnotationAst annotation) {
branchPoints.put(valueName, injector.getAndClearBranchPoints());
}
}
+
+ public void collectDebugInfo() {
+ module.moduleDebugInfo = compilationContext.moduleDebugInfo = new ModuleDebugInfo();
+ }
}
declarations.relationDefinitionsAst);
if(options.computeCoverage)
elaboration.addCoverageBranchPoints();
+ if(options.collectDebugInfo)
+ elaboration.collectDebugInfo();
// Elaboration
if(hasErrors()) return;
elaboration.addTypesToEnvironment(
import java.util.Arrays;
import org.simantics.scl.compiler.common.names.Name;
-import org.simantics.scl.compiler.common.names.Names;
import org.simantics.scl.compiler.common.precedence.Associativity;
import org.simantics.scl.compiler.common.precedence.Precedence;
import org.simantics.scl.compiler.compilation.CompilationContext;
import org.simantics.scl.compiler.environment.filter.AcceptAllNamespaceFilter;
import org.simantics.scl.compiler.errors.Locations;
import org.simantics.scl.compiler.internal.parsing.declarations.DValueAst;
+import org.simantics.scl.compiler.module.debug.ModuleDebugInfo;
+import org.simantics.scl.compiler.module.debug.SymbolReference;
import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
import org.simantics.scl.compiler.types.Type;
public CHRRuleset currentRuleset;
+ public ModuleDebugInfo moduleDebugInfo;
+
+ private String definitionName;
+
static class Entry {
String name;
Variable variable;
}
}
- public TranslationContext(CompilationContext compilationContext, LocalEnvironment localEnvironment) {
+ public TranslationContext(CompilationContext compilationContext, LocalEnvironment localEnvironment, String definitionName) {
super(compilationContext);
this.localEnvironment = localEnvironment;
+ this.moduleDebugInfo = compilationContext.moduleDebugInfo;
+ this.definitionName = definitionName;
}
public static boolean isConstructorName(String name) {
String deprecatedDescription = value.isDeprecated();
if(deprecatedDescription != null)
errorLog.logWarning(location, "Deprecated value " + value.getName().name + "." + (deprecatedDescription.isEmpty() ? "" : " " + deprecatedDescription));
+ if(moduleDebugInfo != null)
+ moduleDebugInfo.symbolReferences.add(new SymbolReference(value.getName(), definitionName, location));
return new EConstant(location, value);
} catch (AmbiguousNameException e) {
if(SCLCompilerConfiguration.ALLOW_OVERLOADING)
public Expression realize() {
EConstant expression = new EConstant(altValue);
expression.location = location;
+ if(moduleDebugInfo != null)
+ moduleDebugInfo.symbolReferences.add(new SymbolReference(altValue.getName(), definitionName, location));
return expression;
}
import java.util.Collections;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.SynchronousQueue;
import java.util.function.Consumer;
import org.simantics.scl.compiler.common.names.Name;
import org.simantics.scl.compiler.environment.filter.NamespaceFilter;
import org.simantics.scl.compiler.errors.CompilationError;
import org.simantics.scl.compiler.internal.codegen.effects.EffectConstructor;
+import org.simantics.scl.compiler.module.debug.ModuleDebugInfo;
import org.simantics.scl.compiler.top.ModuleInitializer;
import org.simantics.scl.compiler.types.TCon;
import org.simantics.scl.runtime.profiling.BranchPoint;
ModuleInitializer moduleInitializer;
protected Documentation documentation;
+
+ public ModuleDebugInfo moduleDebugInfo;
public ConcreteModule(String moduleName) {
this.moduleName = moduleName;
consumer.accept(value);
});
}
+
+ @Override
+ public List<String> getValueNames() {
+ return new ArrayList<String>(values.keySet());
+ }
public Collection<SCLRelation> getRelations() {
return relations.values();
public void setDeprecation(String deprecation) {
this.deprecation = deprecation;
}
+
+ @Override
+ public ModuleDebugInfo getModuleDebugInfo() {
+ return moduleDebugInfo;
+ }
}
package org.simantics.scl.compiler.module;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.Consumer;
import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
import org.simantics.scl.compiler.elaboration.rules.MappingRelation;
import org.simantics.scl.compiler.elaboration.rules.TransformationRule;
+import org.simantics.scl.compiler.environment.filter.AcceptAllNamespaceFilter;
import org.simantics.scl.compiler.environment.filter.NamespaceFilter;
import org.simantics.scl.compiler.errors.CompilationError;
import org.simantics.scl.compiler.internal.codegen.effects.EffectConstructor;
+import org.simantics.scl.compiler.module.debug.ModuleDebugInfo;
import org.simantics.scl.compiler.top.ModuleInitializer;
import org.simantics.scl.compiler.types.TCon;
import org.simantics.scl.runtime.profiling.BranchPoint;
String getDefaultLocalName();
SCLValue getValue(String name);
+ default List<String> getValueNames() {
+ ArrayList<String> valueNames = new ArrayList<String>();
+ findValuesForPrefix("", AcceptAllNamespaceFilter.INSTANCE, value -> {
+ valueNames.add(value.getName().name);
+ });
+ return valueNames;
+ }
List<Constant> getFieldAccessors(String name);
SCLRelation getRelation(String name);
SCLEntityType getEntityType(String name);
CompilationError[] getWarnings();
ClassLoader getParentClassLoader();
String getDeprecation();
+
+ /**
+ * May return null, if there is no debug info.
+ */
+ default ModuleDebugInfo getModuleDebugInfo() {
+ return null;
+ }
}
--- /dev/null
+package org.simantics.scl.compiler.module.debug;
+
+import java.util.ArrayList;
+
+public class ModuleDebugInfo {
+ public final ArrayList<SymbolReference> symbolReferences = new ArrayList<SymbolReference>();
+}
--- /dev/null
+package org.simantics.scl.compiler.module.debug;
+
+import org.simantics.scl.compiler.common.names.Name;
+
+public class SymbolReference {
+ public final Name referred;
+ public final String referrer;
+ public final long referenceLocation;
+
+ public SymbolReference(Name referred, String referrer, long referenceLocation) {
+ this.referred = referred;
+ this.referrer = referrer;
+ this.referenceLocation = referenceLocation;
+ }
+}
public boolean computeCoverage;
public boolean silent = false;
+ public boolean collectDebugInfo = false;
public ModuleCompilationOptions(boolean computeCoverage) {
this.computeCoverage = computeCoverage;
// Elaboration
{
- TranslationContext context = new TranslationContext(compilationContext, localEnvironment);
+ TranslationContext context = new TranslationContext(compilationContext, localEnvironment, "expression");
expression = expression.resolve(context);
if(!errorLog.hasNoErrors())
throw new SCLExpressionCompilationException(errorLog.getErrors());
import java.util.ArrayList;
+import org.eclipse.core.internal.runtime.PlatformActivator;
import org.simantics.scl.compiler.errors.DoesNotExist;
import org.simantics.scl.compiler.errors.Failable;
import org.simantics.scl.compiler.module.Module;
+import org.simantics.scl.compiler.module.options.ModuleCompilationOptions;
+import org.simantics.scl.compiler.module.options.ModuleCompilationOptionsAdvisor;
import org.simantics.scl.compiler.module.repository.ModuleRepository;
import org.simantics.scl.compiler.source.repository.ModuleSourceRepository;
import org.simantics.scl.compiler.testing.repository.TestRepository;
public static ModuleRepository MODULE_REPOSITORY = new ModuleRepository(SOURCE_REPOSITORY);
public static TestRepository TEST_REPOSITORY = new ServiceBasedTestRepository(Activator.getContext());
+ static {
+ MODULE_REPOSITORY.setAdvisor(new ModuleCompilationOptionsAdvisor() {
+ ModuleCompilationOptions options = null;
+ @Override
+ public ModuleCompilationOptions getOptions(String moduleName) {
+ if(options == null) {
+ options = new ModuleCompilationOptions(false);
+ options.collectDebugInfo = Activator.getContext().getProperty("osgi.dev") != null; //$NON-NLS-1$
+ }
+ return options;
+ }
+ });
+ }
public static String compileAllModules() {
ArrayList<String> modulesWithErrors = new ArrayList<String>();