From: Hannu Niemistö Date: Mon, 15 Aug 2016 09:38:14 +0000 (+0300) Subject: migrated to svn revision 33108 X-Git-Tag: v1.25.0~180^2 X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=commitdiff_plain;h=9a175feb652b2b7bba7afa540831b9076be3c10e;hp=0b72d3e4ec886838314ffeba0fa201e32c0aae3e migrated to svn revision 33108 --- diff --git a/bundles/com.famfamfam.silk/META-INF/MANIFEST.MF b/bundles/com.famfamfam.silk/META-INF/MANIFEST.MF index ed8297e4c..7f1d30dab 100644 --- a/bundles/com.famfamfam.silk/META-INF/MANIFEST.MF +++ b/bundles/com.famfamfam.silk/META-INF/MANIFEST.MF @@ -2,5 +2,5 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Silk icon set Bundle-SymbolicName: com.famfamfam.silk -Bundle-Version: 1.3 +Bundle-Version: 1.3.0 Bundle-Vendor: Semantum Oy diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/genericrelation/DependenciesRelation.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/genericrelation/DependenciesRelation.java index 965ca6ee4..d3c44903b 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/genericrelation/DependenciesRelation.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/genericrelation/DependenciesRelation.java @@ -405,10 +405,10 @@ public class DependenciesRelation extends UnsupportedRelation implements Generic if (parent != null) { _additions.add(new Object[] { ss.getRandomAccessId(parent), ss.getRandomAccessId(entry.component), name, types, id != null ? id.indexString() : "" }); } else { - System.err.println("resource " + entry.component + ": no parent for entry " + name + " " + types); + //System.err.println("resource " + entry.component + ": no parent for entry " + name + " " + types); } } else { - System.err.println("resource " + entry.component + ": " + name + " " + types); + //System.err.println("resource " + entry.component + ": " + name + " " + types); } } else if(_entry instanceof ComponentModification) { ComponentModification entry = (ComponentModification)_entry; diff --git a/bundles/org.simantics.db.procore.server.environment/build.properties b/bundles/org.simantics.db.procore.server.environment/build.properties index 6425a9613..93557d694 100644 --- a/bundles/org.simantics.db.procore.server.environment/build.properties +++ b/bundles/org.simantics.db.procore.server.environment/build.properties @@ -13,8 +13,8 @@ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ .,\ - bin/msijni.dll,\ - bin/msijni64.dll,\ + msijni.dll,\ + msijni64.dll,\ VC90.2008.SP1.KB2467174.redist.x64.exe,\ VC90.2008.SP1.KB2467174.redist.x86.exe src.includes = native/ diff --git a/bundles/org.simantics.db.procore.server.environment/src/msijni.dll b/bundles/org.simantics.db.procore.server.environment/src/msijni.dll deleted file mode 100644 index 8009884ed..000000000 Binary files a/bundles/org.simantics.db.procore.server.environment/src/msijni.dll and /dev/null differ diff --git a/bundles/org.simantics.db.procore.server.environment/src/msijni64.dll b/bundles/org.simantics.db.procore.server.environment/src/msijni64.dll deleted file mode 100644 index df7497910..000000000 Binary files a/bundles/org.simantics.db.procore.server.environment/src/msijni64.dll and /dev/null differ diff --git a/bundles/org.simantics.db.procore.ui/META-INF/MANIFEST.MF b/bundles/org.simantics.db.procore.ui/META-INF/MANIFEST.MF index 3965148e3..f16e98137 100644 --- a/bundles/org.simantics.db.procore.ui/META-INF/MANIFEST.MF +++ b/bundles/org.simantics.db.procore.ui/META-INF/MANIFEST.MF @@ -9,14 +9,13 @@ Bundle-Activator: org.simantics.db.procore.ui.internal.Activator Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Export-Package: org.simantics.db.procore.ui Import-Package: - org.osgi.framework;version="1.3.0", + org.eclipse.core.runtime, org.eclipse.jface.dialogs, org.eclipse.jface.operation, - org.eclipse.core.runtime, org.eclipse.swt.widgets, - org.eclipse.ui, + org.osgi.framework;version="1.3.0", org.simantics.db, - org.simantics.db.exception, org.simantics.db.common.utils, + org.simantics.db.exception, org.simantics.db.server;visibility:=reexport Require-Bundle: org.simantics.db.procore;bundle-version="1.2.1" diff --git a/bundles/org.simantics.db.procore.ui/src/org/simantics/db/procore/ui/ProCoreUserAgent.java b/bundles/org.simantics.db.procore.ui/src/org/simantics/db/procore/ui/ProCoreUserAgent.java index dc93b2f9d..54b892070 100644 --- a/bundles/org.simantics.db.procore.ui/src/org/simantics/db/procore/ui/ProCoreUserAgent.java +++ b/bundles/org.simantics.db.procore.ui/src/org/simantics/db/procore/ui/ProCoreUserAgent.java @@ -2,28 +2,21 @@ package org.simantics.db.procore.ui; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchWindow; import org.simantics.db.DatabaseUserAgent; import org.simantics.db.exception.InternalException; import org.simantics.db.procore.ProCoreDriver; public final class ProCoreUserAgent implements DatabaseUserAgent { - private static Shell getShell(IWorkbench workbench) { - IWorkbenchWindow wbw = workbench.getActiveWorkbenchWindow(); + private static Shell getShell() { Shell shell = null; - if (null != wbw) { - shell = wbw.getShell(); - } else { - Display d = getDisplay(); - if (d == null) - return null; - shell = d.getActiveShell(); - if (null == shell) { - Shell[] shells = d.getShells(); - if (null != shells && shells.length > 0) - shell = shells[0]; - } + Display d = getDisplay(); + if (d == null) + return null; + shell = d.getActiveShell(); + if (null == shell) { + Shell[] shells = d.getShells(); + if (null != shells && shells.length > 0) + shell = shells[0]; } return shell; } @@ -33,13 +26,6 @@ public final class ProCoreUserAgent implements DatabaseUserAgent { d = Display.getDefault(); return d; } - private IWorkbench workbench; - public ProCoreUserAgent(IWorkbench workbench) { - this.workbench = workbench; - } - private Shell getShell() { - return getShell(workbench); - } @Override public boolean handleStart(InternalException exception) { Shell shell = getShell(); diff --git a/bundles/org.simantics.db.server/build.properties b/bundles/org.simantics.db.server/build.properties index af1a55787..657c95170 100644 --- a/bundles/org.simantics.db.server/build.properties +++ b/bundles/org.simantics.db.server/build.properties @@ -15,5 +15,4 @@ bin.includes = META-INF/,\ .,\ win32.x86/,\ win32.x86_64/,\ - linux.x86/,\ linux.x86_64/ diff --git a/bundles/org.simantics.diagram.ontology/build.properties b/bundles/org.simantics.diagram.ontology/build.properties index 15454c697..fb164279d 100644 --- a/bundles/org.simantics.diagram.ontology/build.properties +++ b/bundles/org.simantics.diagram.ontology/build.properties @@ -2,6 +2,5 @@ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ .,\ - graphs/*.tg,\ graph.tg src.includes = graph/ diff --git a/bundles/org.simantics.document.server/build.properties b/bundles/org.simantics.document.server/build.properties index 5959d12ac..34f26f886 100644 --- a/bundles/org.simantics.document.server/build.properties +++ b/bundles/org.simantics.document.server/build.properties @@ -3,7 +3,6 @@ output.. = bin/ bin.includes = META-INF/,\ .,\ plugin.xml,\ - document.war,\ webdefault.xml,\ scl/,\ src.includes = scl/ diff --git a/bundles/org.simantics.layer0/build.properties b/bundles/org.simantics.layer0/build.properties index 15454c697..fb164279d 100644 --- a/bundles/org.simantics.layer0/build.properties +++ b/bundles/org.simantics.layer0/build.properties @@ -2,6 +2,5 @@ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ .,\ - graphs/*.tg,\ graph.tg src.includes = graph/ diff --git a/bundles/org.simantics.nativemem/.classpath b/bundles/org.simantics.nativemem/.classpath new file mode 100644 index 000000000..28542144e --- /dev/null +++ b/bundles/org.simantics.nativemem/.classpath @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/bundles/org.simantics.nativemem/.project b/bundles/org.simantics.nativemem/.project new file mode 100644 index 000000000..4d55767d8 --- /dev/null +++ b/bundles/org.simantics.nativemem/.project @@ -0,0 +1,28 @@ + + + org.simantics.nativemem + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/bundles/org.simantics.nativemem/.settings/org.eclipse.jdt.core.prefs b/bundles/org.simantics.nativemem/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..11f6e462d --- /dev/null +++ b/bundles/org.simantics.nativemem/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.7 diff --git a/bundles/org.simantics.nativemem/.settings/org.eclipse.pde.core.prefs b/bundles/org.simantics.nativemem/.settings/org.eclipse.pde.core.prefs new file mode 100644 index 000000000..b7e72d019 --- /dev/null +++ b/bundles/org.simantics.nativemem/.settings/org.eclipse.pde.core.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +pluginProject.extensions=false +resolve.requirebundle=false diff --git a/bundles/org.simantics.nativemem/META-INF/MANIFEST.MF b/bundles/org.simantics.nativemem/META-INF/MANIFEST.MF new file mode 100644 index 000000000..d1de018f9 --- /dev/null +++ b/bundles/org.simantics.nativemem/META-INF/MANIFEST.MF @@ -0,0 +1,11 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Native Memory Tracking +Bundle-SymbolicName: org.simantics.nativemem +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Semantum Oy +Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Bundle-ClassPath: ., + jna-4.2.1.jar, + jna-platform-4.2.1.jar +Export-Package: org.simantics.nativemem diff --git a/bundles/org.simantics.nativemem/build.properties b/bundles/org.simantics.nativemem/build.properties new file mode 100644 index 000000000..07df1f003 --- /dev/null +++ b/bundles/org.simantics.nativemem/build.properties @@ -0,0 +1,6 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + jna-4.2.1.jar,\ + jna-platform-4.2.1.jar diff --git a/bundles/org.simantics.nativemem/jna-4.2.1.jar b/bundles/org.simantics.nativemem/jna-4.2.1.jar new file mode 100644 index 000000000..c21183e38 Binary files /dev/null and b/bundles/org.simantics.nativemem/jna-4.2.1.jar differ diff --git a/bundles/org.simantics.nativemem/jna-platform-4.2.1.jar b/bundles/org.simantics.nativemem/jna-platform-4.2.1.jar new file mode 100644 index 000000000..ca6ea472a Binary files /dev/null and b/bundles/org.simantics.nativemem/jna-platform-4.2.1.jar differ diff --git a/bundles/org.simantics.nativemem/src/org/simantics/nativemem/NativeMem.java b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/NativeMem.java new file mode 100644 index 000000000..cfccc2154 --- /dev/null +++ b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/NativeMem.java @@ -0,0 +1,56 @@ +package org.simantics.nativemem; + +import org.simantics.nativemem.internal.Arch; +import org.simantics.nativemem.internal.OS; +import org.simantics.nativemem.internal.Psapi32; +import org.simantics.nativemem.internal.Psapi64; + +import com.sun.jna.platform.win32.Kernel32; +import com.sun.jna.platform.win32.WinNT.HANDLE; + + +public class NativeMem { + + /** + * @param out + * the structure to write the result into or null to + * create a new structure + * @return the result structure + */ + public static ProcessMemoryCounters getMemoryCounters(ProcessMemoryCounters out) { + if (out == null) + out = new ProcessMemoryCounters(); + + OS os = OS.calculate(); + Arch arch = Arch.calculate(); + switch (os) { + case WINDOWS: { + HANDLE proc = Kernel32.INSTANCE.GetCurrentProcess(); + switch (arch) { + case X86: { + Psapi32.PROCESS_MEMORY_COUNTERS_EX pmem = new Psapi32.PROCESS_MEMORY_COUNTERS_EX(); + boolean ok = Psapi32.INSTANCE.GetProcessMemoryInfo(proc, pmem, pmem.size()); + if (ok) + pmem.writeTo(out); + return out; + } + + case X86_64: { + Psapi64.PROCESS_MEMORY_COUNTERS_EX pmem = new Psapi64.PROCESS_MEMORY_COUNTERS_EX(); + boolean ok = Psapi64.INSTANCE.GetProcessMemoryInfo(proc, pmem, pmem.size()); + if (ok) + pmem.writeTo(out); + return out; + } + + default: + throw new UnsupportedOperationException("Architecture " + arch + " not supported on operating system " + os); + } + } + + default: + throw new UnsupportedOperationException("Operating system " + os + " not supported"); + } + } + +} \ No newline at end of file diff --git a/bundles/org.simantics.nativemem/src/org/simantics/nativemem/ProcessMemoryCounters.java b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/ProcessMemoryCounters.java new file mode 100644 index 000000000..d2192d3c4 --- /dev/null +++ b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/ProcessMemoryCounters.java @@ -0,0 +1,54 @@ +package org.simantics.nativemem; + +/** + * Architecture-independent version of the Windows PsApi PROCESS_MEMORY_COUNTERS + * structure. + * + * @author Tuukka Lehtonen + */ +public class ProcessMemoryCounters { + public int PageFaultCount; + public long PeakWorkingSetSize; + public long WorkingSetSize; + public long QuotaPeakPagedPoolUsage; + public long QuotaPagedPoolUsage; + public long QuotaPeakNonPagedPoolUsage; + public long QuotaNonPagedPoolUsage; + public long PagefileUsage; + public long PeakPagefileUsage; + public long PrivateUsage; + + @Override + public String toString() { + return "ProcessMemoryCounters [PageFaultCount=" + + PageFaultCount + ", PeakWorkingSetSize=" + PeakWorkingSetSize + + ", WorkingSetSize=" + WorkingSetSize + + ", QuotaPeakPagedPoolUsage=" + QuotaPeakPagedPoolUsage + + ", QuotaPagedPoolUsage=" + QuotaPagedPoolUsage + + ", QuotaPeakNonPagedPoolUsage=" + QuotaPeakNonPagedPoolUsage + + ", QuotaNonPagedPoolUsage=" + QuotaNonPagedPoolUsage + + ", PagefileUsage=" + PagefileUsage + ", PeakPagefileUsage=" + + PeakPagefileUsage + ", PrivateUsage=" + PrivateUsage + "]"; + } + + public String toHumanReadableString() { + StringBuilder sb = new StringBuilder(); + sb.append("ProcessMemoryCounters [\n\tPageFaultCount = ").append(PageFaultCount) + .append(",\n\tPeakWorkingSetSize = ").append(toMb(PeakWorkingSetSize)) + .append(" MB,\n\tWorkingSetSize = ").append(toMb(WorkingSetSize)) + .append(" MB,\n\tQuotaPeakPagedPoolUsage = ").append(toMb(QuotaPeakPagedPoolUsage)) + .append(" MB,\n\tQuotaPagedPoolUsage = ").append(toMb(QuotaPagedPoolUsage)) + .append(" MB,\n\tQuotaPeakNonPagedPoolUsage = ").append(toMb(QuotaPeakNonPagedPoolUsage)) + .append(" MB,\n\tQuotaNonPagedPoolUsage = ").append(toMb(QuotaNonPagedPoolUsage)) + .append(" MB,\n\tPagefileUsage = ").append(toMb(PagefileUsage)) + .append(" MB,\n\tPeakPagefileUsage = ").append(toMb(PeakPagefileUsage)) + .append(" MB,\n\tPrivateUsage = ").append(toMb(PrivateUsage)) + .append(" MB]"); + return sb.toString(); + } + + private double toMb(long bytes) { + return (double) bytes / 1048576.0; + } + +} \ No newline at end of file diff --git a/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/Arch.java b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/Arch.java new file mode 100644 index 000000000..7910f06bf --- /dev/null +++ b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/Arch.java @@ -0,0 +1,25 @@ +package org.simantics.nativemem.internal; + +/** + * @author Tuukka Lehtonen + */ +public enum Arch { + PPC, PPC_64, SPARC, X86, X86_64, UNKNOWN; + + public static Arch calculate() { + String osArch = System.getProperty("os.arch"); + assert osArch != null; + osArch = osArch.toLowerCase(); + if (osArch.equals("i386") || osArch.equals("i586") || osArch.equals("i686") || osArch.equals("x86")) + return X86; + if (osArch.startsWith("amd64") || osArch.startsWith("x86_64")) + return X86_64; + if (osArch.equals("ppc")) + return PPC; + if (osArch.startsWith("ppc")) + return PPC_64; + if (osArch.startsWith("sparc")) + return SPARC; + return UNKNOWN; + } +} diff --git a/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/OS.java b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/OS.java new file mode 100644 index 000000000..a1d0a48c3 --- /dev/null +++ b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/OS.java @@ -0,0 +1,20 @@ +package org.simantics.nativemem.internal; + +public enum OS { + APPLE, LINUX, SUN, WINDOWS, UNKNOWN; + + public static OS calculate() { + String osName = System.getProperty("os.name"); + assert osName != null; + osName = osName.toLowerCase(); + if (osName.startsWith("mac os x")) + return APPLE; + if (osName.startsWith("windows")) + return WINDOWS; + if (osName.startsWith("linux")) + return LINUX; + if (osName.startsWith("sun")) + return SUN; + return UNKNOWN; + } +} diff --git a/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/Psapi32.java b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/Psapi32.java new file mode 100644 index 000000000..ba302c9a5 --- /dev/null +++ b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/Psapi32.java @@ -0,0 +1,67 @@ +package org.simantics.nativemem.internal; + +import java.util.Arrays; +import java.util.List; + +import org.simantics.nativemem.ProcessMemoryCounters; + +import com.sun.jna.Native; +import com.sun.jna.Structure; +import com.sun.jna.platform.win32.WinNT.HANDLE; +import com.sun.jna.win32.StdCallLibrary; + +public interface Psapi32 extends StdCallLibrary { + + Psapi32 INSTANCE = (Psapi32) Native.loadLibrary("Psapi", Psapi32.class); + + /* + * https://msdn.microsoft.com/en-us/library/windows/desktop/ms684874%28v=vs.85%29.aspx + */ + public static class PROCESS_MEMORY_COUNTERS_EX extends Structure { + public int cb; + public int PageFaultCount; + public int PeakWorkingSetSize; + public int WorkingSetSize; + public int QuotaPeakPagedPoolUsage; + public int QuotaPagedPoolUsage; + public int QuotaPeakNonPagedPoolUsage; + public int QuotaNonPagedPoolUsage; + public int PagefileUsage; + public int PeakPagefileUsage; + public int PrivateUsage; + + @SuppressWarnings("rawtypes") + @Override + protected List getFieldOrder() { + return PROCESS_MEMORY_COUNTERS_EX_FIELDS; + } + + static final List PROCESS_MEMORY_COUNTERS_EX_FIELDS = Arrays.asList(new String[] { + "cb", "PageFaultCount", + "PeakWorkingSetSize", "WorkingSetSize", + "QuotaPeakPagedPoolUsage", "QuotaPagedPoolUsage", + "QuotaPeakNonPagedPoolUsage", "QuotaNonPagedPoolUsage", + "PagefileUsage", "PeakPagefileUsage", "PrivateUsage" + }); + + public void writeTo(ProcessMemoryCounters to) { + to.PageFaultCount = PageFaultCount; + to.PeakWorkingSetSize = PeakWorkingSetSize; + to.WorkingSetSize = WorkingSetSize; + to.QuotaPeakPagedPoolUsage = QuotaPeakPagedPoolUsage; + to.QuotaPagedPoolUsage = QuotaPagedPoolUsage; + to.QuotaPeakNonPagedPoolUsage = QuotaPeakNonPagedPoolUsage; + to.QuotaNonPagedPoolUsage = QuotaNonPagedPoolUsage; + to.PagefileUsage = PagefileUsage; + to.PeakPagefileUsage = PeakPagefileUsage; + to.PrivateUsage = PrivateUsage; + } + } + + /* + * https://msdn.microsoft.com/en-us/library/windows/desktop/ms683219%28v=vs.85%29.aspx + */ + boolean GetProcessMemoryInfo(HANDLE Process, PROCESS_MEMORY_COUNTERS_EX ppsmemCounters, int cb); + + +} \ No newline at end of file diff --git a/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/Psapi64.java b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/Psapi64.java new file mode 100644 index 000000000..ba58251a0 --- /dev/null +++ b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/Psapi64.java @@ -0,0 +1,66 @@ +package org.simantics.nativemem.internal; + +import java.util.Arrays; +import java.util.List; + +import org.simantics.nativemem.ProcessMemoryCounters; + +import com.sun.jna.Native; +import com.sun.jna.Structure; +import com.sun.jna.platform.win32.WinNT.HANDLE; +import com.sun.jna.win32.StdCallLibrary; + +public interface Psapi64 extends StdCallLibrary { + + Psapi64 INSTANCE = (Psapi64) Native.loadLibrary("Psapi", Psapi64.class); + + /* + * https://msdn.microsoft.com/en-us/library/windows/desktop/ms684874%28v=vs.85%29.aspx + */ + public static class PROCESS_MEMORY_COUNTERS_EX extends Structure { + public int cb; + public int PageFaultCount; + public long PeakWorkingSetSize; + public long WorkingSetSize; + public long QuotaPeakPagedPoolUsage; + public long QuotaPagedPoolUsage; + public long QuotaPeakNonPagedPoolUsage; + public long QuotaNonPagedPoolUsage; + public long PagefileUsage; + public long PeakPagefileUsage; + public long PrivateUsage; + + @SuppressWarnings("rawtypes") + @Override + protected List getFieldOrder() { + return PROCESS_MEMORY_COUNTERS_EX_FIELDS; + } + + private static final List PROCESS_MEMORY_COUNTERS_EX_FIELDS = Arrays.asList(new String[] { + "cb", "PageFaultCount", + "PeakWorkingSetSize", "WorkingSetSize", + "QuotaPeakPagedPoolUsage", "QuotaPagedPoolUsage", + "QuotaPeakNonPagedPoolUsage", "QuotaNonPagedPoolUsage", + "PagefileUsage", "PeakPagefileUsage", "PrivateUsage" + }); + + public void writeTo(ProcessMemoryCounters to) { + to.PageFaultCount = PageFaultCount; + to.PeakWorkingSetSize = PeakWorkingSetSize; + to.WorkingSetSize = WorkingSetSize; + to.QuotaPeakPagedPoolUsage = QuotaPeakPagedPoolUsage; + to.QuotaPagedPoolUsage = QuotaPagedPoolUsage; + to.QuotaPeakNonPagedPoolUsage = QuotaPeakNonPagedPoolUsage; + to.QuotaNonPagedPoolUsage = QuotaNonPagedPoolUsage; + to.PagefileUsage = PagefileUsage; + to.PeakPagefileUsage = PeakPagefileUsage; + to.PrivateUsage = PrivateUsage; + } + } + + /* + * https://msdn.microsoft.com/en-us/library/windows/desktop/ms683219%28v=vs.85%29.aspx + */ + boolean GetProcessMemoryInfo(HANDLE Process, PROCESS_MEMORY_COUNTERS_EX ppsmemCounters, int cb); + +} \ No newline at end of file diff --git a/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/Test.java b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/Test.java new file mode 100644 index 000000000..d00db0c74 --- /dev/null +++ b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/Test.java @@ -0,0 +1,13 @@ +package org.simantics.nativemem.internal; + +import org.simantics.nativemem.NativeMem; +import org.simantics.nativemem.ProcessMemoryCounters; + +public class Test { + + public static void main(String[] args) { + ProcessMemoryCounters mem = NativeMem.getMemoryCounters(null); + System.out.println(mem.toHumanReadableString()); + } + +} diff --git a/bundles/org.simantics.scl.compiler/src/org/cojen/classfile/MethodDesc.java b/bundles/org.simantics.scl.compiler/src/org/cojen/classfile/MethodDesc.java index e95476992..6a751c5b5 100644 --- a/bundles/org.simantics.scl.compiler/src/org/cojen/classfile/MethodDesc.java +++ b/bundles/org.simantics.scl.compiler/src/org/cojen/classfile/MethodDesc.java @@ -16,15 +16,15 @@ package org.cojen.classfile; -import java.io.Serializable; import java.io.Externalizable; -import java.io.ObjectOutput; -import java.io.ObjectInput; import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; import java.io.ObjectStreamException; +import java.io.Serializable; import java.lang.reflect.Method; -import java.util.List; import java.util.ArrayList; +import java.util.List; import org.cojen.util.WeakCanonicalSet; diff --git a/bundles/org.simantics.scl.compiler/src/org/cojen/classfile/TypeDesc.java b/bundles/org.simantics.scl.compiler/src/org/cojen/classfile/TypeDesc.java index 084eb3dc8..cfc5a1deb 100644 --- a/bundles/org.simantics.scl.compiler/src/org/cojen/classfile/TypeDesc.java +++ b/bundles/org.simantics.scl.compiler/src/org/cojen/classfile/TypeDesc.java @@ -17,11 +17,6 @@ package org.cojen.classfile; import java.io.Serializable; -import java.io.Externalizable; -import java.io.ObjectOutput; -import java.io.ObjectInput; -import java.io.IOException; -import java.io.ObjectStreamException; import java.lang.ref.SoftReference; import java.lang.reflect.Array; import java.util.Collections; @@ -510,10 +505,6 @@ public abstract class TypeDesc extends Descriptor implements Serializable { return false; } - Object writeReplace() throws ObjectStreamException { - return new External(mDescriptor); - } - private static class PrimitiveType extends TypeDesc { private transient final int mCode; private transient TypeDesc mArrayType; @@ -895,27 +886,4 @@ public abstract class TypeDesc extends Descriptor implements Serializable { } } } - - private static class External implements Externalizable { - private String mDescriptor; - - public External() { - } - - public External(String desc) { - mDescriptor = desc; - } - - public void writeExternal(ObjectOutput out) throws IOException { - out.writeUTF(mDescriptor); - } - - public void readExternal(ObjectInput in) throws IOException { - mDescriptor = in.readUTF(); - } - - public Object readResolve() throws ObjectStreamException { - return forDescriptor(mDescriptor); - } - } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/commands/CommandSession.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/commands/CommandSession.java index 8ad47b0a0..e463a4e6a 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/commands/CommandSession.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/commands/CommandSession.java @@ -1,9 +1,5 @@ package org.simantics.scl.compiler.commands; -import gnu.trove.map.hash.THashMap; -import gnu.trove.procedure.TObjectProcedure; -import gnu.trove.set.hash.THashSet; - import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileOutputStream; @@ -62,6 +58,10 @@ import org.simantics.scl.runtime.reporting.SCLReporting; import org.simantics.scl.runtime.reporting.SCLReportingHandler; import org.simantics.scl.runtime.tuple.Tuple0; +import gnu.trove.map.hash.THashMap; +import gnu.trove.procedure.TObjectProcedure; +import gnu.trove.set.hash.THashSet; + public class CommandSession { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/commands/ValueToStringConverter.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/commands/ValueToStringConverter.java index 07ca39015..51d5c456f 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/commands/ValueToStringConverter.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/commands/ValueToStringConverter.java @@ -1,7 +1,5 @@ package org.simantics.scl.compiler.commands; -import gnu.trove.map.hash.THashMap; - import org.simantics.scl.compiler.runtime.RuntimeEnvironment; import org.simantics.scl.compiler.top.ExpressionEvaluator; import org.simantics.scl.compiler.top.SCLExpressionCompilationException; @@ -9,6 +7,8 @@ import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.runtime.function.Function1; +import gnu.trove.map.hash.THashMap; + public class ValueToStringConverter { final RuntimeEnvironment environment; final THashMap showInstances = new THashMap(); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/CompilationTimer.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/CompilationTimer.java index 912158862..0ad3627d8 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/CompilationTimer.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/CompilationTimer.java @@ -1,9 +1,9 @@ package org.simantics.scl.compiler.compilation; -import gnu.trove.map.hash.TObjectLongHashMap; - import java.util.ArrayList; +import gnu.trove.map.hash.TObjectLongHashMap; + public class CompilationTimer { private long initialTime, previousTime; private ArrayList entries = new ArrayList(); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/DocumentationGeneration.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/DocumentationGeneration.java index e4124d9b7..b24243180 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/DocumentationGeneration.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/DocumentationGeneration.java @@ -1,8 +1,5 @@ package org.simantics.scl.compiler.compilation; -import gnu.trove.map.hash.THashMap; -import gnu.trove.set.hash.THashSet; - import java.util.ArrayList; import org.simantics.scl.compiler.elaboration.modules.SCLValue; @@ -13,6 +10,9 @@ import org.simantics.scl.compiler.internal.parsing.declarations.DDocumentationAs import org.simantics.scl.compiler.module.ConcreteModule; import org.simantics.scl.compiler.types.TCon; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; + public class DocumentationGeneration { THashMap valueDocumentation; THashMap typeDocumentation; 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 dc3bdc9e8..d331283fd 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 @@ -1,7 +1,6 @@ package org.simantics.scl.compiler.compilation; import java.util.ArrayList; -import java.util.Collections; import java.util.Iterator; import java.util.List; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/NameExistenceChecks.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/NameExistenceChecks.java index 8204b5f60..1f45c5f41 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/NameExistenceChecks.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/NameExistenceChecks.java @@ -5,22 +5,27 @@ import org.simantics.scl.compiler.elaboration.modules.TypeConstructor; import org.simantics.scl.compiler.environment.AmbiguousNameException; import org.simantics.scl.compiler.environment.Environment; import org.simantics.scl.compiler.errors.ErrorLog; +import org.simantics.scl.compiler.top.SCLCompilerConfiguration; public class NameExistenceChecks { public static void checkIfValueExists(ErrorLog errorLog, long location, Environment environment, String name) { - try { - SCLValue value = environment.getLocalNamespace().getValue(name); - if(value != null) + if(SCLCompilerConfiguration.ALLOW_OVERLOADING) + return; + else { + try { + SCLValue value = environment.getLocalNamespace().getValue(name); + if(value != null) + errorLog.log(location, + "Value " + name + " is already defined in the module " + + value.getName().module + + " that is imported to the default namespace."); + } catch(AmbiguousNameException e) { errorLog.log(location, - "Value " + name + " is already defined in the module " + - value.getName().module + - " that is imported to the default namespace."); - } catch(AmbiguousNameException e) { - errorLog.log(location, - "Value " + name + " is already defined in the modules " + - e.conflictingModules[0] + " and " + e.conflictingModules[1] + - " that are imported to the default namespace."); + "Value " + name + " is already defined in the modules " + + e.conflictingModules[0] + " and " + e.conflictingModules[1] + + " that are imported to the default namespace."); + } } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/NamespaceOfModule.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/NamespaceOfModule.java index 7b2ee618f..8ade1602e 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/NamespaceOfModule.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/NamespaceOfModule.java @@ -1,7 +1,6 @@ package org.simantics.scl.compiler.compilation; -import gnu.trove.procedure.TObjectProcedure; - +import java.util.Arrays; import java.util.function.Consumer; import org.simantics.scl.compiler.elaboration.modules.SCLValue; @@ -18,8 +17,11 @@ import org.simantics.scl.compiler.environment.filter.AcceptAllNamespaceFilter; import org.simantics.scl.compiler.environment.filter.NamespaceFilter; import org.simantics.scl.compiler.internal.codegen.effects.EffectConstructor; import org.simantics.scl.compiler.module.Module; +import org.simantics.scl.compiler.top.SCLCompilerConfiguration; import org.simantics.scl.compiler.types.TCon; +import gnu.trove.procedure.TObjectProcedure; + public class NamespaceOfModule implements Namespace { private final Namespace base; private final Module module; @@ -37,9 +39,30 @@ public class NamespaceOfModule implements Namespace { @Override public SCLValue getValue(String name) throws AmbiguousNameException { SCLValue value = module.getValue(name); + if(SCLCompilerConfiguration.ALLOW_OVERLOADING) { + SCLValue value2; + try { + value2 = base.getValue(name); + } catch(AmbiguousNameException e) { + if(value != null) { + String[] conflictingModules = Arrays.copyOf(e.conflictingModules, e.conflictingModules.length+1); + conflictingModules[e.conflictingModules.length] = module.getName(); + throw new AmbiguousNameException(Arrays.asList(conflictingModules), e.name); + } + else + throw e; + } + if(value == null) + return value2; + if(value2 == null) + return value; + throw new AmbiguousNameException(Arrays.asList(value.getName().module, value2.getName().module), value.getName().name); + } + else { if(value != null) return value; return base.getValue(name); + } } @Override diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeChecking.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeChecking.java index 97266d6e9..554a36081 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeChecking.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeChecking.java @@ -5,16 +5,13 @@ import static org.simantics.scl.compiler.elaboration.expressions.Expressions.app import static org.simantics.scl.compiler.elaboration.expressions.Expressions.lambda; import static org.simantics.scl.compiler.elaboration.expressions.Expressions.loc; import static org.simantics.scl.compiler.elaboration.expressions.Expressions.vars; -import gnu.trove.map.hash.THashMap; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; +import org.simantics.scl.compiler.elaboration.expressions.EAmbiguous; import org.simantics.scl.compiler.elaboration.expressions.EPlaceholder; import org.simantics.scl.compiler.elaboration.expressions.ETransformation; import org.simantics.scl.compiler.elaboration.expressions.EVariable; @@ -42,6 +39,11 @@ import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.kinds.Kinds; import org.simantics.scl.compiler.types.util.Polarity; +import gnu.trove.map.hash.THashMap; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + public class TypeChecking { final ErrorLog errorLog; final Environment environment; @@ -97,6 +99,8 @@ public class TypeChecking { context.pushEffectUpperBound(expression.location, Types.PROC); expression = expression.checkType(context, value.getType()); context.popEffectUpperBound(); + for(EAmbiguous overloaded : context.overloadedExpressions) + overloaded.assertResolved(errorLog); value.setExpression(expression); ArrayList constraintDemand = context.getConstraintDemand(); @@ -199,6 +203,7 @@ public class TypeChecking { @Override public void run() { Type type = value.getType(); + Expression expression = value.getExpression(); try { @@ -211,6 +216,8 @@ public class TypeChecking { context.pushEffectUpperBound(expression.location, Types.PROC); expression = expression.checkType(context, type); context.popEffectUpperBound(); + for(EAmbiguous overloaded : context.overloadedExpressions) + overloaded.assertResolved(errorLog); expression.getType().addPolarity(Polarity.POSITIVE); context.solveSubsumptions(expression.getLocation()); ArrayList demands = context.getConstraintDemand(); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeCheckingOld.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeCheckingOld.java deleted file mode 100644 index c5ef57384..000000000 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeCheckingOld.java +++ /dev/null @@ -1,349 +0,0 @@ -package org.simantics.scl.compiler.compilation; - -import static org.simantics.scl.compiler.elaboration.expressions.Expressions.apply; -import static org.simantics.scl.compiler.elaboration.expressions.Expressions.applyTypes; -import static org.simantics.scl.compiler.elaboration.expressions.Expressions.lambda; -import static org.simantics.scl.compiler.elaboration.expressions.Expressions.loc; -import static org.simantics.scl.compiler.elaboration.expressions.Expressions.vars; -import gnu.trove.map.hash.THashMap; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - -import java.util.ArrayList; - -import org.simantics.scl.compiler.elaboration.contexts.TypingContext; -import org.simantics.scl.compiler.elaboration.expressions.EPlaceholder; -import org.simantics.scl.compiler.elaboration.expressions.EVariable; -import org.simantics.scl.compiler.elaboration.expressions.Expression; -import org.simantics.scl.compiler.elaboration.expressions.Variable; -import org.simantics.scl.compiler.elaboration.modules.SCLValue; -import org.simantics.scl.compiler.elaboration.rules.MappingRelation; -import org.simantics.scl.compiler.elaboration.rules.TransformationRule; -import org.simantics.scl.compiler.environment.Environment; -import org.simantics.scl.compiler.errors.ErrorLog; -import org.simantics.scl.compiler.errors.Locations; -import org.simantics.scl.compiler.internal.elaboration.constraints.Constraint; -import org.simantics.scl.compiler.internal.elaboration.constraints.ConstraintEnvironment; -import org.simantics.scl.compiler.internal.elaboration.constraints.ConstraintSolver; -import org.simantics.scl.compiler.internal.elaboration.constraints.ExpressionAugmentation; -import org.simantics.scl.compiler.internal.elaboration.constraints.ReducedConstraints; -import org.simantics.scl.compiler.internal.elaboration.utils.StronglyConnectedComponents; -import org.simantics.scl.compiler.module.ConcreteModule; -import org.simantics.scl.compiler.types.TPred; -import org.simantics.scl.compiler.types.TVar; -import org.simantics.scl.compiler.types.Type; -import org.simantics.scl.compiler.types.Types; -import org.simantics.scl.compiler.types.kinds.Kinds; -import org.simantics.scl.compiler.types.util.Polarity; - -public class TypeCheckingOld { - public static final boolean PRINT_VALUES = false; - - ErrorLog errorLog; - Environment environment; - ConcreteModule module; - - ConstraintEnvironment ce; - ArrayList valuesWithoutTypeAnnotation = new ArrayList(); - ArrayList valuesWithTypeAnnotation = new ArrayList(); - - public TypeCheckingOld(ErrorLog errorLog, Environment environment, - ConcreteModule module) { - this.errorLog = errorLog; - this.environment = environment; - this.module = module; - } - - public void typeCheck() { - ce = new ConstraintEnvironment(environment); - groupValueDefinitionsByDependency(); - typeCheckValuesWithoutTypeAnnotations(); - typeCheckValuesWithTypeAnnotations(); - typeCheckRules(); - } - - private void groupValueDefinitionsByDependency() { - // Collect all untyped names - final ArrayList values = new ArrayList(); - for(SCLValue value : module.getValues()) { - if(value.getExpression() != null) { - if(value.getType() == null) - values.add(value); - else - valuesWithTypeAnnotation.add(value); - } - } - - // Create inverse - final TObjectIntHashMap allRefs = - new TObjectIntHashMap(values.size()*2, 0.5f, -1); - for(int i=0;i(); - for(SCLValue value : group) - context.recursiveValues.add(value); - - @SuppressWarnings("unchecked") - ArrayList[] constraintDemands = new ArrayList[group.length]; - - @SuppressWarnings("unchecked") - ArrayList[] recursiveReferences = new ArrayList[group.length]; - for(int i=0;i(); - - SCLValue value = group[i]; - Expression expression = value.getExpression(); - expression = expression.checkType(context, value.getType()); - value.setExpression(expression); - - ArrayList constraintDemand = context.getConstraintDemand(); - if(!constraintDemand.isEmpty()) { - constraintDemands[i] = constraintDemand; - context.resetConstraintDemand(); - } - - recursiveReferences[i] = context.recursiveReferences; - } - - for(Type type : Types.getTypes(group)) - type.addPolarity(Polarity.POSITIVE); - context.solveSubsumptions(group[0].getExpression().getLocation()); - ArrayList allUnsolvedConstraints = new ArrayList(); - - @SuppressWarnings("unchecked") - ArrayList[] freeEvidence = new ArrayList[group.length]; - for(int i=0;i(0), constraintDemands[i], - true /*!Types.isFunction(expression.getType())*/); - - expression = ExpressionAugmentation.augmentSolved( - red.solvedConstraints, - expression); - value.setExpression(expression); - value.setType(expression.getType()); - - for(Constraint c : red.unsolvedConstraints) - if(c.constraint.isGround()) { - errorLog.log(c.getDemandLocation(), "There is no instance for <"+c.constraint+">."); - } - - ArrayList fe = new ArrayList(red.unsolvedConstraints.size()); - for(Constraint c : red.unsolvedConstraints) { - allUnsolvedConstraints.add(c); - fe.add(c.evidence); - } - freeEvidence[i] = fe; - } - else { - group[i].setExpression(group[i].getExpression().decomposeMatching()); - freeEvidence[i] = new ArrayList(0); - } - } - - THashSet varSet = new THashSet(); - for(int i=0;i constraintSet = new THashSet(); - for(int i=0;i fe = freeEvidence[i]; - THashMap indexedEvidence = new THashMap(fe.size()); - for(Variable v : fe) - indexedEvidence.put((TPred)v.getType(), v); - fe.clear(); - for(TPred c : constraints) { - Variable var = indexedEvidence.get(c); - if(var == null) { - // These are variables that are not directly needed in - // this definition but in the definitions that are - // recursively called - var = new Variable("evX"); - var.setType(c); - fe.add(var); - } - fe.add(var); - } - - // Add evidence parameters to the functions - SCLValue value = group[i]; - value.setExpression(lambda(Types.NO_EFFECTS, fe, value.getExpression()) - .closure(vars)); - value.setType(Types.forAll(vars, - Types.constrained(constraints, value.getType()))); - - // Add evidence parameters to recursive calls - for(EPlaceholder ref : recursiveReferences[i]) { - ref.expression = loc(ref.expression.location, apply( - Types.NO_EFFECTS, - applyTypes(ref.expression, vars), - vars(fe))); - } - } - } - } - - private void typeCheckValuesWithTypeAnnotations() { - ArrayList givenConstraints = new ArrayList(); - for(SCLValue value : valuesWithTypeAnnotation) { - Type type = value.getType(); - if(type != null) { - if(PRINT_VALUES) { - System.out.println("---------------------------------------------"); - System.out.println("--- " + value.getName() + " :: " + type); - } - Expression expression = value.getExpression(); - ArrayList vars = new ArrayList(); - type = Types.removeForAll(type, vars); - type = Types.removePred(type, givenConstraints); - - /*System.out.println("---------------------------------------------"); - TypeUnparsingContext tuc = new TypeUnparsingContext(); - System.out.println("--- " + value.getName() + " :: " + type.toString(tuc)); - for(TPred t : givenConstraints) - System.out.println(">>> " + t.toString(tuc)); - */ - TypingContext context = new TypingContext(errorLog, environment); - //System.out.println(expression); - expression = expression.checkType(context, type); - //System.out.println(expression); - expression.getType().addPolarity(Polarity.POSITIVE); - context.solveSubsumptions(expression.getLocation()); - ArrayList demands = context.getConstraintDemand(); - if(!demands.isEmpty() || !givenConstraints.isEmpty()) { - ReducedConstraints red = - ConstraintSolver.solve(ce, givenConstraints, demands, true); - givenConstraints.clear(); - for(Constraint c : red.unsolvedConstraints) { - errorLog.log(c.getDemandLocation(), - "Constraint <"+c.constraint+"> is not given and cannot be derived."); - } - if(errorLog.isEmpty()) { // To prevent exceptions - expression = ExpressionAugmentation.augmentSolved( - red.solvedConstraints, - expression); - expression = ExpressionAugmentation.augmentUnsolved( - red.givenConstraints, - expression); - } - } - else { - if(errorLog.isEmpty()) // To prevent exceptions - expression = expression.decomposeMatching(); - } - expression = expression.closure(vars.toArray(new TVar[vars.size()])); - value.setExpression(expression); - } - } - } - - public void typeCheckRules() { - TypingContext context = new TypingContext(errorLog, environment); - for(TransformationRule rule : module.getRules()) { - context.pushEffectUpperBound(rule.location, Types.metaVar(Kinds.EFFECT)); - rule.checkType(context); - rule.setEffect(Types.canonical(context.popEffectUpperBound())); - } - context.solveSubsumptions(Locations.NO_LOCATION); - - ArrayList demands = context.getConstraintDemand(); - if(!demands.isEmpty()) { - ReducedConstraints red = - ConstraintSolver.solve(ce, new ArrayList(), demands, true); - for(Constraint c : red.unsolvedConstraints) { - errorLog.log(c.getDemandLocation(), - "Constraint <"+c.constraint+"> is not given and cannot be derived."); - } - } - - for(MappingRelation mappingRelation : module.getMappingRelations()) - for(Type parameterType : mappingRelation.parameterTypes) - if(!parameterType.isGround()) { - errorLog.log(mappingRelation.location, "Parameter types of the mapping relation are not completely determined."); - break; - } - - /*for(Rule rule : module.getRules()) { - System.out.println(rule.name); - for(Variable variable : rule.variables) - System.out.println(" " + variable.getName() + " :: " + variable.getType()); - }*/ - } -} diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeCheckingScheduler.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeCheckingScheduler.java index c3fb2dda7..cb6752527 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeCheckingScheduler.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeCheckingScheduler.java @@ -1,11 +1,5 @@ package org.simantics.scl.compiler.compilation; -import gnu.trove.impl.Constants; -import gnu.trove.map.hash.THashMap; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - import java.util.ArrayList; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; @@ -18,6 +12,12 @@ import org.simantics.scl.compiler.internal.elaboration.utils.StronglyConnectedCo import org.simantics.scl.compiler.types.TPred; import org.simantics.scl.compiler.types.TVar; +import gnu.trove.impl.Constants; +import gnu.trove.map.hash.THashMap; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + /** * Schedules the order of type checking. * diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeInferableDefinition.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeInferableDefinition.java index 34c6c1b85..17b165d7f 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeInferableDefinition.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeInferableDefinition.java @@ -1,9 +1,5 @@ package org.simantics.scl.compiler.compilation; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - import java.util.ArrayList; import java.util.Collection; @@ -13,6 +9,10 @@ import org.simantics.scl.compiler.internal.elaboration.constraints.Constraint; import org.simantics.scl.compiler.types.TPred; import org.simantics.scl.compiler.types.TVar; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + public interface TypeInferableDefinition { long getLocation(); Collection getDefinedObjects(); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/LocalBoxedArrayElementConstant.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/LocalBoxedArrayElementConstant.java index a26ee9d75..b7114a441 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/LocalBoxedArrayElementConstant.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/LocalBoxedArrayElementConstant.java @@ -1,7 +1,7 @@ package org.simantics.scl.compiler.constants; -import org.simantics.scl.compiler.internal.codegen.utils.LocalVariable; import org.cojen.classfile.TypeDesc; +import org.simantics.scl.compiler.internal.codegen.utils.LocalVariable; import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder; import org.simantics.scl.compiler.internal.codegen.utils.TransientClassBuilder; import org.simantics.scl.compiler.types.Type; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/LocalVariableConstant.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/LocalVariableConstant.java index 782f34e39..7de438d15 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/LocalVariableConstant.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/LocalVariableConstant.java @@ -1,7 +1,7 @@ package org.simantics.scl.compiler.constants; -import org.simantics.scl.compiler.internal.codegen.utils.LocalVariable; import org.cojen.classfile.TypeDesc; +import org.simantics.scl.compiler.internal.codegen.utils.LocalVariable; import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder; import org.simantics.scl.compiler.internal.codegen.utils.TransientClassBuilder; import org.simantics.scl.compiler.types.Type; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/generic/ClassRef.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/generic/ClassRef.java index 5686d6340..2ff26cf2d 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/generic/ClassRef.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/generic/ClassRef.java @@ -1,7 +1,5 @@ package org.simantics.scl.compiler.constants.generic; -import gnu.trove.map.hash.THashMap; - import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; @@ -20,6 +18,8 @@ import org.simantics.scl.compiler.constants.generic.MethodRef.StaticFieldRef; import org.simantics.scl.compiler.constants.generic.MethodRef.StaticMethodRef; import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilderBase; +import gnu.trove.map.hash.THashMap; + /** * This class is a reference to a Java class that contains a map of MethodRef for each * method declared by the referenced class. diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/SimplificationContext.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/SimplificationContext.java index e983e1277..90e93f3d0 100755 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/SimplificationContext.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/SimplificationContext.java @@ -1,8 +1,5 @@ package org.simantics.scl.compiler.elaboration.contexts; -import gnu.trove.list.array.TLongArrayList; -import gnu.trove.map.hash.THashMap; - import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.common.names.Name; import org.simantics.scl.compiler.constants.Constant; @@ -30,6 +27,9 @@ import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.MatchException; import org.simantics.scl.compiler.types.util.MultiFunction; +import gnu.trove.list.array.TLongArrayList; +import gnu.trove.map.hash.THashMap; + public class SimplificationContext implements EnvironmentalContext { Environment environment; ErrorLog errorLog; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/TranslationContext.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/TranslationContext.java index 961fa902b..b5f9f93e9 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/TranslationContext.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/TranslationContext.java @@ -1,10 +1,5 @@ package org.simantics.scl.compiler.elaboration.contexts; -import gnu.trove.list.array.TIntArrayList; -import gnu.trove.map.hash.THashMap; -import gnu.trove.procedure.TObjectProcedure; -import gnu.trove.set.hash.THashSet; - import java.util.ArrayList; import java.util.Arrays; @@ -12,6 +7,7 @@ import org.simantics.scl.compiler.common.names.Name; import org.simantics.scl.compiler.common.precedence.Associativity; import org.simantics.scl.compiler.common.precedence.Precedence; import org.simantics.scl.compiler.elaboration.expressions.Case; +import org.simantics.scl.compiler.elaboration.expressions.EAmbiguous; import org.simantics.scl.compiler.elaboration.expressions.EConstant; import org.simantics.scl.compiler.elaboration.expressions.EEntityTypeAnnotation; import org.simantics.scl.compiler.elaboration.expressions.EError; @@ -36,6 +32,13 @@ import org.simantics.scl.compiler.environment.filter.AcceptAllNamespaceFilter; import org.simantics.scl.compiler.errors.ErrorLog; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.parsing.declarations.DValueAst; +import org.simantics.scl.compiler.top.SCLCompilerConfiguration; +import org.simantics.scl.compiler.types.Type; + +import gnu.trove.list.array.TIntArrayList; +import gnu.trove.map.hash.THashMap; +import gnu.trove.procedure.TObjectProcedure; +import gnu.trove.set.hash.THashSet; public class TranslationContext extends TypeTranslationContext implements EnvironmentalContext { @@ -147,7 +150,45 @@ public class TranslationContext extends TypeTranslationContext implements Enviro } private Expression resolveIn(long location, Namespace namespace, String name) { - SCLValue value = resolveValueIn(location, namespace, name); + SCLValue value; + try { + value = resolveValueIn(location, namespace, name); + } catch (AmbiguousNameException e) { + if(SCLCompilerConfiguration.ALLOW_OVERLOADING) { + EAmbiguous.Alternative[] alternatives = new EAmbiguous.Alternative[e.conflictingModules.length]; + //System.out.println("Overloading:"); + for(int i=0;i recursiveValues; public ArrayList recursiveReferences; + // Overloading + public ArrayList overloadedExpressions = new ArrayList(); + //TypeUnparsingContext tuc = new TypeUnparsingContext(); Environment environment; @@ -258,7 +262,7 @@ public class TypingContext implements EnvironmentalContext { * Instantiates type abstractions and constraints from the value. */ public Expression instantiate(Expression expr) { - Type type = Types.weakCanonical(expr.getType()); + Type type = Types.canonical(expr.getType()); while(type instanceof TForAll) { TForAll forAll = (TForAll)type; TVar var = forAll.var; @@ -297,7 +301,7 @@ public class TypingContext implements EnvironmentalContext { * type applications, lambdas and effect subsumptions. */ public Expression subsume(Expression expr, Type b) { - b = Types.weakCanonical(b); + b = Types.canonical(b); /*if(b instanceof TForAll) { TForAll forAll = (TForAll)b; TVar var = forAll.var; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/equation/EqGuard.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/equation/EqGuard.java index c753924e6..8b2494347 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/equation/EqGuard.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/equation/EqGuard.java @@ -56,7 +56,7 @@ public class EqGuard extends Equation { @Override public void checkType(TypingContext context) { - guard = guard.inferType(context); + guard = guard.checkIgnoredType(context); } @Override diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ASTExpression.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ASTExpression.java index aeeb1ec1e..af0a43d08 100755 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ASTExpression.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ASTExpression.java @@ -1,9 +1,5 @@ package org.simantics.scl.compiler.elaboration.expressions; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; @@ -11,6 +7,10 @@ import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.exceptions.MatchException; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + public abstract class ASTExpression extends SimplifiableExpression { public ASTExpression() { } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Case.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Case.java index 219cce461..50eda1c13 100755 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Case.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Case.java @@ -1,9 +1,5 @@ package org.simantics.scl.compiler.elaboration.expressions; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext; import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; @@ -13,6 +9,10 @@ import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator import org.simantics.scl.compiler.internal.parsing.Symbol; import org.simantics.scl.compiler.types.Type; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + public class Case extends Symbol { public Expression[] patterns; public Expression value; @@ -99,6 +99,17 @@ public class Case extends Symbol { patterns[i] = patterns[i].checkTypeAsPattern(context, parameterTypes[i]); value = value.checkType(context, requiredType); } + + public void checkIgnoredType(TypingContext context, Type[] parameterTypes) { + if(patterns.length != parameterTypes.length) { + context.getErrorLog().log(location, "This case has different arity ("+patterns.length+ + ") than than the first case (+"+parameterTypes.length+"+)."); + return; + } + for(int i=0;i allRefs, + TIntHashSet refs) { + } + + @Override + public void collectVars(TObjectIntHashMap allVars, + TIntHashSet vars) { + } + + @Override + public void forVariables(VariableProcedure procedure) { + } + + @Override + protected void updateType() throws MatchException { + throw new InternalCompilerError(); + } + + private Type getCommonSkeleton() { + Type[] types = new Type[activeCount]; + for(int i=0,j=0;i unifications = new THashMap(); + Type requiredType = getType(); + if(DEBUG) + System.out.println("EAmbigious.filterActive with " + requiredType); + for(int i=0;i, but no alteratives match the type: "); + for(int i=0;i, but multiple values match the type: "); + for(int i=0;i vars) { + } + + @Override + public Expression resolve(TranslationContext context) { + throw new InternalCompilerError("EAmbiguousConstant should not exist in resolve phase."); + } + + @Override + public void setLocationDeep(long loc) { + if(location == Locations.NO_LOCATION) + location = loc; + } + + @Override + public Expression decorate(ExpressionDecorator decorator) { + return this; + } + + @Override + public void collectEffects(THashSet effects) { + // TODO Auto-generated method stub + } + + @Override + public void accept(ExpressionVisitor visitor) { + // TODO Auto-generated method stub + } + + @Override + public Expression simplify(SimplificationContext context) { + if(resolvedExpression != null) + return resolvedExpression; + else { + context.getErrorLog().log(location, getAmbiguousDescription(getType())); + return this; + } + } + + public void assertResolved(ErrorLog errorLog) { + if(resolvedExpression == null) + errorLog.log(location, getAmbiguousDescription(getType())); + } + + @Override + public Expression accept(ExpressionTransformer transformer) { + return transformer.transform(this); + } + +} diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EApply.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EApply.java index fb27b9198..8df327362 100755 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EApply.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EApply.java @@ -1,12 +1,9 @@ package org.simantics.scl.compiler.elaboration.expressions; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - import java.util.ArrayList; import org.simantics.scl.compiler.common.names.Name; +import org.simantics.scl.compiler.constants.NoRepConstant; import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext; import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; @@ -26,6 +23,8 @@ import org.simantics.scl.compiler.internal.interpreted.IApply; import org.simantics.scl.compiler.internal.interpreted.IExpression; import org.simantics.scl.compiler.internal.interpreted.IListLiteral; import org.simantics.scl.compiler.top.ExpressionInterpretationContext; +import org.simantics.scl.compiler.types.Skeletons; +import org.simantics.scl.compiler.types.TFun; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.MatchException; @@ -33,6 +32,10 @@ import org.simantics.scl.compiler.types.exceptions.UnificationException; import org.simantics.scl.compiler.types.kinds.Kinds; import org.simantics.scl.compiler.types.util.MultiFunction; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + public class EApply extends Expression { Expression function; Expression[] parameters; @@ -248,8 +251,7 @@ public class EApply extends Expression { return new IApply(function.toIExpression(target), parametersI); } - @Override - public Expression inferType(TypingContext context) { + private void inferType(TypingContext context, boolean ignoreResult) { function = function.inferType(context); function = context.instantiate(function); MultiFunction mfun; @@ -265,7 +267,12 @@ public class EApply extends Expression { setType(Types.metaVar(Kinds.STAR)); for(int i=0;i assignments; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EPreRuleset.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EPreRuleset.java index ff27eb03a..74f24ebb8 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EPreRuleset.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EPreRuleset.java @@ -1,13 +1,13 @@ package org.simantics.scl.compiler.elaboration.expressions; -import gnu.trove.map.hash.THashMap; - import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.expressions.ERuleset.DatalogRule; import org.simantics.scl.compiler.elaboration.expressions.block.RuleStatement; import org.simantics.scl.compiler.elaboration.relations.LocalRelation; import org.simantics.scl.compiler.errors.Locations; +import gnu.trove.map.hash.THashMap; + public class EPreRuleset extends ASTExpression { RuleStatement[] statements; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ERealLiteral.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ERealLiteral.java index 644e31ab6..f2e17aa00 100755 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ERealLiteral.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ERealLiteral.java @@ -1,10 +1,6 @@ package org.simantics.scl.compiler.elaboration.expressions; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.constants.DoubleConstant; import org.simantics.scl.compiler.constants.FloatConstant; @@ -19,6 +15,10 @@ import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.MatchException; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + public class ERealLiteral extends SimplifiableExpression { public String value; EVariable constraint; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ERecord.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ERecord.java index cbb69a34b..32999dcb4 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ERecord.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ERecord.java @@ -52,8 +52,29 @@ public class ERecord extends ASTExpression { return new EError(constructor.location); } THashMap recordMap = new THashMap(fields.length); - for(FieldAssignment field : fields) - recordMap.put(field.name, field); + for(FieldAssignment field : fields) { + if(field.value == null) { + String bestMatch = null; + int bestMatchLength = 0; + for(int i=0;i bestMatchLength) { + bestMatch = fieldName; + bestMatchLength = fieldName.length(); + } + } + if(bestMatch == null) { + context.getErrorLog().log(field.location, "Invalid shorthand field " + field.name + " is defined twice."); + return new EError(location); + } + field.value = new EVar(field.location, field.name); + field.name = bestMatch; + } + if(recordMap.put(field.name, field) != null) { + context.getErrorLog().log(field.location, "Field " + field.name + " is defined more than once."); + return new EError(location); + } + } Expression[] parameters = new Expression[fieldNames.length]; boolean error = false; for(int i=0;i vars) { for(DatalogRule rule : rules) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESelect.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESelect.java index 9a0bb040d..1e9295233 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESelect.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESelect.java @@ -8,9 +8,6 @@ import static org.simantics.scl.compiler.elaboration.expressions.Expressions.new import static org.simantics.scl.compiler.elaboration.expressions.Expressions.seq; import static org.simantics.scl.compiler.elaboration.expressions.Expressions.tuple; import static org.simantics.scl.compiler.elaboration.expressions.Expressions.var; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.common.names.Name; @@ -30,6 +27,10 @@ import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.MatchException; import org.simantics.scl.compiler.types.kinds.Kinds; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + public class ESelect extends SimplifiableExpression { private final Type ARRAY_LIST = Types.con("ArrayList", "T"); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESimpleLambda.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESimpleLambda.java index 071588ab9..e1efb3045 100755 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESimpleLambda.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESimpleLambda.java @@ -1,9 +1,5 @@ package org.simantics.scl.compiler.elaboration.expressions; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - import java.util.ArrayList; import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; @@ -27,6 +23,10 @@ import org.simantics.scl.compiler.types.exceptions.UnificationException; import org.simantics.scl.compiler.types.kinds.Kinds; import org.simantics.scl.compiler.types.util.MultiFunction; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + public class ESimpleLambda extends Expression { public Variable parameter; public Expression value; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESimpleLet.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESimpleLet.java index 53984840d..8e73b2392 100755 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESimpleLet.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESimpleLet.java @@ -141,7 +141,7 @@ public class ESimpleLet extends Expression { private void checkBinding(TypingContext context) { if(variable == null) - value = value.inferType(context); + value = value.checkIgnoredType(context); else if(variable.getType() == null) { value = value.inferType(context); variable.setType(value.getType()); @@ -168,6 +168,13 @@ public class ESimpleLet extends Expression { in = in.checkType(context, requiredType); return this; } + + @Override + public Expression checkIgnoredType(TypingContext context) { + checkBinding(context); + in = in.checkIgnoredType(context); + return this; + } @Override public Expression decorate(ExpressionDecorator decorator) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ETransformation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ETransformation.java index 63fee96ca..24584fe65 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ETransformation.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ETransformation.java @@ -1,9 +1,5 @@ package org.simantics.scl.compiler.elaboration.expressions; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -20,6 +16,10 @@ import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.MatchException; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + public class ETransformation extends SimplifiableExpression { public static final Object TRANSFORMATION_RULES_TYPECHECKED = new Object(); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ETypeAnnotation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ETypeAnnotation.java index 48969e77b..cfeab99f4 100755 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ETypeAnnotation.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ETypeAnnotation.java @@ -1,9 +1,5 @@ package org.simantics.scl.compiler.elaboration.expressions; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; @@ -13,6 +9,10 @@ import org.simantics.scl.compiler.internal.parsing.types.TypeAst; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.exceptions.MatchException; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + public class ETypeAnnotation extends SimplifiableExpression { Expression value; Type type; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EVariable.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EVariable.java index 553677626..ca87d72c4 100755 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EVariable.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EVariable.java @@ -1,9 +1,5 @@ package org.simantics.scl.compiler.elaboration.expressions; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - import java.util.ArrayList; import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; @@ -25,6 +21,10 @@ import org.simantics.scl.compiler.types.exceptions.MatchException; import org.simantics.scl.compiler.types.kinds.Kinds; import org.simantics.scl.compiler.types.util.TypeUnparsingContext; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + public class EVariable extends Expression { public static final EVariable[] EMPTY_ARRAY = new EVariable[0]; @@ -144,9 +144,12 @@ public class EVariable extends Expression { @Override public Expression inferType(TypingContext context) { - if(context.isInPattern()) + if(context.isInPattern()) { variable.setType(Types.metaVar(Kinds.STAR)); - return this; + return this; + } + else + return applyPUnit(context); } @Override diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EWhen.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EWhen.java index e7907f357..8021c407b 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EWhen.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EWhen.java @@ -1,9 +1,5 @@ package org.simantics.scl.compiler.elaboration.expressions; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext; import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; @@ -22,6 +18,10 @@ import org.simantics.scl.compiler.types.exceptions.MatchException; import org.simantics.scl.compiler.types.exceptions.UnificationException; import org.simantics.scl.compiler.types.kinds.Kinds; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + public class EWhen extends SimplifiableExpression { public Query query; @@ -79,7 +79,7 @@ public class EWhen extends SimplifiableExpression { for(Variable variable : variables) variable.setType(Types.metaVar(Kinds.STAR)); query.checkType(context); - action.checkType(context, Types.UNIT); + action.checkIgnoredType(context); // Compile query return compile(context); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Expression.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Expression.java index 83d7ec4e7..edf93841b 100755 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Expression.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Expression.java @@ -1,13 +1,11 @@ package org.simantics.scl.compiler.elaboration.expressions; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - import java.util.ArrayList; import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.common.precedence.Precedence; +import org.simantics.scl.compiler.constants.NoRepConstant; +import org.simantics.scl.compiler.elaboration.contexts.EnvironmentalContext; import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext; import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; @@ -36,6 +34,10 @@ import org.simantics.scl.compiler.types.exceptions.MatchException; import org.simantics.scl.compiler.types.kinds.Kinds; import org.simantics.scl.compiler.types.util.Typed; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + public abstract class Expression extends Symbol implements Typed { public static final Expression[] EMPTY_ARRAY = new Expression[0]; @@ -77,10 +79,30 @@ public abstract class Expression extends Symbol implements Typed { public Expression inferType(TypingContext context) { return checkBasicType(context, Types.metaVar(Kinds.STAR)); } - - public Expression checkBasicType(TypingContext context, Type requiredType) { - return context.subsume(inferType(context), requiredType); - } + + public Expression checkBasicType(TypingContext context, Type requiredType) { + return context.subsume(inferType(context), requiredType); + } + + protected Expression applyPUnit(EnvironmentalContext context) { + Type type = Types.canonical(getType()); + if(type instanceof TFun) { + TFun fun = (TFun)type; + if(fun.getCanonicalDomain() == Types.PUNIT) { + EApply result = new EApply(location, this, new ELiteral(NoRepConstant.PUNIT)); + result.effect = fun.getCanonicalEffect(); + return result; + } + } + return this; + } + + public Expression checkIgnoredType(TypingContext context) { + Expression expression = inferType(context); + if(Types.canonical(expression.getType()) != Types.UNIT) + expression = new ESimpleLet(location, null, expression, new ELiteral(NoRepConstant.PUNIT)); + return expression; + } /** * Checks the type of the expression against the given type. Adds type @@ -89,7 +111,7 @@ public abstract class Expression extends Symbol implements Typed { public final Expression checkType(TypingContext context, Type requiredType) { //System.out.println("checkType: " + this + " :: " + requiredType); if(!context.isInPattern()) { - requiredType = Types.weakCanonical(requiredType); + requiredType = Types.canonical(requiredType); if(requiredType instanceof TForAll) { TForAll forAll = (TForAll)requiredType; TVar var = forAll.var; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ExpressionTransformer.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ExpressionTransformer.java index 1bd50bb6a..baeedd0f0 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ExpressionTransformer.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ExpressionTransformer.java @@ -2,6 +2,7 @@ package org.simantics.scl.compiler.elaboration.expressions; public interface ExpressionTransformer { + Expression transform(EAmbiguous expression); Expression transform(EApply expression); Expression transform(EApplyType expression); Expression transform(EAsPattern expression); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/GuardedExpressionGroup.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/GuardedExpressionGroup.java index 9bec11512..48f72eeac 100755 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/GuardedExpressionGroup.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/GuardedExpressionGroup.java @@ -1,10 +1,5 @@ package org.simantics.scl.compiler.elaboration.expressions; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - -import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext; import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; @@ -13,12 +8,17 @@ import org.simantics.scl.compiler.environment.Environment; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.codegen.continuations.ICont; import org.simantics.scl.compiler.internal.codegen.references.IVal; +import org.simantics.scl.compiler.internal.codegen.ssa.exits.Throw; import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter; import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.MatchException; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + public class GuardedExpressionGroup extends Expression { public GuardedExpression[] expressions; @@ -58,7 +58,7 @@ public class GuardedExpressionGroup extends Expression { CodeWriter failure = w.createBlock(); compile(env, w, success.getContinuation(), failure.getContinuation()); w.continueAs(success); - failure.throw_(location, "Matching failure at: " + toString()); + failure.throw_(location, Throw.MatchingException, "Matching failure at: " + toString()); return result; //throw new InternalCompilerError("GuardedExpressionGroup should be handled in match compilation."); } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/StandardExpressionTransformer.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/StandardExpressionTransformer.java index 17f13889d..1a2f451ee 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/StandardExpressionTransformer.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/StandardExpressionTransformer.java @@ -38,6 +38,11 @@ public class StandardExpressionTransformer implements ExpressionTransformer, QueryTransformer, ListQualifierTransformer, StatementVisitor, EquationVisitor { + @Override + public Expression transform(EAmbiguous expression) { + return expression; + } + @Override public Expression transform(EApply expression) { expression.function = expression.function.accept(this); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/accessor/ExpressionAccessor.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/accessor/ExpressionAccessor.java index 0d8da56d4..db1da2bd8 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/accessor/ExpressionAccessor.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/accessor/ExpressionAccessor.java @@ -1,9 +1,5 @@ package org.simantics.scl.compiler.elaboration.expressions.accessor; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; @@ -14,6 +10,10 @@ import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.types.Types; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + public class ExpressionAccessor extends FieldAccessor { public Expression fieldName; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/accessor/FieldAccessor.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/accessor/FieldAccessor.java index 349623178..a6eeb3f55 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/accessor/FieldAccessor.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/accessor/FieldAccessor.java @@ -1,9 +1,5 @@ package org.simantics.scl.compiler.elaboration.expressions.accessor; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; @@ -13,6 +9,10 @@ import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure; import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.internal.parsing.Symbol; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + public abstract class FieldAccessor extends Symbol { public char accessSeparator; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/block/GuardStatement.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/block/GuardStatement.java index 23733e9c1..59aa3ebe2 100755 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/block/GuardStatement.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/block/GuardStatement.java @@ -19,11 +19,12 @@ public class GuardStatement extends Statement { @Override public Expression toExpression(EnvironmentalContext context, boolean monadic, Expression in) { - Variable var = new Variable("_"); - if(monadic) + if(monadic) { + Variable var = new Variable("_"); return new EBind(location, new EVariable(location, var), value, in); + } else - return new ESimpleLet(location, var, value, in); + return new ESimpleLet(location, null, value, in); } @Override diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListAssignment.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListAssignment.java index 5c82a5aea..5f042ff93 100755 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListAssignment.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListAssignment.java @@ -1,9 +1,5 @@ package org.simantics.scl.compiler.elaboration.expressions.list; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; @@ -16,6 +12,10 @@ import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.types.Type; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + public class ListAssignment extends ListQualifier { public Expression pattern; public Expression value; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListGenerator.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListGenerator.java index 7b4cae6bd..622b53842 100755 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListGenerator.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListGenerator.java @@ -1,9 +1,5 @@ package org.simantics.scl.compiler.elaboration.expressions.list; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; @@ -19,6 +15,10 @@ import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.kinds.Kinds; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + public class ListGenerator extends ListQualifier { public Expression pattern; public Expression value; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListGuard.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListGuard.java index d591652a2..0a47f04b1 100755 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListGuard.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListGuard.java @@ -1,9 +1,5 @@ package org.simantics.scl.compiler.elaboration.expressions.list; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; @@ -15,6 +11,10 @@ import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + public class ListGuard extends ListQualifier { public Expression condition; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListQualifier.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListQualifier.java index e05501e1e..270c3ffc7 100755 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListQualifier.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListQualifier.java @@ -1,9 +1,5 @@ package org.simantics.scl.compiler.elaboration.expressions.list; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; @@ -13,6 +9,10 @@ import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator import org.simantics.scl.compiler.internal.parsing.Symbol; import org.simantics.scl.compiler.types.Type; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + public abstract class ListQualifier extends Symbol { public abstract void checkType(TypingContext context); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListSeq.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListSeq.java index c5affbf96..84fa63e9c 100755 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListSeq.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListSeq.java @@ -1,9 +1,5 @@ package org.simantics.scl.compiler.elaboration.expressions.list; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; @@ -14,6 +10,10 @@ import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.types.Type; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + public class ListSeq extends ListQualifier { public ListQualifier a; public ListQualifier b; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListThen.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListThen.java index 5867a5cfe..c79714c4e 100755 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListThen.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListThen.java @@ -1,9 +1,5 @@ package org.simantics.scl.compiler.elaboration.expressions.list; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; @@ -18,6 +14,10 @@ import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.UnificationException; import org.simantics.scl.compiler.types.kinds.Kinds; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + public class ListThen extends ListQualifier { public ListQualifier left; public Expression transformer; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/printing/ExpressionToStringVisitor.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/printing/ExpressionToStringVisitor.java index c5f8f3621..6cbdb6f6b 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/printing/ExpressionToStringVisitor.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/printing/ExpressionToStringVisitor.java @@ -9,6 +9,7 @@ import org.simantics.scl.compiler.elaboration.expressions.EApplyType; import org.simantics.scl.compiler.elaboration.expressions.EAsPattern; import org.simantics.scl.compiler.elaboration.expressions.EBind; import org.simantics.scl.compiler.elaboration.expressions.EConstant; +import org.simantics.scl.compiler.elaboration.expressions.ECoveringBranchPoint; import org.simantics.scl.compiler.elaboration.expressions.EEnforce; import org.simantics.scl.compiler.elaboration.expressions.EEquations; import org.simantics.scl.compiler.elaboration.expressions.EError; @@ -25,7 +26,6 @@ import org.simantics.scl.compiler.elaboration.expressions.EListLiteral; import org.simantics.scl.compiler.elaboration.expressions.ELiteral; import org.simantics.scl.compiler.elaboration.expressions.EMatch; import org.simantics.scl.compiler.elaboration.expressions.EPlaceholder; -import org.simantics.scl.compiler.elaboration.expressions.ECoveringBranchPoint; import org.simantics.scl.compiler.elaboration.expressions.ERealLiteral; import org.simantics.scl.compiler.elaboration.expressions.ERuleset; import org.simantics.scl.compiler.elaboration.expressions.ESelect; @@ -331,7 +331,7 @@ public class ExpressionToStringVisitor implements ExpressionVisitor, QueryVisito ESimpleLet let = (ESimpleLet)expression; Variable variable = let.getVariable(); Expression value = let.getValue(); - if("_".equals(variable.getName())) + if(variable == null || "_".equals(variable.getName())) printAsDo(value); else { newLine(); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/MinigraphModule.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/MinigraphModule.java index b9534f76b..6bdaaea7b 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/MinigraphModule.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/MinigraphModule.java @@ -1,7 +1,10 @@ package org.simantics.scl.compiler.elaboration.java; -import static org.simantics.scl.compiler.elaboration.expressions.Expressions.*; +import static org.simantics.scl.compiler.elaboration.expressions.Expressions.apply; +import static org.simantics.scl.compiler.elaboration.expressions.Expressions.constant; +import static org.simantics.scl.compiler.elaboration.expressions.Expressions.string; +import static org.simantics.scl.compiler.elaboration.expressions.Expressions.var; import org.cojen.classfile.TypeDesc; import org.simantics.scl.compiler.constants.generic.CallJava; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/macros/StandardMacroRule.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/macros/StandardMacroRule.java index 6319e58b2..a154dff23 100755 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/macros/StandardMacroRule.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/macros/StandardMacroRule.java @@ -1,7 +1,5 @@ package org.simantics.scl.compiler.elaboration.macros; -import gnu.trove.map.hash.THashMap; - import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext; import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.expressions.EApply; @@ -13,6 +11,8 @@ import org.simantics.scl.compiler.elaboration.expressions.Variable; import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; +import gnu.trove.map.hash.THashMap; + /** * This is a macro rule that replaces an application with * the definition of the function. diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/modules/TypeClass.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/modules/TypeClass.java index ef73ea6af..49301b151 100755 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/modules/TypeClass.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/modules/TypeClass.java @@ -1,7 +1,5 @@ package org.simantics.scl.compiler.elaboration.modules; -import gnu.trove.map.hash.THashMap; - import java.util.ArrayList; import org.cojen.classfile.TypeDesc; @@ -16,6 +14,8 @@ import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.kinds.Kinds; +import gnu.trove.map.hash.THashMap; + public class TypeClass extends TypeConstructor { public final TPred[] context; public final TCon name; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/modules/TypeClassInstance.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/modules/TypeClassInstance.java index c9bfa6fde..681c66972 100755 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/modules/TypeClassInstance.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/modules/TypeClassInstance.java @@ -1,12 +1,12 @@ package org.simantics.scl.compiler.elaboration.modules; -import gnu.trove.map.hash.THashMap; - import org.simantics.scl.compiler.constants.Constant; import org.simantics.scl.compiler.elaboration.errors.ElabNode; import org.simantics.scl.compiler.types.TPred; import org.simantics.scl.compiler.types.TVar; +import gnu.trove.map.hash.THashMap; + public class TypeClassInstance extends ElabNode { public final TypeClass typeClass; public final TPred[] context; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAbstractCombiner.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAbstractCombiner.java index 0fc36b6d7..53eb780fd 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAbstractCombiner.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAbstractCombiner.java @@ -1,9 +1,5 @@ package org.simantics.scl.compiler.elaboration.query; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - import java.util.Arrays; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; @@ -16,7 +12,10 @@ import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure; import org.simantics.scl.compiler.elaboration.query.pre.QPreExists; import org.simantics.scl.compiler.elaboration.query.pre.QPreGuard; import org.simantics.scl.compiler.errors.Locations; -import org.simantics.scl.compiler.types.Type; + +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; public abstract class QAbstractCombiner extends Query { public Query[] queries; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAbstractModifier.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAbstractModifier.java index 1f05e4734..e04246e40 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAbstractModifier.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAbstractModifier.java @@ -1,15 +1,14 @@ package org.simantics.scl.compiler.elaboration.query; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.elaboration.expressions.Variable; import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure; import org.simantics.scl.compiler.errors.Locations; -import org.simantics.scl.compiler.types.Type; + +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; public abstract class QAbstractModifier extends Query { public Query query; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAtom.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAtom.java index 95760513b..fd7dacb79 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAtom.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAtom.java @@ -1,11 +1,5 @@ package org.simantics.scl.compiler.elaboration.query; -import gnu.trove.map.hash.THashMap; -import gnu.trove.map.hash.TIntObjectHashMap; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - import java.util.ArrayList; import java.util.Set; @@ -31,16 +25,22 @@ import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; +import gnu.trove.map.hash.THashMap; +import gnu.trove.map.hash.TIntObjectHashMap; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + public class QAtom extends Query { public SCLRelation relation; public Type[] typeParameters; public Expression[] parameters; - + public QAtom(SCLRelation relation, Expression ... parameters) { this.relation = relation; this.parameters = parameters; } - + public QAtom(SCLRelation relation, Type[] typeParameters, Expression ... parameters) { this.relation = relation; this.typeParameters = typeParameters; @@ -52,7 +52,7 @@ public class QAtom extends Query { for(Expression parameter : parameters) parameter.collectFreeVariables(vars); } - + @Override public void checkType(TypingContext context) { // Type parameters @@ -60,7 +60,7 @@ public class QAtom extends Query { typeParameters = new Type[typeVariables.length]; for(int i=0;i= 0) allVariablesSet.add(v); - + context.addConstraint(new RelationConstraint(allVariablesSet.toArray(), varParameters, this, optionalVariableByParameter, procedure.requiredVariablesMask)); } catch(Exception e) { context.getQueryCompilationContext().getTypingContext().getErrorLog().log(location, e); } } - + private static void collectRefs(SCLRelation relation, TObjectIntHashMap allRefs, TIntHashSet refs) { if(relation instanceof CompositeRelation) { @@ -167,7 +167,7 @@ public class QAtom extends Query { for(Expression parameter : parameters) parameter.collectRefs(allRefs, refs); } - + @Override public void collectVars(TObjectIntHashMap allVars, TIntHashSet vars) { @@ -215,7 +215,7 @@ public class QAtom extends Query { return new Diff[] { new Diff(diffable.id, new QConjunction(eqs)) }; } } - + private static boolean containsReferenceTo( CompositeRelation relation, THashMap diffables) { @@ -235,7 +235,7 @@ public class QAtom extends Query { else return this; } - + @Override public void setLocationDeep(long loc) { if(location == Locations.NO_LOCATION) { @@ -244,7 +244,7 @@ public class QAtom extends Query { parameter.setLocationDeep(loc); } } - + @Override public void accept(QueryVisitor visitor) { visitor.visit(this); @@ -266,7 +266,7 @@ public class QAtom extends Query { } list.add(this); } - + @Override public Query accept(QueryTransformer transformer) { return transformer.transform(this); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QConjunction.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QConjunction.java index 95bb7b454..07a1f4556 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QConjunction.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QConjunction.java @@ -1,8 +1,5 @@ package org.simantics.scl.compiler.elaboration.query; -import gnu.trove.map.hash.THashMap; -import gnu.trove.map.hash.TIntObjectHashMap; - import java.util.ArrayList; import java.util.Collection; import java.util.Set; @@ -22,6 +19,9 @@ import org.simantics.scl.compiler.elaboration.relations.LocalRelation; import org.simantics.scl.compiler.elaboration.relations.SCLRelation; import org.simantics.scl.compiler.types.Types; +import gnu.trove.map.hash.THashMap; +import gnu.trove.map.hash.TIntObjectHashMap; + public class QConjunction extends QAbstractCombiner { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QDisjunction.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QDisjunction.java index f27926414..fc1c769ff 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QDisjunction.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QDisjunction.java @@ -1,9 +1,5 @@ package org.simantics.scl.compiler.elaboration.query; -import gnu.trove.map.hash.THashMap; -import gnu.trove.map.hash.TLongObjectHashMap; -import gnu.trove.set.hash.TIntHashSet; - import java.util.ArrayList; import java.util.Set; @@ -25,6 +21,10 @@ import org.simantics.scl.compiler.elaboration.relations.SCLRelation; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.types.Types; +import gnu.trove.map.hash.THashMap; +import gnu.trove.map.hash.TLongObjectHashMap; +import gnu.trove.set.hash.TIntHashSet; + public class QDisjunction extends QAbstractCombiner { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QExists.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QExists.java index cdb0a5726..5356eccc2 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QExists.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QExists.java @@ -1,8 +1,5 @@ package org.simantics.scl.compiler.elaboration.query; -import gnu.trove.map.hash.THashMap; -import gnu.trove.set.hash.THashSet; - import java.util.Collection; import java.util.Set; @@ -20,6 +17,9 @@ import org.simantics.scl.compiler.elaboration.relations.SCLRelation; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.kinds.Kinds; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; + public class QExists extends QAbstractModifier { Variable[] variables; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QMapping.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QMapping.java index fa0794fb4..ca9378c89 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QMapping.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QMapping.java @@ -1,9 +1,5 @@ package org.simantics.scl.compiler.elaboration.query; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; @@ -17,6 +13,10 @@ import org.simantics.scl.compiler.elaboration.rules.MappingRelation; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.types.Type; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + public class QMapping extends Query { public final MappingRelation mappingRelation; public final Expression[] parameters; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QNegation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QNegation.java index 20147c7df..373efa413 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QNegation.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QNegation.java @@ -1,8 +1,5 @@ package org.simantics.scl.compiler.elaboration.query; -import gnu.trove.map.hash.THashMap; -import gnu.trove.set.hash.TIntHashSet; - import org.simantics.scl.compiler.common.names.Name; import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext; import org.simantics.scl.compiler.elaboration.expressions.EApply; @@ -15,6 +12,9 @@ import org.simantics.scl.compiler.elaboration.query.compilation.UnsolvableQueryE import org.simantics.scl.compiler.elaboration.relations.LocalRelation; import org.simantics.scl.compiler.types.Type; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.TIntHashSet; + public class QNegation extends QAbstractModifier { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/Query.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/Query.java index 5154495f5..0ac54e22e 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/Query.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/Query.java @@ -1,11 +1,5 @@ package org.simantics.scl.compiler.elaboration.query; -import gnu.trove.map.hash.THashMap; -import gnu.trove.map.hash.TIntObjectHashMap; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - import java.util.ArrayList; import java.util.Set; @@ -32,6 +26,12 @@ import org.simantics.scl.compiler.elaboration.relations.LocalRelation; import org.simantics.scl.compiler.elaboration.relations.SCLRelation; import org.simantics.scl.compiler.internal.parsing.Symbol; +import gnu.trove.map.hash.THashMap; +import gnu.trove.map.hash.TIntObjectHashMap; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + public abstract class Query extends Symbol { public static final Query[] EMPTY_ARRAY = new Query[0]; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/compilation/ConstraintCollectionContext.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/compilation/ConstraintCollectionContext.java index 7b2bfc609..e77e52c8a 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/compilation/ConstraintCollectionContext.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/compilation/ConstraintCollectionContext.java @@ -1,12 +1,12 @@ package org.simantics.scl.compiler.elaboration.query.compilation; -import gnu.trove.impl.Constants; -import gnu.trove.map.hash.TObjectIntHashMap; - import java.util.ArrayList; import org.simantics.scl.compiler.elaboration.expressions.Variable; +import gnu.trove.impl.Constants; +import gnu.trove.map.hash.TObjectIntHashMap; + public class ConstraintCollectionContext { QueryCompilationContext context; ArrayList variables = new ArrayList(); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/compilation/DynamicProgrammingOrdering.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/compilation/DynamicProgrammingOrdering.java index 0506f410c..d53e4d1f2 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/compilation/DynamicProgrammingOrdering.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/compilation/DynamicProgrammingOrdering.java @@ -1,11 +1,11 @@ package org.simantics.scl.compiler.elaboration.query.compilation; -import gnu.trove.map.hash.TLongObjectHashMap; -import gnu.trove.procedure.TLongObjectProcedure; - import java.util.ArrayList; import java.util.Collections; +import gnu.trove.map.hash.TLongObjectHashMap; +import gnu.trove.procedure.TLongObjectProcedure; + public class DynamicProgrammingOrdering { final ConstraintCollectionContext collectionContext; int variableCount; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/compilation/ExpressionConstraint.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/compilation/ExpressionConstraint.java index 0c7c21e3d..c80d59f37 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/compilation/ExpressionConstraint.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/compilation/ExpressionConstraint.java @@ -1,9 +1,5 @@ package org.simantics.scl.compiler.elaboration.query.compilation; -import gnu.trove.map.hash.THashMap; -import gnu.trove.procedure.TObjectObjectProcedure; -import gnu.trove.set.hash.TIntHashSet; - import java.util.ArrayList; import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; @@ -15,6 +11,10 @@ import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; +import gnu.trove.map.hash.THashMap; +import gnu.trove.procedure.TObjectObjectProcedure; +import gnu.trove.set.hash.TIntHashSet; + public class ExpressionConstraint extends QueryConstraint { Variable variable; Expression expression; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/pre/PreQuery.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/pre/PreQuery.java index 049625f6b..ee96433d3 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/pre/PreQuery.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/pre/PreQuery.java @@ -1,9 +1,5 @@ package org.simantics.scl.compiler.elaboration.query.pre; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - import java.util.ArrayList; import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; @@ -16,7 +12,10 @@ import org.simantics.scl.compiler.elaboration.query.QExists; import org.simantics.scl.compiler.elaboration.query.Query; import org.simantics.scl.compiler.elaboration.query.QueryVisitor; import org.simantics.scl.compiler.elaboration.query.compilation.ConstraintCollectionContext; -import org.simantics.scl.compiler.types.Type; + +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; /** * Query classes that may exist before resolving diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/LocalRelation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/LocalRelation.java index 900c9627b..0a193d6c1 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/LocalRelation.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/LocalRelation.java @@ -1,6 +1,10 @@ package org.simantics.scl.compiler.elaboration.relations; -import static org.simantics.scl.compiler.elaboration.expressions.Expressions.*; +import static org.simantics.scl.compiler.elaboration.expressions.Expressions.apply; +import static org.simantics.scl.compiler.elaboration.expressions.Expressions.newVar; +import static org.simantics.scl.compiler.elaboration.expressions.Expressions.tuple; +import static org.simantics.scl.compiler.elaboration.expressions.Expressions.var; +import static org.simantics.scl.compiler.elaboration.expressions.Expressions.vars; import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.common.names.Name; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/SCLRelation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/SCLRelation.java index a14ddaf06..7b2f2a19e 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/SCLRelation.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/SCLRelation.java @@ -4,7 +4,6 @@ import org.simantics.scl.compiler.elaboration.expressions.Expression; import org.simantics.scl.compiler.elaboration.expressions.Variable; import org.simantics.scl.compiler.elaboration.query.compilation.EnforcingContext; import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationContext; -import org.simantics.scl.compiler.types.TPred; import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/TransitiveClosureRelation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/TransitiveClosureRelation.java index fb59470b3..26111e0b4 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/TransitiveClosureRelation.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/TransitiveClosureRelation.java @@ -9,14 +9,11 @@ import static org.simantics.scl.compiler.elaboration.expressions.Expressions.tup import static org.simantics.scl.compiler.elaboration.expressions.Expressions.var; import org.simantics.scl.compiler.common.names.Name; -import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.expressions.EApply; import org.simantics.scl.compiler.elaboration.expressions.EVariable; import org.simantics.scl.compiler.elaboration.expressions.Expression; import org.simantics.scl.compiler.elaboration.expressions.Variable; import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationContext; -import org.simantics.scl.compiler.errors.Locations; -import org.simantics.scl.compiler.types.TPred; import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/rules/TransformationRule.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/rules/TransformationRule.java index d70bf785e..6bf0f781b 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/rules/TransformationRule.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/rules/TransformationRule.java @@ -1,10 +1,5 @@ package org.simantics.scl.compiler.elaboration.rules; -import gnu.trove.map.hash.THashMap; -import gnu.trove.procedure.TObjectObjectProcedure; -import gnu.trove.procedure.TObjectProcedure; -import gnu.trove.set.hash.THashSet; - import org.simantics.scl.compiler.common.names.Name; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.elaboration.expressions.Variable; @@ -15,6 +10,11 @@ import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.kinds.Kinds; +import gnu.trove.map.hash.THashMap; +import gnu.trove.procedure.TObjectObjectProcedure; +import gnu.trove.procedure.TObjectProcedure; +import gnu.trove.set.hash.THashSet; + public class TransformationRule extends Symbol { public static final TransformationRule[] EMPTY_ARRAY = new TransformationRule[0]; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/AbstractLocalEnvironment.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/AbstractLocalEnvironment.java index 9b9647ee1..98e2467fa 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/AbstractLocalEnvironment.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/AbstractLocalEnvironment.java @@ -1,14 +1,13 @@ package org.simantics.scl.compiler.environment; -import gnu.trove.procedure.TObjectProcedure; - import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda; import org.simantics.scl.compiler.elaboration.expressions.Expression; import org.simantics.scl.compiler.elaboration.expressions.Variable; import org.simantics.scl.compiler.types.Type; -import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.util.ProcedureType; +import gnu.trove.procedure.TObjectProcedure; + public abstract class AbstractLocalEnvironment implements LocalEnvironment { @Override diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/ConcreteEnvironment.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/ConcreteEnvironment.java index 2fb5e41d7..e3280daf6 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/ConcreteEnvironment.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/ConcreteEnvironment.java @@ -1,12 +1,12 @@ package org.simantics.scl.compiler.environment; -import gnu.trove.map.hash.THashMap; - import java.util.Collection; import org.simantics.scl.compiler.elaboration.rules.TransformationRule; import org.simantics.scl.compiler.module.Module; +import gnu.trove.map.hash.THashMap; + public class ConcreteEnvironment extends AbstractEnvironment { private final THashMap moduleMap; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/EmptyNamespace.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/EmptyNamespace.java index 9bffef06b..ed08b7b69 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/EmptyNamespace.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/EmptyNamespace.java @@ -1,7 +1,5 @@ package org.simantics.scl.compiler.environment; -import gnu.trove.procedure.TObjectProcedure; - import java.util.function.Consumer; import org.simantics.scl.compiler.elaboration.modules.SCLValue; @@ -16,6 +14,8 @@ import org.simantics.scl.compiler.environment.filter.NamespaceFilter; import org.simantics.scl.compiler.internal.codegen.effects.EffectConstructor; import org.simantics.scl.compiler.types.TCon; +import gnu.trove.procedure.TObjectProcedure; + public enum EmptyNamespace implements Namespace { INSTANCE; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/Environments.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/Environments.java index 11bc2577d..5a55a6ca1 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/Environments.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/Environments.java @@ -1,7 +1,5 @@ package org.simantics.scl.compiler.environment; -import gnu.trove.procedure.TObjectProcedure; - import java.io.StringReader; import java.util.ArrayList; import java.util.List; @@ -27,6 +25,8 @@ import org.simantics.scl.compiler.top.SCLExpressionCompilationException; import org.simantics.scl.compiler.types.TCon; import org.simantics.scl.compiler.types.Type; +import gnu.trove.procedure.TObjectProcedure; + public class Environments { /** * Get the SCLValue object representing an SCL value defined in a given environment. diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/LocalEnvironment.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/LocalEnvironment.java index 4ea77a0e2..b40bd9cdb 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/LocalEnvironment.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/LocalEnvironment.java @@ -1,11 +1,11 @@ package org.simantics.scl.compiler.environment; -import gnu.trove.procedure.TObjectProcedure; - import org.simantics.scl.compiler.elaboration.expressions.Expression; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.util.ProcedureType; +import gnu.trove.procedure.TObjectProcedure; + /** * Provides local variable names for expressions * that do not need to defined in any module. diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/Namespace.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/Namespace.java index dc388a72c..921b9029d 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/Namespace.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/Namespace.java @@ -1,7 +1,5 @@ package org.simantics.scl.compiler.environment; -import gnu.trove.procedure.TObjectProcedure; - import java.util.function.Consumer; import org.simantics.scl.compiler.elaboration.modules.SCLValue; @@ -16,6 +14,8 @@ import org.simantics.scl.compiler.environment.filter.NamespaceFilter; import org.simantics.scl.compiler.internal.codegen.effects.EffectConstructor; import org.simantics.scl.compiler.types.TCon; +import gnu.trove.procedure.TObjectProcedure; + public interface Namespace { /** * Find a sub-namespace with a given name diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/NamespaceImpl.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/NamespaceImpl.java index 9fd58989d..bb98f1aa5 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/NamespaceImpl.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/NamespaceImpl.java @@ -1,8 +1,5 @@ package org.simantics.scl.compiler.environment; -import gnu.trove.map.hash.THashMap; -import gnu.trove.procedure.TObjectProcedure; - import java.util.ArrayList; import java.util.function.Consumer; @@ -20,6 +17,9 @@ import org.simantics.scl.compiler.internal.codegen.effects.EffectConstructor; import org.simantics.scl.compiler.module.Module; import org.simantics.scl.compiler.types.TCon; +import gnu.trove.map.hash.THashMap; +import gnu.trove.procedure.TObjectProcedure; + public class NamespaceImpl implements Namespace { private final THashMap namespaceMap; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/NamespaceSpec.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/NamespaceSpec.java index 3739edb52..8d97123f2 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/NamespaceSpec.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/NamespaceSpec.java @@ -1,11 +1,11 @@ package org.simantics.scl.compiler.environment; -import gnu.trove.map.hash.THashMap; - import java.util.Map; import org.simantics.scl.compiler.environment.NamespaceImpl.ModuleImport; +import gnu.trove.map.hash.THashMap; + public class NamespaceSpec { public final THashMap namespaceMap = new THashMap(); public final THashMap moduleMap = new THashMap(); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/filter/NamespaceFilters.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/filter/NamespaceFilters.java index 57159b861..2749ae305 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/filter/NamespaceFilters.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/filter/NamespaceFilters.java @@ -1,10 +1,10 @@ package org.simantics.scl.compiler.environment.filter; -import gnu.trove.set.hash.THashSet; - import org.simantics.scl.compiler.elaboration.expressions.EVar; import org.simantics.scl.compiler.module.ImportDeclaration.ImportSpec; +import gnu.trove.set.hash.THashSet; + public class NamespaceFilters { public static NamespaceFilter createFromSpec(ImportSpec spec) { if(spec.hiding) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/errors/CompilationErrorFormatter.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/errors/CompilationErrorFormatter.java index bd29b328b..d75417012 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/errors/CompilationErrorFormatter.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/errors/CompilationErrorFormatter.java @@ -1,11 +1,11 @@ package org.simantics.scl.compiler.errors; -import gnu.trove.list.array.TIntArrayList; - import java.io.IOException; import java.io.Reader; import java.io.StringReader; +import gnu.trove.list.array.TIntArrayList; + public class CompilationErrorFormatter { public static int[] rows(Reader reader) throws IOException { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/analysis/LoopAnalysis.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/analysis/LoopAnalysis.java index 9d6a5645a..853f316ee 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/analysis/LoopAnalysis.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/analysis/LoopAnalysis.java @@ -1,7 +1,5 @@ package org.simantics.scl.compiler.internal.codegen.analysis; -import gnu.trove.set.hash.THashSet; - import org.simantics.scl.compiler.common.names.Name; import org.simantics.scl.compiler.constants.SCLConstant; import org.simantics.scl.compiler.internal.codegen.references.Val; @@ -11,6 +9,8 @@ import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction; import org.simantics.scl.compiler.internal.codegen.ssa.binders.ValRefBinder; import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply; +import gnu.trove.set.hash.THashSet; + public class LoopAnalysis { /** diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/analysis/StatementBrowser.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/analysis/StatementBrowser.java index 576089012..e580c7c79 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/analysis/StatementBrowser.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/analysis/StatementBrowser.java @@ -1,8 +1,5 @@ package org.simantics.scl.compiler.internal.codegen.analysis; -import gnu.trove.map.hash.THashMap; -import gnu.trove.set.hash.THashSet; - import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.common.names.Name; import org.simantics.scl.compiler.constants.SCLConstant; @@ -16,6 +13,9 @@ import org.simantics.scl.compiler.internal.codegen.ssa.SSAStatement; import org.simantics.scl.compiler.internal.codegen.ssa.binders.ValRefBinder; import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; + public abstract class StatementBrowser { THashSet visited; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/optimization/OptimizationMap.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/optimization/OptimizationMap.java index 0867b4b3f..75429d9ae 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/optimization/OptimizationMap.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/optimization/OptimizationMap.java @@ -1,9 +1,9 @@ package org.simantics.scl.compiler.internal.codegen.optimization; -import gnu.trove.map.hash.THashMap; - import org.simantics.scl.compiler.common.names.Name; +import gnu.trove.map.hash.THashMap; + public class OptimizationMap { public static final THashMap OPTIMIZATIONS = new THashMap(); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/references/BoundVar.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/references/BoundVar.java index 803397ce6..1c88ba0aa 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/references/BoundVar.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/references/BoundVar.java @@ -1,7 +1,5 @@ package org.simantics.scl.compiler.internal.codegen.references; -import gnu.trove.map.hash.THashMap; - import org.cojen.classfile.TypeDesc; import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction; import org.simantics.scl.compiler.internal.codegen.ssa.binders.BoundVarBinder; @@ -11,6 +9,8 @@ import org.simantics.scl.compiler.internal.codegen.utils.TransientClassBuilder; import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; +import gnu.trove.map.hash.THashMap; + public final class BoundVar extends Val { public BoundVarBinder parent; Type type; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/references/Val.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/references/Val.java index 392dfb2fe..9837fdb77 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/references/Val.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/references/Val.java @@ -1,7 +1,5 @@ package org.simantics.scl.compiler.internal.codegen.references; -import gnu.trove.map.hash.THashMap; - import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.internal.codegen.types.BTypes; import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder; @@ -11,6 +9,8 @@ import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.MatchException; +import gnu.trove.map.hash.THashMap; + public abstract class Val implements IVal { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/exits/Throw.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/exits/Throw.java index 3af6a0073..730463ab2 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/exits/Throw.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/exits/Throw.java @@ -10,21 +10,27 @@ import org.simantics.scl.compiler.internal.codegen.references.ValRef; import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock; import org.simantics.scl.compiler.internal.codegen.ssa.SSAExit; import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction; +import org.simantics.scl.compiler.internal.codegen.utils.Constants; import org.simantics.scl.compiler.internal.codegen.utils.CopyContext; import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder; import org.simantics.scl.compiler.internal.codegen.utils.PrintingContext; import org.simantics.scl.compiler.internal.codegen.utils.SSAValidationContext; import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; +import org.simantics.scl.runtime.exceptions.MatchingException; public class Throw extends SSAExit { - private static final TypeDesc RuntimeException = + public static final TypeDesc RuntimeException = TypeDesc.forClass(RuntimeException.class); + public static final TypeDesc MatchingException = + TypeDesc.forClass(MatchingException.class); + TypeDesc exceptionClass; String description; - public Throw(String description) { + public Throw(TypeDesc exceptionClass, String description) { + this.exceptionClass = exceptionClass; this.description = description; } @@ -38,10 +44,14 @@ public class Throw extends SSAExit { public void generateCode(MethodBuilder mb) { //mb.push(exception.getBinding()); //cb.mapLineNumber(location); - mb.newObject(RuntimeException); + mb.newObject(exceptionClass); mb.dup(); - mb.loadConstant(description); - mb.invokeConstructor(RuntimeException, new TypeDesc[] {TypeDesc.STRING}); + if(description == null) + mb.invokeConstructor(exceptionClass, Constants.EMPTY_TYPEDESC_ARRAY); + else { + mb.loadConstant(description); + mb.invokeConstructor(exceptionClass, new TypeDesc[] {TypeDesc.STRING}); + } mb.throwObject(); } @@ -56,7 +66,7 @@ public class Throw extends SSAExit { @Override public SSAExit copy(CopyContext context) { - return new Throw(description); + return new Throw(exceptionClass, description); } @Override diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/statements/LetApply.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/statements/LetApply.java index 8d5d24e3c..83b1e0cb6 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/statements/LetApply.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/statements/LetApply.java @@ -28,7 +28,6 @@ import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.MatchException; import org.simantics.scl.compiler.types.util.MultiFunction; -import org.simantics.scl.compiler.types.util.TypeUnparsingContext; public class LetApply extends LetStatement implements ValRefBinder { private ValRef function; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/statements/LetFunctions.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/statements/LetFunctions.java index 7b1db339f..25d9c2544 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/statements/LetFunctions.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/statements/LetFunctions.java @@ -1,8 +1,5 @@ package org.simantics.scl.compiler.internal.codegen.ssa.statements; -import gnu.trove.map.hash.THashMap; -import gnu.trove.set.hash.THashSet; - import java.util.ArrayList; import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; @@ -21,6 +18,9 @@ import org.simantics.scl.compiler.internal.codegen.utils.SSAValidationContext; import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; + public class LetFunctions extends SSAStatement implements FunctionBinder { long recursiveGroupLocation; SSAFunction firstFunction; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/ClassBuilder.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/ClassBuilder.java index c3db313ba..42df43181 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/ClassBuilder.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/ClassBuilder.java @@ -49,7 +49,7 @@ public class ClassBuilder { return new MethodBuilder(this, moduleBuilder, (access&Opcodes.ACC_STATIC) != 0, methodVisitor, params); } - private MethodVisitor augmentMethodVisitor(String methodName, MethodVisitor methodVisitor) { + private MethodVisitor augmentMethodVisitor(final String methodName, MethodVisitor methodVisitor) { if(SCLCompilerConfiguration.TRACE_MAX_METHOD_SIZE && moduleBuilder != null) { methodVisitor = new CodeSizeEvaluator(methodVisitor) { @Override diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/CopyContext.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/CopyContext.java index 2383c2051..e5fb40a8a 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/CopyContext.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/CopyContext.java @@ -1,7 +1,5 @@ package org.simantics.scl.compiler.internal.codegen.utils; -import gnu.trove.map.hash.THashMap; - import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.internal.codegen.continuations.Cont; import org.simantics.scl.compiler.internal.codegen.continuations.ContRef; @@ -13,6 +11,8 @@ import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; +import gnu.trove.map.hash.THashMap; + public class CopyContext { THashMap valMap = new THashMap(); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/PrintingContext.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/PrintingContext.java index 4a8969f14..88556fdb7 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/PrintingContext.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/PrintingContext.java @@ -1,8 +1,5 @@ package org.simantics.scl.compiler.internal.codegen.utils; -import gnu.trove.map.hash.THashMap; -import gnu.trove.set.hash.THashSet; - import java.util.ArrayDeque; import java.util.ArrayList; @@ -18,6 +15,9 @@ import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.util.TypeUnparsingContext; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; + public class PrintingContext { THashMap names = new THashMap(); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/SCLContextPreparationStep.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/SCLContextPreparationStep.java index bf2143c9c..8dd7a2875 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/SCLContextPreparationStep.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/SCLContextPreparationStep.java @@ -1,6 +1,5 @@ package org.simantics.scl.compiler.internal.codegen.utils; -import org.simantics.scl.compiler.internal.codegen.utils.LocalVariable; import org.cojen.classfile.TypeDesc; import org.simantics.scl.runtime.SCLContext; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/SSAValidationContext.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/SSAValidationContext.java index d58d2dd7a..923acdba2 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/SSAValidationContext.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/SSAValidationContext.java @@ -1,9 +1,5 @@ package org.simantics.scl.compiler.internal.codegen.utils; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.procedure.TObjectIntProcedure; -import gnu.trove.set.hash.THashSet; - import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.constants.Constant; import org.simantics.scl.compiler.constants.SCLConstant; @@ -17,6 +13,10 @@ import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.util.TypeUnparsingContext; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.procedure.TObjectIntProcedure; +import gnu.trove.set.hash.THashSet; + public class SSAValidationContext { public THashSet validBoundVariables = new THashSet(); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/writer/CodeWriter.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/writer/CodeWriter.java index f11babe06..6bed9f066 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/writer/CodeWriter.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/writer/CodeWriter.java @@ -1,146 +1,147 @@ -package org.simantics.scl.compiler.internal.codegen.writer; - -import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; -import org.simantics.scl.compiler.internal.codegen.continuations.Branch; -import org.simantics.scl.compiler.internal.codegen.continuations.BranchRef; -import org.simantics.scl.compiler.internal.codegen.continuations.ICont; -import org.simantics.scl.compiler.internal.codegen.references.BoundVar; -import org.simantics.scl.compiler.internal.codegen.references.IVal; -import org.simantics.scl.compiler.internal.codegen.references.ValRef; -import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock; -import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction; -import org.simantics.scl.compiler.internal.codegen.ssa.exits.If; -import org.simantics.scl.compiler.internal.codegen.ssa.exits.Jump; -import org.simantics.scl.compiler.internal.codegen.ssa.exits.Switch; -import org.simantics.scl.compiler.internal.codegen.ssa.exits.Throw; -import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply; -import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetFunctions; -import org.simantics.scl.compiler.top.SCLCompilerConfiguration; -import org.simantics.scl.compiler.types.TVar; -import org.simantics.scl.compiler.types.Type; -import org.simantics.scl.compiler.types.Types; -import org.simantics.scl.compiler.types.exceptions.MatchException; -import org.simantics.scl.compiler.types.util.MultiFunction; - -public class CodeWriter { - - ModuleWriter moduleWriter; - SSABlock block; - - CodeWriter(ModuleWriter moduleWriter, SSABlock block) { - this.moduleWriter = moduleWriter; - this.block = block; - } - - public IVal apply(int lineNumber, IVal function, IVal ... parameters) { - try { - MultiFunction mfun = Types.matchFunction(function.getType(), parameters.length); - return applyWithEffect(lineNumber, - mfun.effect, - mfun.returnType, - function, parameters); - } catch (MatchException e) { - throw new InternalCompilerError(e); - } - } - - public IVal applyWithEffectChecked(int lineNumber, Type effect, Type returnType, IVal function, IVal ... parameters) { - try { - MultiFunction mfun = Types.matchFunction(function.getType(), parameters.length); - if(!Types.equals(effect, mfun.effect)) - throw new InternalCompilerError(); - if(!Types.equals(returnType, mfun.returnType)) - throw new InternalCompilerError(); - } catch (MatchException e) { - throw new InternalCompilerError(e); - } - return applyWithEffect(lineNumber, effect, returnType, function, parameters); - } - - public IVal applyWithEffect(long location, Type effect, Type returnType, IVal function, IVal ... parameters) { - BoundVar var = new BoundVar(returnType); - LetApply apply = new LetApply(var, - effect, - function.createOccurrence(), - ValRef.createOccurrences(parameters)); - apply.location = location; - block.addStatement(apply); - return var; - } - - public CodeWriter createBlock(Type ... parameterTypes) { - SSABlock newBlock = new SSABlock(parameterTypes); - block.getParent().addBlock(newBlock); - return new CodeWriter(moduleWriter, newBlock); - } - - public CodeWriter createFunction(TVar[] typeParameters, Type effect, Type returnType, Type[] parameterTypes) { - if(SCLCompilerConfiguration.DEBUG) - if(effect == null) - throw new InternalCompilerError(); - SSAFunction function = new SSAFunction(typeParameters, effect, returnType); - SSABlock block = new SSABlock(parameterTypes); - function.addBlock(block); - BoundVar target = new BoundVar(function.getType()); - function.setTarget(target); - - this.block.addStatement(new LetFunctions(function)); - return new CodeWriter(moduleWriter, block); - } - - public RecursiveDefinitionWriter createRecursiveDefinition() { - LetFunctions let = new LetFunctions(); - block.addStatement(let); - return new RecursiveDefinitionWriter(moduleWriter, let); - } - - public void continueAs(CodeWriter codeWriter) { - this.block = codeWriter.block; - codeWriter.block = null; - } - - public IVal[] getParameters() { - return block.getParameters(); - } - - public ICont getContinuation() { - return block; - } - - public void jump(ICont cont, IVal ... parameters) { - block.setExit(new Jump(cont.createOccurrence(), - ValRef.createOccurrences(parameters))); - block = null; - } - - public void if_(IVal condition, ICont thenTarget, ICont elseTarget) { - block.setExit(new If(condition.createOccurrence(), - thenTarget.createOccurrence(), - elseTarget.createOccurrence())); - block = null; - } - - public void return_(IVal val) { - jump(block.getParent().getReturnCont(), val); - } - - public void switch_(IVal val, Branch[] branches) { - block.setExit(new Switch(val.createOccurrence(), BranchRef.toBranchRefs(branches))); - block = null; - } - - public void throw_(long location, String description) { - Throw exit = new Throw(description); - exit.location = location; - block.setExit(exit); - block = null; - } - - public ModuleWriter getModuleWriter() { - return moduleWriter; - } - - public SSAFunction getFunction() { - return block.getParent(); - } -} +package org.simantics.scl.compiler.internal.codegen.writer; + +import org.cojen.classfile.TypeDesc; +import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; +import org.simantics.scl.compiler.internal.codegen.continuations.Branch; +import org.simantics.scl.compiler.internal.codegen.continuations.BranchRef; +import org.simantics.scl.compiler.internal.codegen.continuations.ICont; +import org.simantics.scl.compiler.internal.codegen.references.BoundVar; +import org.simantics.scl.compiler.internal.codegen.references.IVal; +import org.simantics.scl.compiler.internal.codegen.references.ValRef; +import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock; +import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction; +import org.simantics.scl.compiler.internal.codegen.ssa.exits.If; +import org.simantics.scl.compiler.internal.codegen.ssa.exits.Jump; +import org.simantics.scl.compiler.internal.codegen.ssa.exits.Switch; +import org.simantics.scl.compiler.internal.codegen.ssa.exits.Throw; +import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply; +import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetFunctions; +import org.simantics.scl.compiler.top.SCLCompilerConfiguration; +import org.simantics.scl.compiler.types.TVar; +import org.simantics.scl.compiler.types.Type; +import org.simantics.scl.compiler.types.Types; +import org.simantics.scl.compiler.types.exceptions.MatchException; +import org.simantics.scl.compiler.types.util.MultiFunction; + +public class CodeWriter { + + ModuleWriter moduleWriter; + SSABlock block; + + CodeWriter(ModuleWriter moduleWriter, SSABlock block) { + this.moduleWriter = moduleWriter; + this.block = block; + } + + public IVal apply(int lineNumber, IVal function, IVal ... parameters) { + try { + MultiFunction mfun = Types.matchFunction(function.getType(), parameters.length); + return applyWithEffect(lineNumber, + mfun.effect, + mfun.returnType, + function, parameters); + } catch (MatchException e) { + throw new InternalCompilerError(e); + } + } + + public IVal applyWithEffectChecked(int lineNumber, Type effect, Type returnType, IVal function, IVal ... parameters) { + try { + MultiFunction mfun = Types.matchFunction(function.getType(), parameters.length); + if(!Types.equals(effect, mfun.effect)) + throw new InternalCompilerError(); + if(!Types.equals(returnType, mfun.returnType)) + throw new InternalCompilerError(); + } catch (MatchException e) { + throw new InternalCompilerError(e); + } + return applyWithEffect(lineNumber, effect, returnType, function, parameters); + } + + public IVal applyWithEffect(long location, Type effect, Type returnType, IVal function, IVal ... parameters) { + BoundVar var = new BoundVar(returnType); + LetApply apply = new LetApply(var, + effect, + function.createOccurrence(), + ValRef.createOccurrences(parameters)); + apply.location = location; + block.addStatement(apply); + return var; + } + + public CodeWriter createBlock(Type ... parameterTypes) { + SSABlock newBlock = new SSABlock(parameterTypes); + block.getParent().addBlock(newBlock); + return new CodeWriter(moduleWriter, newBlock); + } + + public CodeWriter createFunction(TVar[] typeParameters, Type effect, Type returnType, Type[] parameterTypes) { + if(SCLCompilerConfiguration.DEBUG) + if(effect == null) + throw new InternalCompilerError(); + SSAFunction function = new SSAFunction(typeParameters, effect, returnType); + SSABlock block = new SSABlock(parameterTypes); + function.addBlock(block); + BoundVar target = new BoundVar(function.getType()); + function.setTarget(target); + + this.block.addStatement(new LetFunctions(function)); + return new CodeWriter(moduleWriter, block); + } + + public RecursiveDefinitionWriter createRecursiveDefinition() { + LetFunctions let = new LetFunctions(); + block.addStatement(let); + return new RecursiveDefinitionWriter(moduleWriter, let); + } + + public void continueAs(CodeWriter codeWriter) { + this.block = codeWriter.block; + codeWriter.block = null; + } + + public IVal[] getParameters() { + return block.getParameters(); + } + + public ICont getContinuation() { + return block; + } + + public void jump(ICont cont, IVal ... parameters) { + block.setExit(new Jump(cont.createOccurrence(), + ValRef.createOccurrences(parameters))); + block = null; + } + + public void if_(IVal condition, ICont thenTarget, ICont elseTarget) { + block.setExit(new If(condition.createOccurrence(), + thenTarget.createOccurrence(), + elseTarget.createOccurrence())); + block = null; + } + + public void return_(IVal val) { + jump(block.getParent().getReturnCont(), val); + } + + public void switch_(IVal val, Branch[] branches) { + block.setExit(new Switch(val.createOccurrence(), BranchRef.toBranchRefs(branches))); + block = null; + } + + public void throw_(long location, TypeDesc exceptionClass, String description) { + Throw exit = new Throw(exceptionClass, description); + exit.location = location; + block.setExit(exit); + block = null; + } + + public ModuleWriter getModuleWriter() { + return moduleWriter; + } + + public SSAFunction getFunction() { + return block.getParent(); + } +} diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/writer/ModuleWriter.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/writer/ModuleWriter.java index 714f66b95..a04841765 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/writer/ModuleWriter.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/writer/ModuleWriter.java @@ -1,7 +1,5 @@ package org.simantics.scl.compiler.internal.codegen.writer; -import gnu.trove.map.hash.THashMap; - import java.util.Map; import org.simantics.scl.compiler.common.names.Name; @@ -15,6 +13,8 @@ import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.runtime.tuple.Tuple2; +import gnu.trove.map.hash.THashMap; + public class ModuleWriter { SSAModule module; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/deriving/InstanceDerivers.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/deriving/InstanceDerivers.java index b24894660..026769254 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/deriving/InstanceDerivers.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/deriving/InstanceDerivers.java @@ -1,10 +1,10 @@ package org.simantics.scl.compiler.internal.deriving; -import gnu.trove.map.hash.THashMap; - import org.simantics.scl.compiler.types.TCon; import org.simantics.scl.compiler.types.Types; +import gnu.trove.map.hash.THashMap; + public class InstanceDerivers { private static final THashMap MAP = new THashMap(); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/ConstraintEnvironment.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/ConstraintEnvironment.java index d19dfeec1..82df90007 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/ConstraintEnvironment.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/ConstraintEnvironment.java @@ -1,7 +1,5 @@ package org.simantics.scl.compiler.internal.elaboration.constraints; -import gnu.trove.map.hash.THashMap; - import org.cojen.classfile.TypeDesc; import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.constants.ClassConstant; @@ -26,6 +24,8 @@ import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; +import gnu.trove.map.hash.THashMap; + public class ConstraintEnvironment { Environment environment; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/ConstraintSet.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/ConstraintSet.java index 1473ab9c4..4b516a734 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/ConstraintSet.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/ConstraintSet.java @@ -1,8 +1,5 @@ package org.simantics.scl.compiler.internal.elaboration.constraints; -import gnu.trove.map.hash.THashMap; -import gnu.trove.set.hash.THashSet; - import java.util.ArrayList; import org.simantics.scl.compiler.elaboration.expressions.ELiteral; @@ -13,6 +10,9 @@ import org.simantics.scl.compiler.types.TCon; import org.simantics.scl.compiler.types.TPred; import org.simantics.scl.compiler.types.Types; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; + class ConstraintSet { private static int id = 0; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/ConstraintSolver.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/ConstraintSolver.java index dfff76475..dd91efb70 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/ConstraintSolver.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/ConstraintSolver.java @@ -1,8 +1,5 @@ package org.simantics.scl.compiler.internal.elaboration.constraints; -import gnu.trove.map.hash.THashMap; -import gnu.trove.set.hash.THashSet; - import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -20,6 +17,9 @@ import org.simantics.scl.compiler.types.exceptions.UnificationException; import org.simantics.scl.compiler.types.util.TConComparator; import org.simantics.scl.compiler.types.util.TypeUnparsingContext; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; + public class ConstraintSolver { public static THashSet DEFAULTS_IGNORE = new THashSet(); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/InstanceTree.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/InstanceTree.java index 3b0447394..871fc0125 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/InstanceTree.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/InstanceTree.java @@ -1,8 +1,5 @@ package org.simantics.scl.compiler.internal.elaboration.constraints; -import gnu.trove.map.hash.THashMap; -import gnu.trove.procedure.TObjectObjectProcedure; - import java.util.ArrayList; import org.simantics.scl.compiler.types.TApply; @@ -11,6 +8,9 @@ import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.util.MultiApply; +import gnu.trove.map.hash.THashMap; +import gnu.trove.procedure.TObjectObjectProcedure; + public class InstanceTree { Node root; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints2/ConstraintSolver.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints2/ConstraintSolver.java index 652bc00b4..4bd7532b4 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints2/ConstraintSolver.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints2/ConstraintSolver.java @@ -1,13 +1,13 @@ package org.simantics.scl.compiler.internal.elaboration.constraints2; -import gnu.trove.map.hash.THashMap; -import gnu.trove.procedure.TObjectObjectProcedure; - import org.simantics.scl.compiler.environment.Environment; import org.simantics.scl.compiler.types.TCon; import org.simantics.scl.compiler.types.TPred; import org.simantics.scl.compiler.types.util.TypeUnparsingContext; +import gnu.trove.map.hash.THashMap; +import gnu.trove.procedure.TObjectObjectProcedure; + public class ConstraintSolver { final Environment environment; private final THashMap constraintStores = diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints2/ConstraintStore.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints2/ConstraintStore.java index b4f2dcfa3..34973ab45 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints2/ConstraintStore.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints2/ConstraintStore.java @@ -1,8 +1,5 @@ package org.simantics.scl.compiler.internal.elaboration.constraints2; -import gnu.trove.map.hash.THashMap; -import gnu.trove.procedure.TObjectProcedure; - import java.util.ArrayList; import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; @@ -14,6 +11,9 @@ import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.util.TypeUnparsingContext; +import gnu.trove.map.hash.THashMap; +import gnu.trove.procedure.TObjectProcedure; + class ConstraintStore { private final ConstraintSolver solver; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/matching/PatternMatchingCompiler.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/matching/PatternMatchingCompiler.java index 1ca1e7c30..7f200a11c 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/matching/PatternMatchingCompiler.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/matching/PatternMatchingCompiler.java @@ -1,7 +1,5 @@ package org.simantics.scl.compiler.internal.elaboration.matching; -import gnu.trove.map.hash.THashMap; - import java.util.ArrayList; import java.util.List; @@ -27,6 +25,8 @@ import org.simantics.scl.compiler.types.TCon; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.MatchException; +import gnu.trove.map.hash.THashMap; + public class PatternMatchingCompiler { private static class ExpressionMatrix { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/profiling/BranchPointInjector.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/profiling/BranchPointInjector.java index 930dfe14b..dff462221 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/profiling/BranchPointInjector.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/profiling/BranchPointInjector.java @@ -3,6 +3,7 @@ package org.simantics.scl.compiler.internal.elaboration.profiling; import java.util.ArrayList; import org.simantics.scl.compiler.elaboration.expressions.Case; +import org.simantics.scl.compiler.elaboration.expressions.EAmbiguous; import org.simantics.scl.compiler.elaboration.expressions.EApply; import org.simantics.scl.compiler.elaboration.expressions.EApplyType; import org.simantics.scl.compiler.elaboration.expressions.EAsPattern; @@ -159,6 +160,12 @@ public class BranchPointInjector extends StandardExpressionTransformer { return expression; } + @Override + public Expression transform(EAmbiguous expression) { + ++codeCounter; + return super.transform(expression); + } + @Override public Expression transform(EApply expression) { ++codeCounter; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/subsumption/SubSolver.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/subsumption/SubSolver.java index 34b34ecce..70adf524b 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/subsumption/SubSolver.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/subsumption/SubSolver.java @@ -1,8 +1,5 @@ package org.simantics.scl.compiler.internal.elaboration.subsumption; -import gnu.trove.map.hash.THashMap; -import gnu.trove.set.hash.THashSet; - import java.util.ArrayDeque; import java.util.ArrayList; @@ -16,6 +13,9 @@ import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.util.Polarity; import org.simantics.scl.compiler.types.util.TypeUnparsingContext; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; + public class SubSolver { public static final boolean DEBUG = false; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/transformations/DecomposedRule.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/transformations/DecomposedRule.java index bfffd2c6e..28ea97dfb 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/transformations/DecomposedRule.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/transformations/DecomposedRule.java @@ -1,7 +1,5 @@ package org.simantics.scl.compiler.internal.elaboration.transformations; -import gnu.trove.procedure.TObjectObjectProcedure; - import java.util.ArrayList; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; @@ -11,6 +9,8 @@ import org.simantics.scl.compiler.elaboration.relations.LocalRelation; import org.simantics.scl.compiler.elaboration.rules.SectionName; import org.simantics.scl.compiler.elaboration.rules.TransformationRule; +import gnu.trove.procedure.TObjectObjectProcedure; + public class DecomposedRule { final TransformationRule rule; final ArrayList sourceQueries = new ArrayList(); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/transformations/TransformationBuilder.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/transformations/TransformationBuilder.java index 0beb90f83..dcb212488 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/transformations/TransformationBuilder.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/transformations/TransformationBuilder.java @@ -1,10 +1,5 @@ package org.simantics.scl.compiler.internal.elaboration.transformations; -import gnu.trove.map.hash.THashMap; -import gnu.trove.map.hash.TIntObjectHashMap; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; - import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -38,11 +33,15 @@ import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.codegen.references.IVal; import org.simantics.scl.compiler.internal.elaboration.utils.ForcedClosure; import org.simantics.scl.compiler.top.SCLCompilerConfiguration; -import org.simantics.scl.compiler.top.SCLExpressionCompilationException; import org.simantics.scl.compiler.types.TCon; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; +import gnu.trove.map.hash.THashMap; +import gnu.trove.map.hash.TIntObjectHashMap; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; + public class TransformationBuilder { private static final TCon UMap = Types.con("Unification", "UMap"); private static final Name createUMap = Name.create("Unification", "createUMap"); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/transformations/UnifiableFactory.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/transformations/UnifiableFactory.java index 0daeb02ae..7b3face61 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/transformations/UnifiableFactory.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/transformations/UnifiableFactory.java @@ -1,8 +1,5 @@ package org.simantics.scl.compiler.internal.elaboration.transformations; -import gnu.trove.map.hash.THashMap; -import gnu.trove.set.hash.THashSet; - import java.util.ArrayList; import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; @@ -25,7 +22,7 @@ import org.simantics.scl.compiler.elaboration.expressions.block.Statement; import org.simantics.scl.compiler.elaboration.modules.SCLValue; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.codegen.references.IVal; -import org.simantics.scl.compiler.internal.types.TypeHashCodeContext; +import org.simantics.scl.compiler.internal.types.HashCodeUtils; import org.simantics.scl.compiler.types.TCon; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; @@ -33,6 +30,9 @@ import org.simantics.scl.compiler.types.exceptions.MatchException; import org.simantics.scl.compiler.types.util.MultiApply; import org.simantics.scl.compiler.types.util.MultiFunction; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; + public class UnifiableFactory { private static final TCon Unifiable = Types.con("Unification", "Unifiable"); private static final Name uVar = Name.create("Unification", "uVar"); @@ -245,11 +245,11 @@ public class UnifiableFactory { @Override public int hashCode() { if(hashCode == 0) { - TypeHashCodeContext hcContext = new TypeHashCodeContext(); - hcContext.append(function.hashCode()); + int hash = HashCodeUtils.SEED; + hash = HashCodeUtils.update(hash, function.hashCode()); for(Type typeParameter : typeParameters) - typeParameter.updateHashCode(hcContext); - hashCode = hcContext.getResult(); + hash = typeParameter.hashCode(hash); + hashCode = hash; } return hashCode; } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/declarations/DRuleAst.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/declarations/DRuleAst.java index e44a18879..5d7e9172c 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/declarations/DRuleAst.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/declarations/DRuleAst.java @@ -1,11 +1,11 @@ package org.simantics.scl.compiler.internal.parsing.declarations; -import gnu.trove.map.hash.THashMap; - import java.util.ArrayList; import org.simantics.scl.compiler.elaboration.query.Query; +import gnu.trove.map.hash.THashMap; + public class DRuleAst extends DeclarationAst { public final boolean isAbstract; public final String name; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/translation/RelationRepository.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/translation/RelationRepository.java index d94d6c123..a0ac1cc4f 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/translation/RelationRepository.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/translation/RelationRepository.java @@ -1,7 +1,5 @@ package org.simantics.scl.compiler.internal.parsing.translation; -import gnu.trove.map.hash.THashMap; - import java.util.ArrayList; import java.util.Collection; @@ -9,6 +7,8 @@ import org.simantics.scl.compiler.elaboration.errors.NotPatternException; import org.simantics.scl.compiler.internal.parsing.declarations.DAnnotationAst; import org.simantics.scl.compiler.internal.parsing.declarations.DRelationAst; +import gnu.trove.map.hash.THashMap; + public class RelationRepository { THashMap> relations = new THashMap>(); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/types/TypeElaborationContext.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/types/TypeElaborationContext.java index bd563120b..bfde46773 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/types/TypeElaborationContext.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/types/TypeElaborationContext.java @@ -1,13 +1,13 @@ package org.simantics.scl.compiler.internal.types; -import gnu.trove.map.hash.THashMap; - import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.kinds.Kinds; import org.simantics.scl.compiler.types.util.ITypeEnvironment; +import gnu.trove.map.hash.THashMap; + public class TypeElaborationContext { THashMap vars; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/types/TypeHashCodeContext.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/types/TypeHashCodeContext.java index 5e7aec1a0..742325caa 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/types/TypeHashCodeContext.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/types/TypeHashCodeContext.java @@ -1,9 +1,9 @@ package org.simantics.scl.compiler.internal.types; -import gnu.trove.map.hash.TObjectIntHashMap; - import org.simantics.scl.compiler.types.TVar; +import gnu.trove.map.hash.TObjectIntHashMap; + public class TypeHashCodeContext { public static final int APPLY = 0x12345678; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/types/effects/EffectIdMap.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/types/effects/EffectIdMap.java index 149e139bd..4168fff93 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/types/effects/EffectIdMap.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/types/effects/EffectIdMap.java @@ -1,7 +1,5 @@ package org.simantics.scl.compiler.internal.types.effects; -import gnu.trove.map.hash.TObjectIntHashMap; - import java.util.ArrayList; import java.util.Collection; @@ -11,6 +9,8 @@ import org.simantics.scl.compiler.types.TUnion; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; +import gnu.trove.map.hash.TObjectIntHashMap; + public class EffectIdMap { public static final int MIN = 0; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/html/HierarchicalDocumentationRef.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/html/HierarchicalDocumentationRef.java index f39901c3b..93c8c8d2f 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/html/HierarchicalDocumentationRef.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/html/HierarchicalDocumentationRef.java @@ -1,15 +1,15 @@ package org.simantics.scl.compiler.markdown.html; -import gnu.trove.map.hash.THashMap; -import gnu.trove.procedure.TObjectProcedure; -import gnu.trove.set.hash.THashSet; - import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.simantics.scl.compiler.source.repository.ModuleSourceRepository; +import gnu.trove.map.hash.THashMap; +import gnu.trove.procedure.TObjectProcedure; +import gnu.trove.set.hash.THashSet; + public class HierarchicalDocumentationRef implements Comparable { final String name; final ArrayList children = new ArrayList(); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/html/SCLDocumentationExtensionNodeHandler.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/html/SCLDocumentationExtensionNodeHandler.java index 6a505fabb..d971f7d0f 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/html/SCLDocumentationExtensionNodeHandler.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/html/SCLDocumentationExtensionNodeHandler.java @@ -1,9 +1,5 @@ package org.simantics.scl.compiler.markdown.html; -import gnu.trove.map.hash.THashMap; -import gnu.trove.procedure.TObjectProcedure; -import gnu.trove.set.hash.THashSet; - import java.util.ArrayList; import java.util.Collections; @@ -27,6 +23,10 @@ import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.util.TypeUnparsingContext; +import gnu.trove.map.hash.THashMap; +import gnu.trove.procedure.TObjectProcedure; +import gnu.trove.set.hash.THashSet; + public class SCLDocumentationExtensionNodeHandler implements ExtensionNodeHandler { final ModuleRepository moduleRepository; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/inlines/Entities.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/inlines/Entities.java index f2d8917b8..9be7ca24b 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/inlines/Entities.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/inlines/Entities.java @@ -1,11 +1,11 @@ package org.simantics.scl.compiler.markdown.inlines; -import gnu.trove.map.hash.THashMap; - import java.io.BufferedReader; import java.io.InputStreamReader; import java.nio.charset.Charset; +import gnu.trove.map.hash.THashMap; + public class Entities { public static final THashMap ENTITY_MAP = new THashMap(); public static int MAX_ENTITY_LENGTH; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/inlines/Subject.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/inlines/Subject.java index 163d70708..a6a3abdae 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/inlines/Subject.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/inlines/Subject.java @@ -1,7 +1,5 @@ package org.simantics.scl.compiler.markdown.inlines; -import gnu.trove.map.hash.THashMap; - import org.simantics.scl.compiler.markdown.internal.Scanner; import org.simantics.scl.compiler.markdown.nodes.AutolinkNode; import org.simantics.scl.compiler.markdown.nodes.CodeNode; @@ -14,6 +12,8 @@ import org.simantics.scl.compiler.markdown.nodes.Node; import org.simantics.scl.compiler.markdown.nodes.Reference; import org.simantics.scl.compiler.markdown.nodes.TextNode; +import gnu.trove.map.hash.THashMap; + public class Subject { THashMap referenceMap; StringBuilder input; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/internal/HtmlEscape.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/internal/HtmlEscape.java index a31c70655..bd2ba47b8 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/internal/HtmlEscape.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/internal/HtmlEscape.java @@ -1,11 +1,11 @@ package org.simantics.scl.compiler.markdown.internal; -import gnu.trove.map.hash.TCharObjectHashMap; - import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; +import gnu.trove.map.hash.TCharObjectHashMap; + public class HtmlEscape { private static final Charset UTF8 = Charset.forName("UTF-8"); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/internal/MarkdownParser.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/internal/MarkdownParser.java index 7d30856c8..eb4626f66 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/internal/MarkdownParser.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/internal/MarkdownParser.java @@ -1,7 +1,5 @@ package org.simantics.scl.compiler.markdown.internal; -import gnu.trove.map.hash.THashMap; - import java.io.IOException; import java.io.Reader; import java.io.StringReader; @@ -20,6 +18,8 @@ import org.simantics.scl.compiler.markdown.nodes.Node; import org.simantics.scl.compiler.markdown.nodes.ParagraphNode; import org.simantics.scl.compiler.markdown.nodes.Reference; +import gnu.trove.map.hash.THashMap; + public class MarkdownParser { public static final boolean DEBUG = false; public static final int CODE_INDENT = 4; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/internal/Scanner.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/internal/Scanner.java index 437d80c11..0254e8e59 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/internal/Scanner.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/internal/Scanner.java @@ -1,9 +1,9 @@ package org.simantics.scl.compiler.markdown.internal; -import gnu.trove.set.hash.THashSet; - import org.simantics.scl.compiler.markdown.inlines.Subject; +import gnu.trove.set.hash.THashSet; + public class Scanner { public int level; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/LazyModule.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/LazyModule.java index 54914dd42..a5399e88f 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/LazyModule.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/LazyModule.java @@ -1,7 +1,5 @@ package org.simantics.scl.compiler.module; -import gnu.trove.map.hash.THashMap; - import java.util.Collection; import java.util.Collections; @@ -20,6 +18,8 @@ import org.simantics.scl.compiler.top.ModuleInitializer; import org.simantics.scl.compiler.types.TCon; import org.simantics.scl.runtime.profiling.BranchPoint; +import gnu.trove.map.hash.THashMap; + public abstract class LazyModule implements Module { String moduleName; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/repository/ModuleRepositories.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/repository/ModuleRepositories.java index 3a39c4e0e..13157f9fb 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/repository/ModuleRepositories.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/repository/ModuleRepositories.java @@ -1,7 +1,5 @@ package org.simantics.scl.compiler.module.repository; -import gnu.trove.procedure.TObjectProcedure; - import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; @@ -11,6 +9,8 @@ import org.simantics.scl.compiler.environment.filter.AcceptAllNamespaceFilter; import org.simantics.scl.compiler.errors.Failable; import org.simantics.scl.compiler.module.Module; +import gnu.trove.procedure.TObjectProcedure; + public class ModuleRepositories { public static List allValuesMatching(final ModuleRepository repository, String pattern) { final Pattern compiledPattern = pattern == null ? null diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/runtime/ExpressionClassLoader.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/runtime/ExpressionClassLoader.java index bb2e5efc0..c91daab91 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/runtime/ExpressionClassLoader.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/runtime/ExpressionClassLoader.java @@ -1,11 +1,11 @@ package org.simantics.scl.compiler.runtime; -import gnu.trove.map.hash.THashMap; - import java.util.Map; import org.simantics.scl.compiler.constants.Constant; +import gnu.trove.map.hash.THashMap; + public class ExpressionClassLoader extends ClassLoader implements MutableClassLoader { public static final boolean VALIDATE_CLASS_NAMES = true; public static final boolean TRACE_CLASS_CREATION = false; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/runtime/MutableClassLoader.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/runtime/MutableClassLoader.java index 8fd9a7a0b..adf36f8af 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/runtime/MutableClassLoader.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/runtime/MutableClassLoader.java @@ -1,11 +1,11 @@ package org.simantics.scl.compiler.runtime; -import gnu.trove.map.hash.THashMap; - import java.util.Map; import org.simantics.scl.compiler.constants.Constant; +import gnu.trove.map.hash.THashMap; + public interface MutableClassLoader { public static final String SCL_PACKAGE_PREFIX = "scl."; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/runtime/RuntimeEnvironmentImpl.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/runtime/RuntimeEnvironmentImpl.java index cbac0c85a..8d7080394 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/runtime/RuntimeEnvironmentImpl.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/runtime/RuntimeEnvironmentImpl.java @@ -1,9 +1,9 @@ package org.simantics.scl.compiler.runtime; -import gnu.trove.map.hash.THashMap; - import org.simantics.scl.compiler.environment.Environment; +import gnu.trove.map.hash.THashMap; + public class RuntimeEnvironmentImpl implements RuntimeEnvironment { private final Environment environment; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/runtime/RuntimeModuleMap.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/runtime/RuntimeModuleMap.java index d1d897174..80db43ef0 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/runtime/RuntimeModuleMap.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/runtime/RuntimeModuleMap.java @@ -1,9 +1,9 @@ package org.simantics.scl.compiler.runtime; -import gnu.trove.map.hash.THashMap; - import java.util.Collection; +import gnu.trove.map.hash.THashMap; + public class RuntimeModuleMap { THashMap moduleMap = new THashMap(); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/ClassModuleSource.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/ClassModuleSource.java index efdc63000..1316ee5d7 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/ClassModuleSource.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/ClassModuleSource.java @@ -2,7 +2,6 @@ package org.simantics.scl.compiler.source; import java.io.IOException; import java.io.InputStream; -import java.nio.charset.Charset; import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidator; import org.simantics.scl.compiler.internal.codegen.types.RuntimeJavaReferenceValidator; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/ClassModuleSourceRepository.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/ClassModuleSourceRepository.java index 310472cdc..873859a2d 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/ClassModuleSourceRepository.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/ClassModuleSourceRepository.java @@ -1,8 +1,5 @@ package org.simantics.scl.compiler.source.repository; -import gnu.trove.procedure.TObjectProcedure; -import gnu.trove.set.hash.THashSet; - import java.io.IOException; import java.net.URL; @@ -11,6 +8,9 @@ import org.simantics.scl.compiler.module.repository.UpdateListener; import org.simantics.scl.compiler.source.ClassModuleSource; import org.simantics.scl.compiler.source.ModuleSource; +import gnu.trove.procedure.TObjectProcedure; +import gnu.trove.set.hash.THashSet; + public class ClassModuleSourceRepository extends AbstractModuleSourceRepository { private final Class clazz; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/CompositeModuleSourceRepository.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/CompositeModuleSourceRepository.java index ce3f775ce..82bb0bcf9 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/CompositeModuleSourceRepository.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/CompositeModuleSourceRepository.java @@ -1,10 +1,10 @@ package org.simantics.scl.compiler.source.repository; -import gnu.trove.procedure.TObjectProcedure; - import org.simantics.scl.compiler.module.repository.UpdateListener; import org.simantics.scl.compiler.source.ModuleSource; +import gnu.trove.procedure.TObjectProcedure; + public class CompositeModuleSourceRepository implements ModuleSourceRepository { public final ModuleSourceRepository[] children; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/FileModuleSourceRepository.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/FileModuleSourceRepository.java index 5a4e93ce5..805dd77f4 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/FileModuleSourceRepository.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/FileModuleSourceRepository.java @@ -1,8 +1,5 @@ package org.simantics.scl.compiler.source.repository; -import gnu.trove.procedure.TObjectProcedure; -import gnu.trove.set.hash.THashSet; - import java.io.File; import java.io.IOException; @@ -12,6 +9,9 @@ import org.simantics.scl.compiler.source.ClassModuleSource; import org.simantics.scl.compiler.source.FileModuleSource; import org.simantics.scl.compiler.source.ModuleSource; +import gnu.trove.procedure.TObjectProcedure; +import gnu.trove.set.hash.THashSet; + public class FileModuleSourceRepository extends AbstractModuleSourceRepository { private final File path; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/MapModuleSourceRepository.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/MapModuleSourceRepository.java index 6cbf03aef..9872451c3 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/MapModuleSourceRepository.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/MapModuleSourceRepository.java @@ -1,13 +1,13 @@ package org.simantics.scl.compiler.source.repository; -import gnu.trove.map.hash.THashMap; -import gnu.trove.procedure.TObjectProcedure; - import org.simantics.scl.compiler.module.Module; import org.simantics.scl.compiler.module.repository.UpdateListener; import org.simantics.scl.compiler.source.ModuleSource; import org.simantics.scl.compiler.source.PrecompiledModuleSource; +import gnu.trove.map.hash.THashMap; +import gnu.trove.procedure.TObjectProcedure; + /** * An implementation of {@link ModuleSourceRepository} as a finite map. * This implementation does not support listening module changes, diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/ModuleSourceRepository.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/ModuleSourceRepository.java index 71e08dcd6..76698f5be 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/ModuleSourceRepository.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/ModuleSourceRepository.java @@ -1,11 +1,11 @@ package org.simantics.scl.compiler.source.repository; -import gnu.trove.procedure.TObjectProcedure; - import org.simantics.scl.compiler.module.repository.ModuleRepository; import org.simantics.scl.compiler.module.repository.UpdateListener; import org.simantics.scl.compiler.source.ModuleSource; +import gnu.trove.procedure.TObjectProcedure; + /** * An interface for locating modules descriptors and listening if they change. * An instance of this interface is used to create a {@link ModuleRepository}. diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/ExpressionEvaluator.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/ExpressionEvaluator.java index 6cb68b673..5c8f59bb2 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/ExpressionEvaluator.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/ExpressionEvaluator.java @@ -1,7 +1,5 @@ package org.simantics.scl.compiler.top; -import gnu.trove.set.hash.THashSet; - import java.io.StringReader; import java.lang.reflect.Method; import java.util.ArrayList; @@ -59,6 +57,8 @@ import org.simantics.scl.compiler.types.util.ProcedureType; import org.simantics.scl.runtime.function.FunctionImpl1; import org.simantics.scl.runtime.tuple.Tuple0; +import gnu.trove.set.hash.THashSet; + public class ExpressionEvaluator { public static final boolean TRACE_INTERPRETATION_VS_COMPILATION = false; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/ExpressionInterpretationContext.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/ExpressionInterpretationContext.java index e80883969..8b788c2ff 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/ExpressionInterpretationContext.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/ExpressionInterpretationContext.java @@ -1,13 +1,13 @@ package org.simantics.scl.compiler.top; -import gnu.trove.impl.Constants; -import gnu.trove.map.hash.TObjectIntHashMap; - import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.elaboration.expressions.Variable; import org.simantics.scl.compiler.internal.codegen.utils.TransientClassBuilder; import org.simantics.scl.compiler.runtime.RuntimeEnvironment; +import gnu.trove.impl.Constants; +import gnu.trove.map.hash.TObjectIntHashMap; + public class ExpressionInterpretationContext { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/SCLCompilerConfiguration.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/SCLCompilerConfiguration.java index 799a1495a..d7b896a98 100755 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/SCLCompilerConfiguration.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/SCLCompilerConfiguration.java @@ -33,4 +33,6 @@ public interface SCLCompilerConfiguration { public static final boolean EVERY_RULE_ENFORCEMENT_IN_SEPARATE_METHOD = true; public static final boolean EVERY_DATALOG_STRATUM_IN_SEPARATE_METHOD = true; + public static final boolean ALLOW_OVERLOADING = false; + } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/Skeletons.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/Skeletons.java new file mode 100644 index 000000000..81dec2403 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/Skeletons.java @@ -0,0 +1,292 @@ +package org.simantics.scl.compiler.types; + +import org.simantics.scl.compiler.environment.Environment; +import org.simantics.scl.compiler.internal.types.HashCodeUtils; +import org.simantics.scl.compiler.types.exceptions.KindUnificationException; +import org.simantics.scl.compiler.types.exceptions.UnificationException; +import org.simantics.scl.compiler.types.kinds.Kinds; + +import gnu.trove.map.hash.THashMap; + +public class Skeletons { + + public static Type canonicalSkeleton(Type type) { + while(type instanceof TMetaVar) { + TMetaVar metaVar = (TMetaVar)type; + if(metaVar.ref != null) + type = metaVar.ref; + else if(metaVar.skeletonRef != null) + type = metaVar.skeletonRef; + else + return metaVar; + } + return type; + } + + public static Type canonicalSkeleton(THashMap unifications, Type type) { + while(type instanceof TMetaVar) { + TMetaVar metaVar = (TMetaVar)type; + if(metaVar.ref != null) + type = metaVar.ref; + else if(metaVar.skeletonRef != null) + type = metaVar.skeletonRef; + else { + Type temp = unifications.get(metaVar); + if(temp == null) + return metaVar; + else + type = temp; + } + } + return type; + } + + public static boolean doesSkeletonContain(THashMap unifications, Type type, TMetaVar metaVar) { + type = canonicalSkeleton(unifications, type); + if(type == metaVar) + return true; + if(type instanceof TFun) { + TFun fun = (TFun)type; + return doesSkeletonContain(unifications, fun.domain, metaVar) + || doesSkeletonContain(unifications, fun.range, metaVar); + } + if(type instanceof TApply) { + TApply apply = (TApply)type; + return doesSkeletonContain(unifications, apply.function, metaVar) + || doesSkeletonContain(unifications, apply.parameter, metaVar); + } + if(type instanceof TForAll) { + TForAll forAll = (TForAll)type; + return doesSkeletonContain(unifications, forAll.type, metaVar); + } + if(type instanceof TPred) { + TPred pred = (TPred)type; + for(Type param : pred.parameters) + if(doesSkeletonContain(unifications, param, metaVar)) + return true; + return false; + } + else + return false; + } + + /** + * Returns true, if unification of the skeletons of the types would succeed. + */ + public static boolean areSkeletonsCompatible(THashMap unifications, Type a, Type b) { + a = canonicalSkeleton(unifications, a); + b = canonicalSkeleton(unifications, b); + if(a == b) + return true; + Class ca = a.getClass(); + Class cb = b.getClass(); + + if(ca == TMetaVar.class) { + TMetaVar ma = (TMetaVar)a; + if(doesSkeletonContain(unifications, b, ma)) + return false; + unifications.put(ma, b); + return true; + } + if(cb == TMetaVar.class) { + TMetaVar mb = (TMetaVar)b; + if(doesSkeletonContain(unifications, a, mb)) + return false; + unifications.put(mb, a); + return true; + } + if(ca != cb) + return false; + if(ca == TFun.class) { + TFun funA = (TFun)a; + TFun funB = (TFun)b; + return areSkeletonsCompatible(unifications, funA.domain, funB.domain) + && areSkeletonsCompatible(unifications, funA.range, funB.range); + } + if(ca == TApply.class) { + TApply applyA = (TApply)a; + TApply applyB = (TApply)b; + return areSkeletonsCompatible(unifications, applyA.function, applyB.function) + && areSkeletonsCompatible(unifications, applyA.parameter, applyB.parameter); + } + if(ca == TPred.class) { + TPred predA = (TPred)a; + TPred predB = (TPred)b; + if(predA.typeClass != predB.typeClass) + return false; + for(int i=0;i ca = a.getClass(); + Class cb = b.getClass(); + if(ca != cb) { + throw new UnificationException(a, b); + } + if(ca == TApply.class) + //unifySkeletons((TApply)a, (TApply)b); + Types.unify(a, b); + else if(ca == TFun.class) + unifySkeletons((TFun)a, (TFun)b); + else if(ca == TForAll.class) + unifySkeletons((TForAll)a, (TForAll)b); + else if(ca == TPred.class) + //unifySkeletons((TPred)a, (TPred)b); + Types.unify(a, b); + else if(ca == TUnion.class) + unifySkeletons((TUnion)a, (TUnion)b); + else // ca == TCon.class || ca = TVar.class + throw new UnificationException(a, b); + } + + public static void unifySkeletons(TFun a, TFun b) throws UnificationException { + unifySkeletons(a.domain, b.domain); + unifySkeletons(a.range, b.range); + } + + public static void unifySkeletons(TApply a, TApply b) throws UnificationException { + unifySkeletons(a.function, b.function); + unifySkeletons(a.parameter, b.parameter); + } + + public static void unifySkeletons(TForAll a, TForAll b) throws UnificationException { + try { + Kinds.unify(a.var.getKind(), b.var.getKind()); + } catch (KindUnificationException e) { + throw new UnificationException(a, b); + } + TVar newVar = Types.var(a.var.getKind()); + unifySkeletons(a.type.replace(a.var, newVar), b.type.replace(b.var, newVar)); + } + + public static void unifySkeletons(TPred a, TPred b) throws UnificationException { + if(a.typeClass != b.typeClass + || a.parameters.length != b.parameters.length) + throw new UnificationException(a, b); + for(int i=0;i metaVarMap = new THashMap() { + @Override + protected boolean equals(Object a, Object b) { + return Types.equals((Type[])a, (Type[])b); + } + @Override + protected int hash(Object a) { + Type[] types = (Type[])a; + int hash = HashCodeUtils.SEED; + for(Type type : types) + hash = type.hashCode(hash); + return hash; + } + }; + return commonSkeleton(context, metaVarMap, types); + } + + private static TMetaVar metaVarFor(Environment context, THashMap metaVarMap, Type[] types) { + TMetaVar result = metaVarMap.get(types); + if(result == null) { + try { + result = Types.metaVar(types[0].inferKind(context)); + } catch (KindUnificationException e) { + result = Types.metaVar(Kinds.STAR); + } + metaVarMap.put(types, result); + } + return result; + } + + /** + * Finds the most specific type that can be unified with the all the types + * given as a parameter. + */ + private static Type commonSkeleton(Environment context, THashMap metaVarMap, Type[] types) { + for(int i=0;i clazz = first.getClass(); + for(int i=1;i metaVarMap) { return this; } + + @Override + public int hashCode(int hash) { + return HashCodeUtils.update(hash, System.identityHashCode(this)); + } + + @Override + public int hashCode(int hash, TVar[] boundVars) { + return HashCodeUtils.update(hash, System.identityHashCode(this)); + } + + @Override + public boolean equalsCanonical(Type other) { + return this == other; + } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TForAll.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TForAll.java index a22a4b244..98b4578af 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TForAll.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TForAll.java @@ -1,12 +1,10 @@ package org.simantics.scl.compiler.types; -import gnu.trove.map.hash.THashMap; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; - import java.util.ArrayList; +import java.util.Arrays; import org.simantics.scl.compiler.environment.Environment; +import org.simantics.scl.compiler.internal.types.HashCodeUtils; import org.simantics.scl.compiler.internal.types.TypeHashCodeContext; import org.simantics.scl.compiler.internal.types.ast.TForAllAst; import org.simantics.scl.compiler.internal.types.ast.TypeAst; @@ -16,10 +14,14 @@ import org.simantics.scl.compiler.types.kinds.Kinds; import org.simantics.scl.compiler.types.util.Polarity; import org.simantics.scl.compiler.types.util.TypeUnparsingContext; +import gnu.trove.map.hash.THashMap; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; + public class TForAll extends Type { public final TVar var; - public final Type type; + public Type type; TForAll(TVar var, Type type) { if(NULL_CHECKS) { @@ -150,4 +152,76 @@ public class TForAll extends Type { // Should never get here return new TMetaVar(Kinds.STAR); } + + @Override + public int hashCode(int hash) { + int count=1; + { + Type t = Types.canonical(type); + while(t instanceof TForAll) { + t = Types.canonical( ((TForAll)t).type ); + ++count; + } + } + TVar[] boundVars = new TVar[count]; + boundVars[0] = var; + TForAll t = this; + { + for(int i=1;i " + type); + if(ref != null) + throw new InternalCompilerError("Method setRef should be called only for unbound meta variables."); + if(type.contains(this)) + throw new UnificationException(this, type); + ref = type; if(polarity != Polarity.NO_POLARITY) - a.addPolarity(polarity); + type.addPolarity(polarity); + if(skeletonRef != null) { + Type skeleton = skeletonRef; + skeletonRef = null; + Skeletons.unifySkeletons(skeleton, type); + } + fireNotifyAboutChange(); } public Type getRef() { @@ -130,10 +165,12 @@ public class TMetaVar extends Type { @Override public boolean contains(TMetaVar other) { - if(ref == null) - return this == other; - else + if(ref != null) return ref.contains(other); + else if(skeletonRef != null) + return skeletonRef.contains(other); + else + return this == other; } @Override @@ -231,4 +268,79 @@ public class TMetaVar extends Type { return result; } } + + public void setSkeletonRef(Type type) throws UnificationException { + if(DEBUG) + System.out.println("setSkeletonRef " + System.identityHashCode(this) + " -> " + type); + if(ref != null || skeletonRef != null) + throw new InternalCompilerError("Method setRef should be called only for unbound meta variables."); + if(type.contains(this)) + throw new UnificationException(this, type); + this.skeletonRef = type; + fireNotifyAboutChange(); + } + + @Override + public int hashCode(int hash) { + if(ref == null) + return HashCodeUtils.update(hash, System.identityHashCode(this)); + else + return ref.hashCode(hash); + } + + @Override + public int hashCode(int hash, TVar[] boundVars) { + if(ref == null) + return HashCodeUtils.update(hash, System.identityHashCode(this)); + else + return ref.hashCode(hash, boundVars); + } + + @Override + public boolean equalsCanonical(Type other) { + return this == other; + } + + @Override + public Type canonical() { + if(ref == null) + return this; + else + return ref = ref.canonical(); + } + + public void addListener(TMetaVarListener newListener) { + if(DEBUG) + System.out.println("addListener " + System.identityHashCode(this)); + newListener.next = listener; + newListener.prev = this; + if(listener != null) + listener.prev = newListener; + listener = newListener; + } + + private void fireNotifyAboutChange() { + if(DEBUG) + System.out.println("fireNotifyAboutChange " + System.identityHashCode(this) + " " + ref); + TMetaVarListener cur = listener; + listener = null; + while(cur != null) { + if(DEBUG) + System.out.println(" call listener"); + cur.prev = null; // This prevents TMetaVarListener.remove from doing anything + cur.notifyAboutChange(); + TMetaVarListener next = cur.next; + cur.next = null; + cur = next; + } + } + + public TMetaVarListener getLatestListener() { + return listener; + } + + @Override + public Kind getKind(Environment context) { + return kind; + } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TPred.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TPred.java index d9fd79f91..e8a0469c5 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TPred.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TPred.java @@ -1,11 +1,9 @@ package org.simantics.scl.compiler.types; -import gnu.trove.map.hash.THashMap; -import gnu.trove.set.hash.THashSet; - import java.util.ArrayList; import org.simantics.scl.compiler.environment.Environment; +import org.simantics.scl.compiler.internal.types.HashCodeUtils; import org.simantics.scl.compiler.internal.types.TypeHashCodeContext; import org.simantics.scl.compiler.internal.types.ast.TApplyAst; import org.simantics.scl.compiler.internal.types.ast.TypeAst; @@ -15,6 +13,9 @@ import org.simantics.scl.compiler.types.kinds.Kinds; import org.simantics.scl.compiler.types.util.Polarity; import org.simantics.scl.compiler.types.util.TypeUnparsingContext; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; + public class TPred extends Type { @@ -172,4 +173,42 @@ public class TPred extends Type { newParameters[i] = parameters[i].copySkeleton(metaVarMap); return new TPred(typeClass, parameters); } + + @Override + public int hashCode(int hash) { + hash = HashCodeUtils.updateWithPreprocessedValue(hash, PRED_HASH); + hash = typeClass.hashCode(hash); + for(Type parameter : parameters) + hash = parameter.hashCode(hash); + return hash; + } + + @Override + public int hashCode(int hash, TVar[] boundVars) { + hash = HashCodeUtils.updateWithPreprocessedValue(hash, PRED_HASH); + hash = typeClass.hashCode(hash, boundVars); + for(Type parameter : parameters) + hash = parameter.hashCode(hash, boundVars); + return hash; + } + + @Override + public boolean equalsCanonical(Type other) { + if(this == other) + return true; + if(!other.getClass().equals(TPred.class)) + return false; + TPred pred = (TPred)other; + if(typeClass != pred.typeClass || parameters.length != pred.parameters.length) + return false; + for(int i=0;i metaVarMap) { return Types.NO_EFFECTS; } + + @Override + public int hashCode(int hash) { + int sum = UNION_HASH; + for(Type effect : effects) + sum += effect.hashCode(HashCodeUtils.SEED); + return HashCodeUtils.updateWithPreprocessedValue(hash, sum); + } + + @Override + public int hashCode(int hash, TVar[] boundVars) { + int sum = UNION_HASH; + for(Type effect : effects) + sum += effect.hashCode(HashCodeUtils.SEED, boundVars); + return HashCodeUtils.updateWithPreprocessedValue(hash, sum); + } + + @Override + public boolean equalsCanonical(Type other) { + if(this == other) + return true; + if(!other.getClass().equals(TUnion.class)) + return false; + TUnion union = (TUnion)other; + int length = effects.length; + if(length != union.effects.length) + return false; + if(length == 0) + return true; + for(int i=0;i i) { + effect = union.effects[i]; + union.effects[i] = union.effects[j]; + union.effects[j] = effect; + } + continue loop; + } + return false; + } + return true; + } + + @Override + public Kind getKind(Environment context) { + return Kinds.EFFECT; + } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TVar.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TVar.java index 1fca6c59a..aeb971145 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TVar.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TVar.java @@ -1,12 +1,9 @@ package org.simantics.scl.compiler.types; -import gnu.trove.map.hash.THashMap; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; - import java.util.ArrayList; import org.simantics.scl.compiler.environment.Environment; +import org.simantics.scl.compiler.internal.types.HashCodeUtils; import org.simantics.scl.compiler.internal.types.TypeHashCodeContext; import org.simantics.scl.compiler.internal.types.ast.TVarAst; import org.simantics.scl.compiler.internal.types.ast.TypeAst; @@ -17,8 +14,12 @@ import org.simantics.scl.compiler.types.kinds.Kinds; import org.simantics.scl.compiler.types.util.Polarity; import org.simantics.scl.compiler.types.util.TypeUnparsingContext; +import gnu.trove.map.hash.THashMap; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; + -public class TVar extends Type { +public final class TVar extends Type { public static final TVar[] EMPTY_ARRAY = new TVar[0]; private Kind kind; @@ -139,4 +140,29 @@ public class TVar extends Type { public Type copySkeleton(THashMap metaVarMap) { return this; } + + @Override + public int hashCode(int hash) { + return HashCodeUtils.update(hash, System.identityHashCode(this)); + } + + @Override + public int hashCode(int hash, TVar[] boundVars) { + for(int i=0;i vars); @@ -160,5 +166,13 @@ public abstract class Type { * Creates an independent copy of the type, but replaces all effects by metavars */ public abstract Type copySkeleton(THashMap metaVarMap); + + public abstract boolean equalsCanonical(Type other); + + public Type canonical() { + return this; + } + + public abstract Kind getKind(Environment context); } \ No newline at end of file diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/Types.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/Types.java index a706e2b8f..f0c9dbddf 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/Types.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/Types.java @@ -147,29 +147,9 @@ public class Types { function = apply(function, parameter); return function; } - - /** - * Get the concrete type or alias type pointed to by a chain of type meta-variables, - * or the last metavariable in the link, if it is not linked to an actual type. - * Unlike {@link #canonical(Type)}, this method does not resolve type aliases. - */ - public static Type weakCanonical(Type type) { - while(true) { - if(type instanceof TMetaVar) { - TMetaVar metaVar = (TMetaVar)type; - if(metaVar.ref == null) - return type; - else - type = metaVar.ref; - } - else - return type; - } - } /** - * Get the concrete type pointed to by a chain of type meta-variables. Unlike {@link #weakCanonical(Type)} - * this method also resolves type aliases. + * Get the concrete type pointed to by a chain of type meta-variables. */ public static Type canonical(Type type) { while(type instanceof TMetaVar) { @@ -795,8 +775,8 @@ public class Types { } public static void unify(Type a, Type b) throws UnificationException { - a = weakCanonical(a); - b = weakCanonical(b); + a = canonical(a); + b = canonical(b); if(a == b) return; if(a instanceof TMetaVar) { @@ -1137,4 +1117,30 @@ public class Types { e.getMessage())); } } + + public static Type instantiateAndStrip(Type type) { + while(true) { + if(type instanceof TForAll) { + TForAll forAll = (TForAll)type; + type = forAll.type.replace(forAll.var, metaVar(forAll.var.getKind())); + } + else if(type instanceof TFun) { + TFun fun = (TFun)type; + if(fun.domain instanceof TPred || fun.domain == Types.PUNIT) + type = fun.range; + else + return type; + } + else if(type instanceof TMetaVar) { + TMetaVar metaVar = (TMetaVar)type; + if(metaVar.ref == null) + return type; + else + type = metaVar.ref; + } + else + return type; + } + } + } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/kinds/Kinds.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/kinds/Kinds.java index edf63df74..4707110f8 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/kinds/Kinds.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/kinds/Kinds.java @@ -1,5 +1,6 @@ package org.simantics.scl.compiler.types.kinds; +import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.types.exceptions.KindUnificationException; public class Kinds { @@ -77,5 +78,24 @@ public class Kinds { public static boolean equals(Kind a, Kind b) { return equalsCanonical(canonical(a), canonical(b)); + } + + public static Kind rangeOfArrow(Kind kind) { + kind = canonical(kind); + if(kind instanceof KArrow) + return ((KArrow)kind).range; + else if(kind instanceof KMetaVar) { + Kind domain = Kinds.metaVar(); + Kind range = Kinds.metaVar(); + try { + ((KMetaVar)kind).setRef(arrow(domain, range)); + } catch (KindUnificationException e) { + // Should not fail because kind is canonical + e.printStackTrace(); + } + return range; + } + else + throw new InternalCompilerError("Assumed arrow kind but encountered " + kind + "."); } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/util/TypeListener.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/util/TypeListener.java new file mode 100644 index 000000000..04c9e169e --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/util/TypeListener.java @@ -0,0 +1,63 @@ +package org.simantics.scl.compiler.types.util; + +import java.util.ArrayList; + +import org.simantics.scl.compiler.types.Skeletons; +import org.simantics.scl.compiler.types.TApply; +import org.simantics.scl.compiler.types.TForAll; +import org.simantics.scl.compiler.types.TFun; +import org.simantics.scl.compiler.types.TMetaVar; +import org.simantics.scl.compiler.types.TMetaVar.TMetaVarListener; +import org.simantics.scl.compiler.types.TPred; +import org.simantics.scl.compiler.types.Type; + +public abstract class TypeListener { + private ArrayList metaVarListeners = new ArrayList(2); + public abstract void notifyAboutChange(); + + private static class SubListener extends TMetaVarListener { + private final TypeListener parent; + public SubListener(TypeListener parent) { + this.parent = parent; + } @Override + public void notifyAboutChange() { + for(TMetaVarListener otherListeners : parent.metaVarListeners) + otherListeners.remove(); + parent.notifyAboutChange(); + } + }; + + public void listenSkeleton(Type type) { + type = Skeletons.canonicalSkeleton(type); + if(type instanceof TMetaVar) { + TMetaVar metaVar = (TMetaVar)type; + TMetaVarListener latestListener = metaVar.getLatestListener(); + if(latestListener instanceof SubListener && + ((SubListener)latestListener).parent == this) + return; + + SubListener subListener = new SubListener(this); + metaVarListeners.add(subListener); + metaVar.addListener(subListener); + } + else if(type instanceof TApply) { + TApply apply = (TApply)type; + listenSkeleton(apply.function); + listenSkeleton(apply.parameter); + } + else if(type instanceof TFun) { + TFun fun = (TFun)type; + listenSkeleton(fun.domain); + listenSkeleton(fun.range); + } + else if(type instanceof TForAll) { + TForAll forAll = (TForAll)type; + listenSkeleton(forAll.type); + } + else if(type instanceof TPred) { + TPred pred = (TPred)type; + for(Type parameter : pred.parameters) + listenSkeleton(parameter); + } + } +} diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/util/TypeTree.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/util/TypeTree.java new file mode 100644 index 000000000..b41dba8cf --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/util/TypeTree.java @@ -0,0 +1,70 @@ +package org.simantics.scl.compiler.types.util; + +import org.simantics.scl.compiler.types.Skeletons; +import org.simantics.scl.compiler.types.TMetaVar; +import org.simantics.scl.compiler.types.Type; + +public class TypeTree { + + public static class Case { + public Type[] types; + public T result; + } + + private static class Node { + Case[] cases; + Branch[] branches; + + public Node(Case[] cases) { + this.cases = cases; + this.branches = new Branch[cases[0].types.length]; + } + + Branch getBranch(int i) { + // TODO + return null; + } + } + + private static class Branch { + + public void improve(Iterator iterator) { + // TODO Auto-generated method stub + + } + + } + + public static class Iterator { + Node node; + Type[] scrutinee; + + public Iterator(Node node, Type[] scrutinee) { + this.node = node; + this.scrutinee = scrutinee; + } + + public void improve() { + for(int i=0;i branch = node.getBranch(i); + if(branch != null) { + branch.improve(this); + --i; + } + } + } + } + } + + Node root; + + public TypeTree(Case[] cases) { + this.root = new Node(cases); + } + + public Iterator iterator(Type ... scrutinee) { + return new Iterator(root, scrutinee); + } +} diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/ActiveTests.java b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/ActiveTests.java index b80577e53..0b7b52e29 100644 --- a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/ActiveTests.java +++ b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/ActiveTests.java @@ -8,15 +8,12 @@ public class ActiveTests extends TestBase { public ActiveTests() { super("scl"); } @Test public void Equations1() { test(); } - @Test public void Equality() { test(); } - @Test public void ModuleInitialization() { test(); } - - @Test public void ImportJavaConstructor() { test(); } - @Test public void MarketModel() { test(); } @Test public void MarketModel2() { test(); } - @Ignore + @Test public void Overloading2() { test(); } + @Test public void Overloading3() { test(); } + //@Ignore @Test public void PatternError() { test(); } - @Test public void TypeAliasRefsToTypeAlias() { test(); } + @Test public void Serialization() { test(); } @Ignore @Test public void TypeClass2() { test(); } @Test public void TypeClassBug2() { test(); } diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/FindAllowedChars.java b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/FindAllowedChars.java new file mode 100644 index 000000000..1e4078670 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/FindAllowedChars.java @@ -0,0 +1,66 @@ +package org.simantics.scl.compiler.tests; + +import java.lang.reflect.Method; + +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +public class FindAllowedChars { + public static class MyClassLoader extends ClassLoader { + final String className; + final byte[] classBytes; + + public MyClassLoader(ClassLoader parent, String className, byte[] classBytes) { + super(parent); + this.className = className; + this.classBytes = classBytes; + } + + public MyClassLoader(String className, byte[] classBytes) { + this.className = className; + this.classBytes = classBytes; + } + + @Override + protected Class findClass(String name) throws ClassNotFoundException { + if(name.equals(name)) + return defineClass(name, classBytes, 0, classBytes.length); + else + return super.findClass(name); + } + } + + public static void test(String className, String methodName) throws Exception { + ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS); + classWriter.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, className, null, "java/lang/Object", null); + + MethodVisitor methodVisitor = classWriter.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, methodName, "()V", null, null); + /*methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); + methodVisitor.visitLdcInsn("Hello world!"); + methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);*/ + methodVisitor.visitInsn(Opcodes.RETURN); + methodVisitor.visitMaxs(0, 0); + methodVisitor.visitEnd(); + classWriter.visitEnd(); + + ClassLoader loader = new MyClassLoader(className, classWriter.toByteArray()); + Class clazz = loader.loadClass(className); + Method method = clazz.getMethod(methodName); + method.invoke(null); + } + + public static void main(String[] args) throws Exception { + for(int a=Character.MIN_VALUE;a maybeModule = PRELUDE_MODULE_REPOSITORY.getModule("Prelude"); + if(!maybeModule.didSucceed()) + return; + Module module = maybeModule.getResult(); + ModuleCoverage coverage = CoverageUtils.getCoverage(module); + if(coverage == null) + return; + coverage.print(System.out); + printCoverageTree(module.getBranchPoints().get("lookup"), 0); + } + + private static void printCoverageTree(BranchPoint[] branchPoints, int ind) { + for(BranchPoint bp : branchPoints) { + for(int i=0;i auxModuleNameList = new ArrayList(); + while(j < testParts.length) { + String part = testParts[j]; + if(part.startsWith("// module ")) + auxModuleNameList.add(part.substring(10).split("\\n", 2)[0].trim()); + else + break; + ++j; + } + int mainId = j; + String[] moduleNames = new String[mainId+1]; + String[] moduleTexts = new String[mainId+1]; + for(int i=0;i result = testEnvironment.getModule(testModuleName); + new MapModuleSourceRepository(moduleSources)); + int lastId = moduleNames.length-1; + Failable result = testEnvironment.getModule(moduleNames[lastId]); if(!result.didSucceed()) - return ((Failure)result).toString(input); + return ((Failure)result).toString(moduleTexts[lastId]); else { - Object main = testEnvironment.getRuntimeModule(testModuleName).getResult().getValue("main"); + Object main = testEnvironment.getRuntimeModule(moduleNames[lastId]).getResult().getValue("main"); return String.valueOf(main); } } @@ -97,9 +128,11 @@ public class TestBase { } String text = new String(buffer, 0, pos, UTF8); String[] result = TEST_SEPARATOR.split(text); - if(result.length % 2 == 1) { - result = Arrays.copyOf(result, result.length+2); - result[result.length-1] = ""; + for(int i=1;i 0 + then 1 + else "asd" + +bar n = n + where + do + c = n+1 + if c > 0 + then 1 + else "asd" + +main = foo 3 + bar 3 +-- +6 \ No newline at end of file diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Formula.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Formula.scl new file mode 100644 index 000000000..10eafb061 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Formula.scl @@ -0,0 +1,131 @@ +import "Prelude" + +data Formula a = TrueF + | FalseF + | XorF (Formula a) (Formula a) + | AndF (Formula a) (Formula a) + | ConditionF a + | NextF (Formula a) + | UntilF (Formula a) (Formula a) + +deriving instance (Ord a) => Ord (Formula a) + +instance (Show a) => Show (Formula a) where + sb <+ TrueF = sb << "true" + sb <+ FalseF = sb << "false" + sb <+ XorF a b = sb << "(" <+ a << " `XorF` " <+ b << ")" + sb <+ AndF a b = sb << "(" <+ a << " &&& " <+ b << ")" + sb <+ ConditionF c = sb <+ c + sb <+ NextF a = sb << "(next " <+ a << ")" + sb <+ UntilF a b = sb << "(" <+ a << " `UntilF` " <+ b << ")" + +xorF FalseF f2 = f2 +xorF f1 FalseF = f1 +xorF f1@(XorF h1 t1) f2@(XorF h2 t2) = + let cmp = compare h1 h2 + in if cmp < 0 + then XorF h1 (xorF t1 f2) + else if cmp > 0 + then XorF h2 (xorF f1 t2) + else xorF t1 t2 +xorF f1@(XorF h1 t1) f2 = + let cmp = compare h1 f2 + in if cmp < 0 + then XorF h1 (xorF t1 f2) + else if cmp > 0 + then XorF f2 f1 + else t1 +xorF f1 f2@(XorF h2 t2) = + let cmp = compare f1 h2 + in if cmp < 0 + then XorF f1 f2 + else if cmp > 0 + then XorF h2 (xorF f1 t2) + else t2 +xorF f1 f2 = + let cmp = compare f1 f2 + in if cmp < 0 + then XorF f1 f2 + else if cmp > 0 + then XorF f2 f1 + else TrueF + +notF f = xorF TrueF f + +TrueF &&& f2 = f2 +f1 &&& TrueF = f1 +FalseF &&& _ = FalseF +_ &&& FalseF = FalseF +XorF h1 t1 &&& f2 = xorF (h1 &&& f2) (t1 &&& f2) +f1 &&& XorF h2 t2 = xorF (f1 &&& h2) (f1 &&& t2) +f1@(AndF h1 t1) &&& f2@(AndF h2 t2) = + let cmp = compare h1 h2 + in if cmp < 0 + then AndF h1 (t1 &&& f2) + else if cmp > 0 + then AndF h2 (f1 &&& t2) + else AndF h1 (t1 &&& t2) +f1@(AndF h1 t1) &&& f2 = + let cmp = compare h1 f2 + in if cmp < 0 + then AndF h1 (t1 &&& f2) + else if cmp > 0 + then AndF f2 f1 + else f1 +f1 &&& f2@(AndF h2 t2) = + let cmp = compare f1 h2 + in if cmp < 0 + then AndF f1 f2 + else if cmp > 0 + then AndF h2 (f1 &&& t2) + else f2 +f1 &&& f2 = + let cmp = compare f1 f2 + in if cmp < 0 + then AndF f1 f2 + else if cmp > 0 + then AndF f2 f1 + else f1 + +f1 ||| f2 = xorF (xorF f1 f2) (f1 &&& f2) + +eval :: Ord a => (a -> Boolean) -> Formula a -> Formula a +eval s TrueF = TrueF +eval s FalseF = FalseF +eval s (XorF f1 f2) = xorF (eval s f1) (eval s f2) +eval s (AndF f1 f2) = eval s f1 &&& eval s f2 +eval s (ConditionF c) = if s c then TrueF else FalseF +eval s (NextF f) = f +eval s (UntilF f1 f2) = eval s f2 ||| (eval s f1 &&& UntilF f1 f2) + +// Concrete conditions + +data V = V String (Ref Boolean) + +instance Ord V where + compare (V a _) (V b _) = compare a b +instance Show V where + sb <+ V a _ = sb <+ a + +cond :: String -> Ref Boolean -> Formula V +cond name ref = ConditionF (V name ref) + +// Testing + +x = ref True +y = ref False + +f = cond "x" x `UntilF` cond "y" y + +evalV = eval (\(V _ c) -> getRef c) + +main = do + print (evalV f) + x := False + print (evalV f) + y = ref True + print (evalV f) + x := True + print (evalV f) +-- +() \ No newline at end of file diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Hashable1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Hashable1.scl deleted file mode 100644 index dc72fb05c..000000000 --- a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Hashable1.scl +++ /dev/null @@ -1,7 +0,0 @@ -import "Prelude" - -l :: [Integer] -l = [1,2,3,4,5] -main = hash l - foldl (\c x -> 31*c + x) 0 l --- --1625180697 \ No newline at end of file diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Hashable2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Hashable2.scl deleted file mode 100644 index ce3c5b72f..000000000 --- a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Hashable2.scl +++ /dev/null @@ -1,7 +0,0 @@ -import "Prelude" - -l :: [Double] -l = [1,2,3,4,5] -main = hash l --- -849277455 \ No newline at end of file diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidLambda.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidLambda.scl index 723a017d3..8897d43dd 100644 --- a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidLambda.scl +++ b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidLambda.scl @@ -1,4 +1,4 @@ main = \ /* no parameters */ -> 3 -- -2:30-2:32: Unexpected token '->' (ARROW). Expected one of ATTACHED_HASH, BEGIN_STRING, BLANK, CHAR, DO, ENFORCE, ESCAPED_SYMBOL, FLOAT, ID, IF, INTEGER, LAMBDA, LBRACKET, LET, LPAREN, MATCH, MDO, SELECT, SELECT_DISTINCT, SELECT_FIRST, TRANSFORMATION, WHEN. +2:30-2:32: Unexpected token '->' (ARROW). Expected one of ATTACHED_HASH, BEGIN_STRING, BLANK, CHAR, DO, ENFORCE, EQ, ESCAPED_SYMBOL, FLOAT, ID, IF, INTEGER, LAMBDA, LBRACKET, LET, LPAREN, MATCH, MDO, SELECT, SELECT_DISTINCT, SELECT_FIRST, TRANSFORMATION, WHEN. diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Matching3b.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Matching3b.scl new file mode 100644 index 000000000..486434583 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Matching3b.scl @@ -0,0 +1,8 @@ +import "StandardLibrary" + +foo 1 = "one" +foo 2 = "two" + +main = if True then foo (2 :: Long) else foo (1 :: Integer) +-- +two \ No newline at end of file diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MatchingWithMissingParameter.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MatchingWithMissingParameter.scl new file mode 100644 index 000000000..33a681fd3 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MatchingWithMissingParameter.scl @@ -0,0 +1,10 @@ +data Foo = Foo Integer Integer + | Bar + +isFoo (Foo _) = True +isFoo _ = False + +main = "Hello world!" +-- +4:7-4:14: The function is applied with too few parameters. + diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Overloading1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Overloading1.scl new file mode 100644 index 000000000..dfb607934 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Overloading1.scl @@ -0,0 +1,19 @@ +// module Foo1 +import "Prelude" + +foo :: Integer -> Boolean +foo i = i == 5 +-- +// module Foo2 +import "Prelude" + +foo :: Integer -> Integer -> Boolean +foo i j = i == j +-- +import "Prelude" +import "Foo1" +import "Foo2" + +main = foo 5 && foo 5 4 +-- +false \ No newline at end of file diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Overloading2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Overloading2.scl new file mode 100644 index 000000000..e7a28de00 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Overloading2.scl @@ -0,0 +1,20 @@ +// module Max1 +import "Prelude" + +myMax :: Ord a => a -> a -> a +myMax = max +-- +// module Max2 +import "Prelude" + +myMax :: Ord a => a -> a -> a -> a +myMax a b c = max a (max b c) +-- +import "Prelude" +import "Max1" +import "Max2" + +main = myMax (1 :: Integer) 2 3 + myMax (3 :: Integer) 2 1 + myMax 4 2 :: Integer +-- +10 + diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Overloading3.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Overloading3.scl new file mode 100644 index 000000000..9385ce7bc --- /dev/null +++ b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Overloading3.scl @@ -0,0 +1,23 @@ +// module M1 +import "Prelude" + +foo :: Ring a => Boolean -> a -> a +foo True v = v+1 +foo False v = v+1 +-- +// module M2 +import "Prelude" + +foo :: Ring a => String -> a -> a +foo cond v = if cond=="true" + then v+1 + else v-1 +-- +import "Prelude" +import "M1" +import "M2" + +main = foo False (foo "True" 10) :: Integer +-- +10 + diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RecordShorthand.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RecordShorthand.scl new file mode 100644 index 000000000..d3af73e02 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RecordShorthand.scl @@ -0,0 +1,11 @@ +import "Prelude" + +data Vec = Vec { x :: Double, y :: Double } +deriving instance Show Vec + +createVec x y = Vec {x, y} +sumVec Vec { x1, y1 } Vec { x2, y2 } = Vec { x = x1+x2, y = y1 + y2 } + +main = sumVec (createVec 1 2) (createVec 3 4) +-- +(Vec 4.0 6.0) \ No newline at end of file diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Seq.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Seq.scl deleted file mode 100644 index 4b60e5298..000000000 --- a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Seq.scl +++ /dev/null @@ -1,19 +0,0 @@ -import "Prelude" -import "JavaBuiltin" as Java - -class Seq seq el where - myLength :: seq -> Integer - myGet :: seq -> Integer -> el - -instance (b ~ Character) => Seq String b where - myLength = Java.method "length" - myGet = Java.method "charAt" - -instance (b ~ a) => Seq [a] b where - myLength = Java.method "size" - myGet = Java.method "get" - -//main :: (Character, String) -main = (myGet "abc" 1, myGet ["a", "b", "c"] 1) --- -(b,b) \ No newline at end of file diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/StringEscape.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/StringEscape.scl new file mode 100644 index 000000000..51a75d3cb --- /dev/null +++ b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/StringEscape.scl @@ -0,0 +1,12 @@ +main = "a\nb\"c\'d" +-- +a +b"c'd +-- +main = "a\u0053" +-- +aS +-- +main = "a\xb" +-- +1:8-1:10: Illegal string escape character. diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UnexpectedToken.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UnexpectedToken.scl index 891815259..270d5751b 100644 --- a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UnexpectedToken.scl +++ b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UnexpectedToken.scl @@ -1,4 +1,4 @@ -a = = -b = 4 --- -1:5-1:6: Unexpected token '=' (EQUALS). Expected one of ATTACHED_HASH, BEGIN_STRING, BLANK, CHAR, DO, ENFORCE, ESCAPED_SYMBOL, FLOAT, ID, IF, INTEGER, LAMBDA, LBRACKET, LET, LPAREN, MATCH, MDO, MINUS, SELECT, SELECT_DISTINCT, SELECT_FIRST, TRANSFORMATION, WHEN. +a = = +b = 4 +-- +1:5-1:6: Unexpected token '=' (EQUALS). Expected one of ATTACHED_HASH, BEGIN_STRING, BLANK, CHAR, DO, ENFORCE, EQ, ESCAPED_SYMBOL, FLOAT, ID, IF, INTEGER, LAMBDA, LBRACKET, LET, LPAREN, MATCH, MDO, MINUS, SELECT, SELECT_DISTINCT, SELECT_FIRST, TRANSFORMATION, WHEN. \ No newline at end of file diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/unit/TestNamespaceFilter.java b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/unit/TestNamespaceFilter.java index 5fbc73cf9..fa3bd9f65 100644 --- a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/unit/TestNamespaceFilter.java +++ b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/unit/TestNamespaceFilter.java @@ -1,11 +1,7 @@ package org.simantics.scl.compiler.tests.unit; -import gnu.trove.set.hash.THashSet; - import java.util.Collection; -import junit.framework.Assert; - import org.junit.Test; import org.simantics.scl.compiler.environment.filter.AcceptAllNamespaceFilter; import org.simantics.scl.compiler.environment.filter.NamespaceFilter; @@ -13,6 +9,9 @@ import org.simantics.scl.compiler.environment.filter.NamespaceFilters; import org.simantics.scl.compiler.environment.filter.NegativeNamespaceFilter; import org.simantics.scl.compiler.environment.filter.PositiveNamespaceFilter; +import gnu.trove.set.hash.THashSet; +import junit.framework.Assert; + public class TestNamespaceFilter { private void testBooleanOperations(Collection all, NamespaceFilter a, NamespaceFilter b) { diff --git a/bundles/org.simantics.scl.osgi/src/org/simantics/scl/osgi/internal/BundleModuleSource.java b/bundles/org.simantics.scl.osgi/src/org/simantics/scl/osgi/internal/BundleModuleSource.java index 66431fe50..975dd57fd 100644 --- a/bundles/org.simantics.scl.osgi/src/org/simantics/scl/osgi/internal/BundleModuleSource.java +++ b/bundles/org.simantics.scl.osgi/src/org/simantics/scl/osgi/internal/BundleModuleSource.java @@ -105,7 +105,6 @@ public class BundleModuleSource extends EncodedTextualModuleSource { } public void checkUpdates() { - System.out.println(url + " checkUpdates"); if(digest != null && listeners != null) { byte[] newDigest = computeDigest(); if(!Arrays.equals(digest, newDigest)) { @@ -137,7 +136,6 @@ public class BundleModuleSource extends EncodedTextualModuleSource { @Override public void update(String newSourceText) { - System.out.println(url + " update"); try { Path path = getPath(); Files.write(path, newSourceText.getBytes(Charset.forName("UTF-8"))); diff --git a/bundles/org.simantics.scl.osgi/src/org/simantics/scl/osgi/internal/BundleTestScriptRunnable.java b/bundles/org.simantics.scl.osgi/src/org/simantics/scl/osgi/internal/BundleTestScriptRunnable.java index 2a5d56d7e..c064bd79c 100644 --- a/bundles/org.simantics.scl.osgi/src/org/simantics/scl/osgi/internal/BundleTestScriptRunnable.java +++ b/bundles/org.simantics.scl.osgi/src/org/simantics/scl/osgi/internal/BundleTestScriptRunnable.java @@ -43,9 +43,6 @@ public class BundleTestScriptRunnable implements TestRunnable { try { CommandSession session = new CommandSession(SCLOsgi.MODULE_REPOSITORY, handler); new TestScriptExecutor(session, reader, handler).execute(); - } catch(Throwable e) { - CommandSession.formatException(handler, e); - throw e; } finally { reader.close(); } diff --git a/bundles/org.simantics.scl.runtime/META-INF/MANIFEST.MF b/bundles/org.simantics.scl.runtime/META-INF/MANIFEST.MF index ea449d36c..64d5ac63d 100755 --- a/bundles/org.simantics.scl.runtime/META-INF/MANIFEST.MF +++ b/bundles/org.simantics.scl.runtime/META-INF/MANIFEST.MF @@ -6,7 +6,7 @@ Bundle-Version: 0.4.0.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Export-Package: org.simantics.scl.runtime, org.simantics.scl.runtime.collection, - org.simantics.scl.runtime.equations, + org.simantics.scl.runtime.exceptions, org.simantics.scl.runtime.function, org.simantics.scl.runtime.io, org.simantics.scl.runtime.lazy, diff --git a/bundles/org.simantics.scl.runtime/build.properties b/bundles/org.simantics.scl.runtime/build.properties index accef0636..cbbb8252d 100755 --- a/bundles/org.simantics.scl.runtime/build.properties +++ b/bundles/org.simantics.scl.runtime/build.properties @@ -3,5 +3,4 @@ output.. = bin/ bin.includes = META-INF/,\ .,\ scl/,\ - schema/,\ - plugin.xml \ No newline at end of file + schema/ \ No newline at end of file diff --git a/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/Lists.java b/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/Lists.java index 50376a61b..7149fc63e 100755 --- a/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/Lists.java +++ b/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/Lists.java @@ -1,9 +1,5 @@ package org.simantics.scl.runtime; -import gnu.trove.map.hash.TCustomHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.strategy.HashingStrategy; - import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; @@ -15,6 +11,10 @@ import org.simantics.scl.runtime.function.FunctionImpl1; import org.simantics.scl.runtime.function.FunctionImpl2; import org.simantics.scl.runtime.tuple.Tuple2; +import gnu.trove.map.hash.TCustomHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.strategy.HashingStrategy; + @SuppressWarnings({"rawtypes", "unchecked"}) public class Lists { diff --git a/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/SCLContext.java b/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/SCLContext.java index 63fa2f1e2..9b3da5232 100644 --- a/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/SCLContext.java +++ b/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/SCLContext.java @@ -2,8 +2,6 @@ package org.simantics.scl.runtime; import gnu.trove.map.hash.THashMap; -import java.util.Map; - public class SCLContext extends THashMap { private static ThreadLocal CONTEXT = new ThreadLocal(); private static ThreadLocal OLD_CONTEXT = new ThreadLocal(); diff --git a/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/equations/TestEquationContext.java b/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/equations/TestEquationContext.java index 8b1c71ef9..856ef2870 100644 --- a/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/equations/TestEquationContext.java +++ b/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/equations/TestEquationContext.java @@ -2,7 +2,6 @@ package org.simantics.scl.runtime.equations; import java.util.ArrayList; import java.util.Collections; -import java.util.Comparator; import java.util.List; import org.simantics.scl.runtime.SCLContext; diff --git a/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/exceptions/MatchingException.java b/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/exceptions/MatchingException.java new file mode 100644 index 000000000..9bca8d80f --- /dev/null +++ b/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/exceptions/MatchingException.java @@ -0,0 +1,13 @@ +package org.simantics.scl.runtime.exceptions; + +public class MatchingException extends RuntimeException { + private static final long serialVersionUID = -3364111368224089448L; + + public MatchingException() { + super(); + } + + public MatchingException(String message) { + super(message); + } +} diff --git a/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/io/SclIO.java b/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/io/SclIO.java index 5b515c262..69cfa77be 100644 --- a/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/io/SclIO.java +++ b/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/io/SclIO.java @@ -1,13 +1,13 @@ package org.simantics.scl.runtime.io; -import gnu.trove.list.array.TByteArrayList; - import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.charset.Charset; +import gnu.trove.list.array.TByteArrayList; + public class SclIO { private static final Charset UTF8 = Charset.forName("UTF-8"); diff --git a/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/minigraph/Minigraph.java b/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/minigraph/Minigraph.java index 0a5b99dc6..4294ee96a 100644 --- a/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/minigraph/Minigraph.java +++ b/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/minigraph/Minigraph.java @@ -1,12 +1,5 @@ package org.simantics.scl.runtime.minigraph; -import gnu.trove.impl.Constants; -import gnu.trove.map.hash.TIntObjectHashMap; -import gnu.trove.map.hash.TLongObjectHashMap; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.procedure.TIntProcedure; -import gnu.trove.set.hash.TIntHashSet; - import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -15,6 +8,13 @@ import org.simantics.scl.runtime.SCLContext; import org.simantics.scl.runtime.function.Function; import org.simantics.scl.runtime.tuple.Tuple0; +import gnu.trove.impl.Constants; +import gnu.trove.map.hash.TIntObjectHashMap; +import gnu.trove.map.hash.TLongObjectHashMap; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.procedure.TIntProcedure; +import gnu.trove.set.hash.TIntHashSet; + public class Minigraph { private static final int[] EMPTY_INT_ARRAY = new int[0]; diff --git a/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/unification/UMapUtils.java b/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/unification/UMapUtils.java index 8bc899370..4b4657323 100644 --- a/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/unification/UMapUtils.java +++ b/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/unification/UMapUtils.java @@ -1,12 +1,12 @@ package org.simantics.scl.runtime.unification; -import gnu.trove.map.hash.THashMap; - import java.util.Map; import org.simantics.scl.runtime.function.Function; import org.simantics.scl.runtime.tuple.Tuple0; +import gnu.trove.map.hash.THashMap; + public class UMapUtils { public static void put(Map map, Object key, Object value) { if(map.containsKey(key)) diff --git a/bundles/org.simantics.spreadsheet.ontology/build.properties b/bundles/org.simantics.spreadsheet.ontology/build.properties index 15454c697..fb164279d 100644 --- a/bundles/org.simantics.spreadsheet.ontology/build.properties +++ b/bundles/org.simantics.spreadsheet.ontology/build.properties @@ -2,6 +2,5 @@ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ .,\ - graphs/*.tg,\ graph.tg src.includes = graph/ diff --git a/bundles/org.simantics.structural.ontology/build.properties b/bundles/org.simantics.structural.ontology/build.properties index 15454c697..fb164279d 100644 --- a/bundles/org.simantics.structural.ontology/build.properties +++ b/bundles/org.simantics.structural.ontology/build.properties @@ -2,6 +2,5 @@ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ .,\ - graphs/*.tg,\ graph.tg src.includes = graph/ diff --git a/bundles/org.simantics.threadlog/.classpath b/bundles/org.simantics.threadlog/.classpath new file mode 100644 index 000000000..23e107f90 --- /dev/null +++ b/bundles/org.simantics.threadlog/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/bundles/org.simantics.threadlog/.project b/bundles/org.simantics.threadlog/.project new file mode 100644 index 000000000..2b62393d1 --- /dev/null +++ b/bundles/org.simantics.threadlog/.project @@ -0,0 +1,28 @@ + + + org.simantics.threadlog + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/bundles/org.simantics.threadlog/.settings/org.eclipse.jdt.core.prefs b/bundles/org.simantics.threadlog/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..81b661013 --- /dev/null +++ b/bundles/org.simantics.threadlog/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Fri Oct 30 22:48:46 EET 2009 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/bundles/org.simantics.threadlog/META-INF/MANIFEST.MF b/bundles/org.simantics.threadlog/META-INF/MANIFEST.MF new file mode 100644 index 000000000..79b038e46 --- /dev/null +++ b/bundles/org.simantics.threadlog/META-INF/MANIFEST.MF @@ -0,0 +1,11 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Threadlog +Bundle-SymbolicName: org.simantics.threadlog +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: org.simantics.threadlog.internal.Activator +Require-Bundle: org.eclipse.core.runtime, + gnu.trove2;bundle-version="2.0.0" +Bundle-ActivationPolicy: lazy +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Export-Package: org.simantics.threadlog diff --git a/bundles/org.simantics.threadlog/build.properties b/bundles/org.simantics.threadlog/build.properties new file mode 100644 index 000000000..b088bf189 --- /dev/null +++ b/bundles/org.simantics.threadlog/build.properties @@ -0,0 +1,15 @@ +############################################################################### +# Copyright (c) 2007, 2010 Association for Decentralized Information Management +# in Industry THTH ry. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# VTT Technical Research Centre of Finland - initial API and implementation +############################################################################### +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/bundles/org.simantics.threadlog/examples/org/simantics/threadlog/examples/Example1.java b/bundles/org.simantics.threadlog/examples/org/simantics/threadlog/examples/Example1.java new file mode 100644 index 000000000..953055313 --- /dev/null +++ b/bundles/org.simantics.threadlog/examples/org/simantics/threadlog/examples/Example1.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.threadlog.examples; + +import static org.simantics.threadlog.ThreadLog.BEGIN; + +import org.simantics.threadlog.Task; +import org.simantics.threadlog.ui.ThreadLogController; + +public class Example1 { + + public static void main(String[] args) throws InterruptedException { + ThreadLogController.start(); + + while(true) { + Thread.sleep(50); + Task t = BEGIN("Foo"); + Thread.sleep(100); + t.end(); + } + } + +} diff --git a/bundles/org.simantics.threadlog/src/org/simantics/threadlog/Task.java b/bundles/org.simantics.threadlog/src/org/simantics/threadlog/Task.java new file mode 100644 index 000000000..d9198caa1 --- /dev/null +++ b/bundles/org.simantics.threadlog/src/org/simantics/threadlog/Task.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.threadlog; + +public interface Task { + void end(); +} diff --git a/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ThreadLog.java b/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ThreadLog.java new file mode 100644 index 000000000..a6214741a --- /dev/null +++ b/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ThreadLog.java @@ -0,0 +1,175 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.threadlog; + +import gnu.trove.TDoubleArrayList; +import gnu.trove.TLongArrayList; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.DataInput; +import java.io.DataInputStream; +import java.io.DataOutput; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.StreamCorruptedException; +import java.util.ArrayList; + +public class ThreadLog { + + private static final transient String HDR = "TLOG"; + private static final transient int CURRENT_VERSION = 1; + + static ThreadLog defaultLog; + + ArrayList tasks = new ArrayList(); + TDoubleArrayList times = new TDoubleArrayList(); + TLongArrayList threads = new TLongArrayList(); + + public double[] getTimes() { + return times.toNativeArray(); + } + + public String[] getTasks() { + return tasks.toArray(new String[tasks.size()]); + } + + public long[] getThreads() { + return threads.toNativeArray(); + } + + private class TaskImpl implements Task { + public String name; + public long thread; + public long beginTime; + + public TaskImpl(String name) { + this.name = name; + this.thread = Thread.currentThread().getId(); + this.beginTime = System.nanoTime(); + } + + @Override + public void end() { + long endTime = System.nanoTime(); + synchronized(tasks) { + tasks.add(name); + times.add(beginTime*1e-9); + times.add(endTime*1e-9); + threads.add(thread); + } + } + } + + private static enum DummyTask implements Task { + INSTANCE; + + @Override + public void end() { + } + } + + public Task begin(String name) { + return new TaskImpl(name); + } + + public static Task BEGIN(String name) { + try { + if(defaultLog != null) + return defaultLog.begin(name); + } catch(NullPointerException e) { + } + return DummyTask.INSTANCE; + } + + public static ThreadLog setDefaultThreadLog(ThreadLog log) { + ThreadLog currentLog = defaultLog; + defaultLog = log; + return currentLog; + } + + // ------------------------------------------------------------------------ + // SERIALIZATION + // ------------------------------------------------------------------------ + + public static ThreadLog deserialize(File file) throws IOException { + DataInputStream in = null; + try { + in = new DataInputStream(new BufferedInputStream(new FileInputStream(file))); + ThreadLog log = new ThreadLog(); + log.doDeserialize(in); + return log; + } finally { + if (in != null) { + in.close(); + } + } + } + + public static ThreadLog deserialize(DataInput in) throws IOException { + ThreadLog log = new ThreadLog(); + log.doDeserialize(in); + return log; + } + + private void doDeserialize(DataInput in) throws IOException { + String hdr = in.readUTF(); + if (!HDR.equals(hdr)) { + throw new StreamCorruptedException("invalid header '" + hdr + "', expected " + HDR); + } + int ver = in.readInt(); + if (ver == CURRENT_VERSION) { + int taskCount = in.readInt(); + for (int i = 0; i < taskCount; ++i) { + String task = in.readUTF(); + double beginTime = in.readDouble(); + double endTime = in.readDouble(); + long threadId = in.readLong(); + tasks.add(task); + times.add(beginTime); + times.add(endTime); + threads.add(threadId); + } + } else { + throw new StreamCorruptedException("unrecognized log version: " + ver); + } + } + + public void serialize(File file) throws IOException { + DataOutputStream out = null; + try { + out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file))); + serialize(out); + } finally { + if (out != null) { + out.close(); + } + } + } + + public void serialize(DataOutput out) throws IOException { + out.writeUTF(HDR); + out.writeInt(CURRENT_VERSION); + int len = tasks.size(); + out.writeInt(len); + for (int i = 0; i < len; ++i) { + out.writeUTF(tasks.get(i)); + out.writeDouble(times.getQuick(i*2)); + out.writeDouble(times.getQuick(i*2+1)); + out.writeLong(threads.getQuick(i)); + } + } + +} diff --git a/bundles/org.simantics.threadlog/src/org/simantics/threadlog/internal/Activator.java b/bundles/org.simantics.threadlog/src/org/simantics/threadlog/internal/Activator.java new file mode 100644 index 000000000..908fbd015 --- /dev/null +++ b/bundles/org.simantics.threadlog/src/org/simantics/threadlog/internal/Activator.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.threadlog.internal; + +import org.eclipse.core.runtime.Plugin; +import org.osgi.framework.BundleContext; +import org.simantics.threadlog.ui.ThreadLogController; + +/** + * The activator class controls the plug-in life cycle + */ +public class Activator extends Plugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.simantics.threadlog"; + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() { + } + + /* + * (non-Javadoc) + * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + + ThreadLogController.start(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + +} diff --git a/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/Interval.java b/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/Interval.java new file mode 100644 index 000000000..e7f2fa181 --- /dev/null +++ b/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/Interval.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.threadlog.ui; + +public class Interval implements Comparable { + String text; + double begin; + double end; + + public Interval(String text, double begin, double end) { + this.text = text; + this.begin = begin; + this.end = end; + } + + @Override + public int compareTo(Interval o) { + return Double.compare(begin, o.begin); + } +} diff --git a/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/Lane.java b/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/Lane.java new file mode 100644 index 000000000..2c06e4185 --- /dev/null +++ b/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/Lane.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.threadlog.ui; + +import java.util.ArrayList; +import java.util.List; + +public class Lane { + List intervals = new ArrayList(); + + public void addInterval(Interval interval) { + intervals.add(interval); + } + + public double getEnd() { + return intervals.get(intervals.size()-1).end; + } +} diff --git a/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/ThreadLogController.java b/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/ThreadLogController.java new file mode 100644 index 000000000..36a605db7 --- /dev/null +++ b/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/ThreadLogController.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.threadlog.ui; + +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.IOException; + +import javax.swing.JButton; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.filechooser.FileNameExtensionFilter; + +import org.simantics.threadlog.ThreadLog; + +public class ThreadLogController extends JFrame { + + private static final long serialVersionUID = -2487997716157625672L; + + boolean isLogging = false; + JButton logButton; + JButton loadButton; + + public ThreadLogController() { + super("Thread log controller"); + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + + logButton = new JButton("Start logging"); + logButton.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + if(isLogging) { + logButton.setText("Start logging"); + isLogging = false; + ThreadLog log = ThreadLog.setDefaultThreadLog(null); + + ThreadLogVisualizer visualizer = new ThreadLogVisualizer(); + visualizer.setLog(log); + visualizer.setVisible(true); + } + else { + logButton.setText("Stop logging"); + isLogging = true; + ThreadLog.setDefaultThreadLog(new ThreadLog()); + } + } + + }); + loadButton = new JButton("Load log"); + loadButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + JFileChooser chooser = new JFileChooser(); + FileNameExtensionFilter filter = new FileNameExtensionFilter( + "Thread Logs (*.tlog)", "tlog", "tlog"); + chooser.setFileFilter(filter); + int returnVal = chooser.showOpenDialog(ThreadLogController.this); + if (returnVal != JFileChooser.APPROVE_OPTION) + return; + + try { + ThreadLog log = ThreadLog.deserialize(chooser.getSelectedFile()); + ThreadLogVisualizer visualizer = new ThreadLogVisualizer(); + visualizer.setLog(log); + visualizer.setVisible(true); + } catch (IOException ex) { + ex.printStackTrace(); + } + } + }); + getContentPane().setLayout(new GridLayout(2, 1)); + getContentPane().add(logButton); + getContentPane().add(loadButton); + + setSize(200, 100); + } + + public static void start() { + javax.swing.SwingUtilities.invokeLater(new Runnable() { + public void run() { + new ThreadLogController().setVisible(true); + } + }); + } + + public static void main(String[] args) { + start(); + } + +} diff --git a/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/ThreadLogVisualizer.java b/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/ThreadLogVisualizer.java new file mode 100644 index 000000000..db29a910a --- /dev/null +++ b/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/ThreadLogVisualizer.java @@ -0,0 +1,187 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.threadlog.ui; + +import gnu.trove.TLongObjectHashMap; +import gnu.trove.TObjectProcedure; + +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; + +import javax.swing.AbstractAction; +import javax.swing.JButton; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JToolBar; +import javax.swing.filechooser.FileNameExtensionFilter; + +import org.simantics.threadlog.Task; +import org.simantics.threadlog.ThreadLog; + +public class ThreadLogVisualizer extends JFrame { + + private static final long serialVersionUID = 6250996509358338304L; + + TimeLineViewer viewer = new TimeLineViewer(); + JToolBar toolbar = new JToolBar("Thread Log Visualizer Tools"); + JButton saveButton = new JButton(new SaveAction()); + + ThreadLog currentLog; + + public ThreadLogVisualizer() { + super("Thread log visualizer"); + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + setSize(800, 600); + + getContentPane().setLayout(new BorderLayout()); + getContentPane().add(toolbar, BorderLayout.NORTH); + getContentPane().add(viewer, BorderLayout.CENTER); + + toolbar.add(saveButton); + } + + class SaveAction extends AbstractAction { + private static final long serialVersionUID = 1L; + + public SaveAction() { + super("Save"); + putValue(SHORT_DESCRIPTION, "Save the Current Log"); + putValue(MNEMONIC_KEY, KeyEvent.VK_S); + } + + @Override + public void actionPerformed(ActionEvent e) { + JFileChooser chooser = new JFileChooser(); + FileNameExtensionFilter filter = new FileNameExtensionFilter( + "Thread Logs (*.tlog)", "tlog", "tlog"); + chooser.setFileFilter(filter); + int returnVal = chooser.showSaveDialog(ThreadLogVisualizer.this); + if (returnVal != JFileChooser.APPROVE_OPTION) + return; + + try { + currentLog.serialize(chooser.getSelectedFile()); + } catch (IOException ex) { + ex.printStackTrace(); + } + } + } + + public void setLog(ThreadLog log) { + this.currentLog = log; + + String[] tasks = log.getTasks(); + double[] times = log.getTimes(); + + // Relativize to the first task + double minTime = Double.POSITIVE_INFINITY; + double maxTime = Double.NEGATIVE_INFINITY; + + for(int i=0;i maxTime) + maxTime = temp; + } + for(int i=0;i> intervals = new TLongObjectHashMap>(); + long[] threads = log.getThreads(); + for(int i=0;i in = intervals.get(thread); + if(in == null) { + in = new ArrayList(); + intervals.put(thread, in); + } + in.add(new Interval(tasks[i], times[i*2], times[i*2+1])); + } + + // Create lanes + viewer.clear(); + intervals.forEachValue(new TObjectProcedure>() { + + @Override + public boolean execute(ArrayList intervals) { + Collections.sort(intervals); + ArrayList lanes = new ArrayList(); + + int curLaneId = -1; + Lane curLane = null; + for(Interval in : intervals) { + if(curLane == null || in.begin < curLane.getEnd()) { + ++curLaneId; + if(curLaneId < lanes.size()) + curLane = lanes.get(curLaneId); + else { + curLane = new Lane(); + lanes.add(curLane); + } + } + else { + while(curLaneId > 0) { + Lane prevLane = lanes.get(curLaneId-1); + if(prevLane.getEnd() > in.begin) + break; + --curLaneId; + curLane = prevLane; + } + } + curLane.addInterval(in); + } + + for(Lane lane : lanes) + viewer.addLane(lane); + return true; + } + + }); + + // update viewer + viewer.repaint(); + } + + public void saveImage() { + + } + + public static void main(String[] args) throws Exception { + ThreadLog.setDefaultThreadLog(new ThreadLog()); + + { + Task A = ThreadLog.BEGIN("A"); + Thread.sleep(200); + Task B = ThreadLog.BEGIN("B"); + Thread.sleep(100); + B.end(); + Thread.sleep(100); + Task C = ThreadLog.BEGIN("C"); + Thread.sleep(100); + C.end(); + A.end(); + } + + ThreadLogVisualizer vis = new ThreadLogVisualizer(); + vis.setLog(ThreadLog.setDefaultThreadLog(null)); + vis.setVisible(true); + } +} diff --git a/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/TimeLineViewer.java b/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/TimeLineViewer.java new file mode 100644 index 000000000..40aefb055 --- /dev/null +++ b/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/TimeLineViewer.java @@ -0,0 +1,184 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.threadlog.ui; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Shape; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; +import java.awt.geom.Rectangle2D; +import java.awt.geom.RoundRectangle2D; +import java.text.DecimalFormat; +import java.text.Format; +import java.util.ArrayList; +import java.util.List; +import java.util.Timer; +import java.util.TimerTask; + +import javax.swing.JPanel; + +public class TimeLineViewer extends JPanel { + + private static final long serialVersionUID = -7410066541298449720L; + + public static long TOOL_TIP_DELAY = 500; + public static double MIN_GRID_LINE_SEPARATION = 15; + + // Time line data + List lanes = new ArrayList(); + + // For panning and zooming + double xScale = 100.0; + double xOffset = 0.0; + double yOffset = 0.0; + int oldX; + int oldY; + + // Tool tips + Timer toolTipTimer = new Timer(); + class ToolTipTask extends TimerTask { + + @Override + public void run() { + System.out.println("show tooltip"); + } + + } + + public TimeLineViewer() { + addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + oldX = e.getX(); + oldY = e.getY(); + } + }); + addMouseMotionListener(new MouseMotionAdapter() { + @Override + public void mouseDragged(MouseEvent e) { + int curX = e.getX(); + int curY = e.getY(); + int diffX = curX - oldX; + int diffY = curY - oldY; + oldX = curX; + oldY = curY; + + xOffset -= diffX/xScale; + yOffset -= diffY; + repaint(); + } + TimerTask toolTipTask; + @Override + public void mouseMoved(MouseEvent e) { + if(toolTipTask != null) + toolTipTask.cancel(); + toolTipTask = new ToolTipTask(); + toolTipTimer.schedule(toolTipTask, TOOL_TIP_DELAY); + } + }); + addMouseWheelListener(new MouseWheelListener() { + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + xOffset += e.getX() / xScale; + xScale *= Math.pow(1.25, -e.getWheelRotation()); + xOffset -= e.getX() / xScale; + repaint(); + } + }); + } + + public void addLane(Lane lane) { + lanes.add(lane); + } + + public void clear() { + lanes.clear(); + } + + public void paintIntervals(Graphics2D g) { + for(int laneId=0;laneId < lanes.size();++laneId) { + Lane lane = lanes.get(laneId); + + double y = 35.0*laneId - yOffset; + double height = 30.0; + + for(Interval interval : lane.intervals) { + double x = (interval.begin - xOffset) * xScale; + double width = (interval.end - interval.begin) * xScale; + + Shape shape = new RoundRectangle2D.Double(x, y, width, height, 10.0, 10.0); + g.setColor(Color.WHITE); + g.fill(shape); + g.setColor(Color.BLACK); + g.draw(shape); + + Rectangle2D bounds = g.getFontMetrics().getStringBounds(interval.text, g); + if(bounds.getWidth() < width) + g.drawString(interval.text, (float)(x+0.5*(width-bounds.getWidth())), (float)(y+20.0)); + } + } + } + + public void paintGrid(Graphics2D g) { + Dimension dim = getSize(); + + g.setBackground(Color.WHITE); + g.clearRect(0, 0, dim.width, dim.height); + + double stepsize = 0.001; + double majorStepsize; + while(true) { + majorStepsize = stepsize * 5.0; + if(stepsize * xScale >= MIN_GRID_LINE_SEPARATION) + break; + stepsize = majorStepsize; + majorStepsize = stepsize * 2.0; + if(stepsize * xScale >= MIN_GRID_LINE_SEPARATION) + break; + stepsize = majorStepsize; + } + + double firstP = Math.ceil(xOffset / stepsize) * stepsize; + double lastP = Math.floor((xOffset + dim.width / xScale) / stepsize) * stepsize; + if(firstP < 0.0) + firstP = 0.0; + + Format format = new DecimalFormat(); + for(double p = firstP;p <= lastP; p+=stepsize) { + int x = (int)((p - xOffset) * xScale); + if(Math.abs(p/majorStepsize - Math.round(p/majorStepsize)) < 1e-3) { + g.setColor(Color.BLACK); + String text = format.format(p); + Rectangle2D bounds = g.getFontMetrics().getStringBounds(text, g); + g.drawString(text, (float)(x-bounds.getWidth()*0.5), 12.0f); + } + else + g.setColor(Color.LIGHT_GRAY); + g.drawLine(x, 14, x, (int)dim.getHeight()); + } + } + + @Override + public void paint(Graphics _g) { + Graphics2D g = (Graphics2D)_g; + + paintGrid(g); + paintIntervals(g); + } + +} diff --git a/bundles/org.simantics.utils.datastructures/build.properties b/bundles/org.simantics.utils.datastructures/build.properties index 06b471165..b088bf189 100644 --- a/bundles/org.simantics.utils.datastructures/build.properties +++ b/bundles/org.simantics.utils.datastructures/build.properties @@ -13,6 +13,3 @@ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ . -javacSource=1.6 -javacTarget=1.6 - \ No newline at end of file diff --git a/bundles/pom.xml b/bundles/pom.xml index 1dbd1ef20..aa1e3ebd1 100644 --- a/bundles/pom.xml +++ b/bundles/pom.xml @@ -58,6 +58,7 @@ org.simantics.diagram.profile org.simantics.document org.simantics.document.base.ontology + org.simantics.document.linking.ontology org.simantics.document.linking.ui org.simantics.document.ontology org.simantics.document.server @@ -109,6 +110,7 @@ org.simantics.modeling.template2d.ontology org.simantics.modeling.template2d.ui org.simantics.modeling.ui + org.simantics.nativemem org.simantics.objmap2 org.simantics.platform.ui.ontology org.simantics.project @@ -122,6 +124,7 @@ org.simantics.scl.commands org.simantics.scl.compiler org.simantics.scl.compiler.dummy + org.simantics.scl.data org.simantics.scl.db org.simantics.scl.expressions org.simantics.scl.osgi @@ -150,6 +153,7 @@ org.simantics.structural.ui org.simantics.structural2 org.simantics.team.ui + org.simantics.threadlog org.simantics.trend org.simantics.ui org.simantics.user.ontology @@ -168,5 +172,6 @@ org.simantics.workbench org.simantics.workbench.ontology org.simantics.workbench.search + winterwell.markdown \ No newline at end of file diff --git a/bundles/winterwell.markdown/.classpath b/bundles/winterwell.markdown/.classpath new file mode 100644 index 000000000..cf4ff31b9 --- /dev/null +++ b/bundles/winterwell.markdown/.classpath @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/bundles/winterwell.markdown/.project b/bundles/winterwell.markdown/.project new file mode 100644 index 000000000..16de67173 --- /dev/null +++ b/bundles/winterwell.markdown/.project @@ -0,0 +1,28 @@ + + + winterwell.markdown + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/bundles/winterwell.markdown/META-INF/MANIFEST.MF b/bundles/winterwell.markdown/META-INF/MANIFEST.MF new file mode 100644 index 000000000..3c0bdf2bb --- /dev/null +++ b/bundles/winterwell.markdown/META-INF/MANIFEST.MF @@ -0,0 +1,41 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Markdown +Bundle-SymbolicName: winterwell.markdown;singleton:=true +Bundle-Version: 1.2.0.qualifier +Bundle-Activator: winterwell.markdown.Activator +Bundle-Vendor: Winterwell Associates Ltd +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.ui.editors, + org.eclipse.jface.text, + org.eclipse.core.resources, + org.eclipse.ui.views, + org.eclipse.jface, + org.eclipse.swt, + org.eclipse.ui.workbench +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-ActivationPolicy: lazy +Import-Package: org.eclipse.core.internal.resources, + org.eclipse.jface.text, + org.eclipse.ui.texteditor +Bundle-ClassPath: .,target/classes,lib/markdownj-1.0.2b4-0.3.0.jar, + lib/winterwell.utils.jar, + lib/net.sf.paperclips_1.0.1.jar +Export-Package: com.petebevin.markdown, + com.petebevin.markdown.test, + net.sf.paperclips, + net.sf.paperclips.decorator, + winterwell.markdown, + winterwell.markdown.editors, + winterwell.markdown.pagemodel, + winterwell.markdown.preferences, + winterwell.markdown.views, + winterwell.utils, + winterwell.utils.containers, + winterwell.utils.gui, + winterwell.utils.io, + winterwell.utils.reporting, + winterwell.utils.threads, + winterwell.utils.time, + winterwell.utils.web diff --git a/bundles/winterwell.markdown/build.properties b/bundles/winterwell.markdown/build.properties new file mode 100644 index 000000000..ccfe656ed --- /dev/null +++ b/bundles/winterwell.markdown/build.properties @@ -0,0 +1,15 @@ +source.. = src/ +bin.includes = META-INF/,\ + plugin.xml,\ + icons/,\ + .,\ + lib/ +src.includes = src/,\ + pom.xml,\ + plugin.xml,\ + icons/,\ + lib/,\ + .project,\ + .classpath,\ + META-INF/,\ + build.properties diff --git a/bundles/winterwell.markdown/icons/coffee.png b/bundles/winterwell.markdown/icons/coffee.png new file mode 100644 index 000000000..2a8c92bc4 Binary files /dev/null and b/bundles/winterwell.markdown/icons/coffee.png differ diff --git a/bundles/winterwell.markdown/icons/github-cat_yellow.png b/bundles/winterwell.markdown/icons/github-cat_yellow.png new file mode 100644 index 000000000..a1e5ea993 Binary files /dev/null and b/bundles/winterwell.markdown/icons/github-cat_yellow.png differ diff --git a/bundles/winterwell.markdown/icons/notepad.gif b/bundles/winterwell.markdown/icons/notepad.gif new file mode 100644 index 000000000..153159366 Binary files /dev/null and b/bundles/winterwell.markdown/icons/notepad.gif differ diff --git a/bundles/winterwell.markdown/icons/settings16_yellow.png b/bundles/winterwell.markdown/icons/settings16_yellow.png new file mode 100644 index 000000000..27e53978a Binary files /dev/null and b/bundles/winterwell.markdown/icons/settings16_yellow.png differ diff --git a/bundles/winterwell.markdown/lib/markdownj-1.0.2b4-0.3.0.jar b/bundles/winterwell.markdown/lib/markdownj-1.0.2b4-0.3.0.jar new file mode 100644 index 000000000..5e8f22b91 Binary files /dev/null and b/bundles/winterwell.markdown/lib/markdownj-1.0.2b4-0.3.0.jar differ diff --git a/bundles/winterwell.markdown/lib/net.sf.paperclips_1.0.1.jar b/bundles/winterwell.markdown/lib/net.sf.paperclips_1.0.1.jar new file mode 100644 index 000000000..18531820c Binary files /dev/null and b/bundles/winterwell.markdown/lib/net.sf.paperclips_1.0.1.jar differ diff --git a/bundles/winterwell.markdown/lib/winterwell.utils.jar b/bundles/winterwell.markdown/lib/winterwell.utils.jar new file mode 100644 index 000000000..1a5784a41 Binary files /dev/null and b/bundles/winterwell.markdown/lib/winterwell.utils.jar differ diff --git a/bundles/winterwell.markdown/plugin.xml b/bundles/winterwell.markdown/plugin.xml new file mode 100644 index 000000000..8d043e788 --- /dev/null +++ b/bundles/winterwell.markdown/plugin.xml @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/Activator.java b/bundles/winterwell.markdown/src/winterwell/markdown/Activator.java new file mode 100644 index 000000000..300014442 --- /dev/null +++ b/bundles/winterwell.markdown/src/winterwell/markdown/Activator.java @@ -0,0 +1,60 @@ +package winterwell.markdown; + +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +import winterwell.markdown.preferences.MarkdownPreferencePage; + +/** + * The activator class controls the plug-in life cycle + */ +public class Activator extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "winterwell.markdown"; + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() { + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + doInstall(); + MarkdownPreferencePage.setDefaultPreferences(getPreferenceStore()); + } + + // ?? Have this method called by start(), saving a reminder so it doesn't repeat itself?? + private void doInstall() { + // ??Try to make this the default for file types -- but is this possible?? + // c.f. http://stackoverflow.com/questions/15877123/eclipse-rcp-programmatically-associate-file-type-with-editor + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + +} diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/LogUtil.java b/bundles/winterwell.markdown/src/winterwell/markdown/LogUtil.java new file mode 100644 index 000000000..384b951c4 --- /dev/null +++ b/bundles/winterwell.markdown/src/winterwell/markdown/LogUtil.java @@ -0,0 +1,41 @@ +package winterwell.markdown; + +import org.eclipse.core.runtime.ILog; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; + +/** + * Nodeclipse Log Util + * @author Lamb Gao, Paul Verest + */ +public class LogUtil { + + public static void info(String message) { + log(IStatus.INFO, IStatus.OK, message, null); + } + + public static void error(Throwable exception) { + error("Unexpected Exception", exception); + } + + public static void error(String message) { + error(message, null); + } + + public static void error(String message, Throwable exception) { + log(IStatus.ERROR, IStatus.ERROR, message, exception); + } + + public static void log(int severity, int code, String message, Throwable exception) { + log(createStatus(severity, code, message, exception)); + } + + public static IStatus createStatus(int severity, int code, String message, Throwable exception) { + return new Status(severity, Activator.PLUGIN_ID, code, message, exception); + } + + public static void log(IStatus status) { + ILog log = Activator.getDefault().getLog(); + log.log(status); + } +} diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/StringMethods.java b/bundles/winterwell.markdown/src/winterwell/markdown/StringMethods.java new file mode 100644 index 000000000..208e0ae99 --- /dev/null +++ b/bundles/winterwell.markdown/src/winterwell/markdown/StringMethods.java @@ -0,0 +1,557 @@ +/** + * Basic String manipulation utilities. + * (c) Winterwell 2010 and ThinkTank Mathematics 2007 + */ +package winterwell.markdown; + +import java.math.BigInteger; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; + +import winterwell.utils.Mutable; +import winterwell.utils.containers.Pair; + +/** + * A collection of general-purpose String handling methods. + * + * @author daniel.winterstein + */ +public final class StringMethods { + + /** + * Removes xml tags, comment blocks and script blocks. + * + * @param page + * @return the page with all xml tags removed. + */ + public static String stripTags(String page) { + // This code is rather ugly, but it does the job + StringBuilder stripped = new StringBuilder(page.length()); + boolean inTag = false; + // Comment blocks and script blocks are given special treatment + boolean inComment = false; + boolean inScript = false; + // Go through the text + for (int i = 0; i < page.length(); i++) { + char c = page.charAt(i); + // First check whether we are ignoring text + if (inTag) { + if (c == '>') + inTag = false; + } else if (inComment) { + if (c == '>' && page.charAt(i - 1) == '-' + && page.charAt(i - 1) == '-') { + inComment = false; + } + } else if (inScript) { + if (c == '>' && page.substring(i - 7, i).equals("/script")) { + inScript = false; + } + } else { + // Check for the start of a tag - looks for '<' followed by any + // non-whitespace character + if (c == '<' && !Character.isWhitespace(page.charAt(i + 1))) { + // Comment, script-block or tag? + if (page.charAt(i + 1) == '!' && page.charAt(i + 2) == '-' + && page.charAt(i + 3) == '-') { + inComment = true; + } else if (i + 8 < page.length() + && page.substring(i + 1, i + 7).equals("script")) { + inScript = true; + i += 7; + } else + inTag = true; // Normal tag by default + } else { + // Append all non-tag chars + stripped.append(c); + } + } // end if... + } + return stripped.toString(); + } + + /** + * The local line-end string. \n on unix, \r\n on windows, \r on mac. + */ + public static final String LINEEND = System.getProperty("line.separator"); + + /** + * @param s + * @return A version of s where the first letter is uppercase and all others + * are lowercase + */ + public static final String capitalise(final String s) { + return s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase(); + } + + /** + * Convert all line breaks into the system line break. + */ + public static final String convertLineBreaks(String text) { + return convertLineBreaks(text, LINEEND); + } + + /** + * Convert all line breaks into the specified line break. + */ + public static final String convertLineBreaks(String text, String br) { + text = text.replaceAll("\r\n", br); + text = text.replaceAll("\r", br); + text = text.replaceAll("\n", br); + return text; + } + + /** + * @param string + * @param character + * @return the number of times character appears in the string + * @author Sam Halliday + */ + static public int countCharsInString(String string, char character) { + int count = 0; + for (char c : string.toCharArray()) { + if (c == character) { + count++; + } + } + return count; + } + + /** + * + * E.g. + * findEnclosingRegion("text with a [region] inside", 15, '[', ']') + * is (??,??) + * + * @param text + * @param offset + * @param start + * @param end + * @return the smallest enclosed region (including start and end chars, the + * 1st number is inclusive, the 2nd exclusive), or null if none. So + * text.subString(start,end) is the specified region + */ + public static Pair findEnclosingRegion(String text, int offset, + char startMarker, char endMarker) { + // Forward + int end = findEnclosingRegion2(text, offset, endMarker, 1); + if (end == -1) + return null; + end++; // end is exclusive + // Backward + int start = findEnclosingRegion2(text, offset, startMarker, -1); + if (start == -1) + return null; + // Sanity + assert text.substring(start, end).charAt(0) == startMarker; + assert text.substring(start, end).endsWith("" + endMarker); + // Done + return new Pair(start, end); + } + + private static int findEnclosingRegion2(String text, int offset, + char endMarker, int direction) { + while (offset > -1 && offset < text.length()) { + char c = text.charAt(offset); + if (c == endMarker) + return offset; + offset += direction; + } + return -1; + } + + /** + * A convenience wrapper for + * {@link #findEnclosingRegion(String, int, char, char)} E.g. + findEnclosingRegion("text with a [region] inside", 15, '[', ']') .equals("[region]"); + + * + * @param text + * @param offset + * @param start + * @param end + * @return the smallest enclosed region (including start and end chars), or + * null if none. + */ + public static String findEnclosingText(String text, int offset, + char startMarker, char endMarker) { + Pair region = findEnclosingRegion(text, offset, startMarker, + endMarker); + if (region == null) + return null; + String s = text.substring(region.first, region.second); + return s; + } + + /** + * Format a block of text to use the given line-width. I.e. adjust the line + * breaks. Also known as hard line-wrapping. Paragraphs are + * recognised by a line of blank space between them (e.g. two returns). + *

+ * Note: a side-effect of this method is that it converts all line-breaks + * into the local system's line-breaks. E.g. on Windows, \n will become \r\n + * + * @param text + * The text to format + * @param lineWidth + * The number of columns in a line. Typically 78 or 80. + * @param respectLeadingCharacters + * Can be null. If set, the specified leading characters will be + * copied if the line is split. Use with " \t" to keep indented + * paragraphs properly indented. Use with "> \t" to also handle + * email-style quoting. Note that respected leading characters + * receive no special treatment when they are used inside a + * paragraph. + * @return A copy of text, formatted to the given line-width. + *

+ * TODO: recognise paragraphs by changes in the respected leading + * characters + */ + public static String format(String text, int lineWidth, int tabWidth, + String respectLeadingCharacters) { + // Switch to Linux line breaks for easier internal workings + text = convertLineBreaks(text, "\n"); + // Find paragraphs + List paras = format2_splitParagraphs(text, + respectLeadingCharacters); + // Rebuild text + StringBuilder sb = new StringBuilder(text.length() + 10); + for (String p : paras) { + String fp = format3_oneParagraph(p, lineWidth, tabWidth, + respectLeadingCharacters); + sb.append(fp); + // Paragraphs end with a double line break + sb.append("\n\n"); + } + // Pop the last line breaks + sb.delete(sb.length() - 2, sb.length()); + // Convert line breaks to system ones + text = convertLineBreaks(sb.toString()); + // Done + return text; + } + + private static List format2_splitParagraphs(String text, + String respectLeadingCharacters) { + List paras = new ArrayList(); + Mutable.Int index = new Mutable.Int(0); + // TODO The characters prefacing this paragraph + String leadingChars = ""; + while (index.value < text.length()) { + // One paragraph + boolean inSpace = false; + int start = index.value; + while (index.value < text.length()) { + char c = text.charAt(index.value); + index.value++; + if (!Character.isWhitespace(c)) { + inSpace = false; + continue; + } + // Line end? + if (c == '\r' || c == '\n') { + // // Handle MS Windows 2 character \r\n line breaks + // if (index.value < text.length()) { + // char c2 = text.charAt(index.value); + // if (c=='\r' && c2=='\n') index.value++; // Push on past + // the 2nd line break char + // } + // Double line end - indicating a paragraph break + if (inSpace) + break; + inSpace = true; + } + // TODO Other paragraph markers, spotted by a change in + // leadingChars + } + String p = text.substring(start, index.value); + paras.add(p); + } + // Done + return paras; + } + + /** + * Format a block of text to fit the given line width + * + * @param p + * @param lineWidth + * @param tabWidth + * @param respectLeadingCharacters + * @return + */ + private static String format3_oneParagraph(String p, int lineWidth, + int tabWidth, String respectLeadingCharacters) { + // Collect the reformatted paragraph + StringBuilder sb = new StringBuilder(p.length() + 10); // Allow for + // some extra + // line-breaks + // Get respected leading chars + String leadingChars = format4_getLeadingChars(p, + respectLeadingCharacters); + // First Line + sb.append(leadingChars); + int lineLength = leadingChars.length(); + int index = leadingChars.length(); + // Loop + while (index < p.length()) { + // Get the next word + StringBuilder word = new StringBuilder(); + char c = p.charAt(index); + index++; + while (!Character.isWhitespace(c)) { + word.append(c); + if (index == p.length()) + break; + c = p.charAt(index); + index++; + } + // Break the line if the word will not fit + if (lineLength + word.length() > lineWidth && lineLength != 0) { + trimEnd(sb); + sb.append('\n'); // lineEnd(sb); + // New line + sb.append(leadingChars); + lineLength = leadingChars.length(); + } + // Add word + sb.append(word); + lineLength += word.length(); + // Add the whitespace + if (index != p.length() && lineLength < lineWidth) { + if (c == '\n') { + c = ' '; + } + sb.append(c); + lineLength += (c == '\t') ? tabWidth : 1; + } + } + // A final trim + trimEnd(sb); + // Done + return sb.toString(); + } + + /** + * + * @param text + * @param respectLeadingCharacters + * Can be null + * @return The characters at the beginning of text which are respected. E.g. + * ("> Hello", " \t>") --> "> " + */ + private static String format4_getLeadingChars(String text, + String respectLeadingCharacters) { + if (respectLeadingCharacters == null) + return ""; + // Line-breaks cannot be respected + assert respectLeadingCharacters.indexOf('\n') == -1; + // Look for the first non-respected char + for (int i = 0; i < text.length(); i++) { + char c = text.charAt(i); + if (respectLeadingCharacters.indexOf(c) == -1) { + // Return the previous chars + return text.substring(0, i); + } + } + // All chars are respected + return text; + } + + /** + * Ensure that line ends with the right line-end character(s) + */ + public static final String lineEnd(String line) { + // strip possibly inappropriate line-endings + if (line.endsWith("\n")) { + line = line.substring(0, line.length() - 1); + } + if (line.endsWith("\r\n")) { + line = line.substring(0, line.length() - 2); + } + if (line.endsWith("\r")) { + line = line.substring(0, line.length() - 1); + } + // add in proper line end + if (!line.endsWith(LINEEND)) { + line += LINEEND; + } + return line; + } + + /** + * Ensure that line ends with the right line-end character(s). This is more + * efficient than the version for Strings. + * + * @param line + */ + public static final void lineEnd(final StringBuilder line) { + if (line.length() == 0) { + line.append(LINEEND); + return; + } + // strip possibly inappropriate line-endings + final char last = line.charAt(line.length() - 1); + if (last == '\n') { + if ((line.length() > 1) && (line.charAt(line.length() - 2) == '\r')) { + // \r\n + line.replace(line.length() - 2, line.length(), LINEEND); + return; + } + line.replace(line.length() - 1, line.length(), LINEEND); + return; + } + if (last == '\r') { + line.replace(line.length() - 1, line.length(), LINEEND); + return; + } + line.append(LINEEND); + return; + } + + + + /** + * @param string + * @return the MD5 sum of the string using the default charset. Null if + * there was an error in calculating the hash. + * @author Sam Halliday + */ + public static String md5Hash(String string) { + MessageDigest md5 = null; + try { + md5 = MessageDigest.getInstance("MD5"); + } catch (NoSuchAlgorithmException e) { + // ignore this exception, we know MD5 exists + } + md5.update(string.getBytes()); + BigInteger hash = new BigInteger(1, md5.digest()); + return hash.toString(16); + } + + /** + * Removes HTML-style tags from a string. + * + * @param s + * a String from which to remove tags + * @return a string with all instances of <.*> removed. + */ + public static String removeTags(String s) { + StringBuffer sb = new StringBuffer(); + boolean inTag = false; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c == '<') + inTag = true; + if (!inTag) + sb.append(c); + if (c == '>') + inTag = false; + } + return sb.toString(); + } + + /** + * Repeat a character. + * + * @param c + * @param i + * @return A String consisting of i x c. + * @example assert repeat('-', 5).equals("-----"); + */ + public static String repeat(Character c, int i) { + StringBuilder dashes = new StringBuilder(i); + for (int j = 0; j < i; j++) + dashes.append(c); + return dashes.toString(); + } + + /** + * Split a piece of text into separate lines. The line breaks are left at + * the end of each line. + * + * @param text + * @return The individual lines in the text. + */ + public static List splitLines(String text) { + List lines = new ArrayList(); + // Search for lines + int start = 0; + for (int i = 0; i < text.length(); i++) { + char c = text.charAt(i); + if (c == '\r' || c == '\n') { + // Handle MS Windows 2 character \r\n line breaks + if (i + 1 < text.length()) { + char c2 = text.charAt(i + 1); + if (c == '\r' && c2 == '\n') + i++; + } + // Get the line, with the line break + String line = text.substring(start, i + 1); + lines.add(line); + start = i + 1; + } + } + // Last one + if (start != text.length()) { + String line = text.substring(start); + lines.add(line); + } + return lines; + } + + /** + * Remove trailing whitespace. c.f. String#trim() which removes + * leading and trailing whitespace. + * + * @param sb + */ + private static void trimEnd(StringBuilder sb) { + while (true) { + // Get the last character + int i = sb.length() - 1; + if (i == -1) + return; // Quit if sb is empty + char c = sb.charAt(i); + if (!Character.isWhitespace(c)) + return; // Finish? + sb.deleteCharAt(i); // Remove and continue + } + } + + /** + * Returns true if the string is just whitespace, or empty, or null. + * + * @param s + */ + public static final boolean whitespace(final String s) { + if (s == null) { + return true; + } + for (int i = 0; i < s.length(); i++) { + final char c = s.charAt(i); + if (!Character.isWhitespace(c)) { + return false; + } + } + return true; + } + + /** + * @param text + * @return the number of words in text. Uses a crude whitespace + * measure. + */ + public static int wordCount(String text) { + String[] bits = text.split("\\W+"); + int wc = 0; + for (String string : bits) { + if (!whitespace(string)) wc++; + } + return wc; + } + +} diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/commands/OpenGfmView.java b/bundles/winterwell.markdown/src/winterwell/markdown/commands/OpenGfmView.java new file mode 100644 index 000000000..80dc8eb10 --- /dev/null +++ b/bundles/winterwell.markdown/src/winterwell/markdown/commands/OpenGfmView.java @@ -0,0 +1,41 @@ +package winterwell.markdown.commands; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; + +import winterwell.markdown.LogUtil; + +public class OpenGfmView extends AbstractHandler { + + @Override + public Object execute(final ExecutionEvent event) throws ExecutionException { + try { + IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + String gfmViewId = "code.satyagraha.gfm.viewer.views.GfmView"; + IViewPart gfmView = activePage.showView(gfmViewId); + activePage.activate(gfmView); + } catch (PartInitException e) { + showError(e); + } catch (Exception e) { + showError(e); + } + return null; + } + + private void showError(Exception e) { + String title = "Exception while opening GitHub Flavored Markdown View"; + String message = title+" (code.satyagraha.gfm.viewer.views.GfmView)" + +"\nCheck Error Log View and continue at https://github.com/winterstein/Eclipse-Markdown-Editor-Plugin/issues/42" + +"\n\nYou can also right-click file in Project Explorer" + +"\n and select \"Show in GFM view\"."; + LogUtil.error(message, e); + MessageDialog.openError(Display.getDefault().getActiveShell(), title , message); + } +} diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/commands/OpenMdView.java b/bundles/winterwell.markdown/src/winterwell/markdown/commands/OpenMdView.java new file mode 100644 index 000000000..f36d7bd57 --- /dev/null +++ b/bundles/winterwell.markdown/src/winterwell/markdown/commands/OpenMdView.java @@ -0,0 +1,39 @@ +package winterwell.markdown.commands; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.handlers.HandlerUtil; + +import winterwell.markdown.LogUtil; + +public class OpenMdView extends AbstractHandler { + + @Override + public Object execute(final ExecutionEvent event) throws ExecutionException { + try { + IWorkbenchPage activePage = HandlerUtil.getActiveWorkbenchWindow(event).getActivePage(); + String mdViewId = "winterwell.markdown.views.MarkdownPreview"; + IViewPart mdView = activePage.showView(mdViewId); + activePage.activate(mdView); + } catch (PartInitException e) { + showError(e); + } catch (Exception e) { + showError(e); + } + return null; + } + + private void showError(Exception e) { + String title = "Exception while opening Markdown View"; + String message = title+" (winterwell.markdown.views.MarkdownPreview)" + +"\nCheck Error Log View"; + LogUtil.error(message, e); + MessageDialog.openError(Display.getDefault().getActiveShell(), title , message); + } +} diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/commands/Preferences.java b/bundles/winterwell.markdown/src/winterwell/markdown/commands/Preferences.java new file mode 100644 index 000000000..5c813a2d1 --- /dev/null +++ b/bundles/winterwell.markdown/src/winterwell/markdown/commands/Preferences.java @@ -0,0 +1,20 @@ +package winterwell.markdown.commands; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.preference.PreferenceDialog; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.dialogs.PreferencesUtil; + +public class Preferences extends AbstractHandler { + + @Override + public Object execute(final ExecutionEvent event) throws ExecutionException { + PreferenceDialog pref = PreferencesUtil.createPreferenceDialogOn( + PlatformUI.getWorkbench().getDisplay().getActiveShell(), + "winterwell.markdown.preferences.MarkdownPreferencePage", null, null); + pref.open(); + return null; + } +} diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/ActionBarContributor.java b/bundles/winterwell.markdown/src/winterwell/markdown/editors/ActionBarContributor.java new file mode 100644 index 000000000..e41793f44 --- /dev/null +++ b/bundles/winterwell.markdown/src/winterwell/markdown/editors/ActionBarContributor.java @@ -0,0 +1,49 @@ +package winterwell.markdown.editors; + +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.editors.text.TextEditorActionContributor; + +import winterwell.markdown.views.MarkdownPreview; + +public class ActionBarContributor extends TextEditorActionContributor { + + private static IEditorPart activeEditor = null; + +// IAction print = new PrintAction(); + + public void setActiveEditor(IEditorPart targetEditor) { + super.setActiveEditor(targetEditor); + activeEditor = targetEditor; + // add print action + IActionBars bars= getActionBars(); + if (bars != null) { +// todo bars.setGlobalActionHandler(ActionFactory.PRINT.getId(), print); +// bars.updateActionBars(); + } + // Update preview? + if (MarkdownPreview.preview != null) { + MarkdownPreview.preview.update(); + } + } + public static IEditorPart getActiveEditor() { + return activeEditor; + } + + @Override + public void contributeToMenu(IMenuManager menu) { + super.contributeToMenu(menu); + // Add format action + IMenuManager edit = menu.findMenuUsingPath("edit"); + if (edit != null) { + edit.add(new FormatAction()); + } + // Add Export action + IMenuManager file = menu.findMenuUsingPath("file"); + if (file != null) { + file.appendToGroup("import.ext", new ExportHTMLAction()); + } + } + +} diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/ColorManager.java b/bundles/winterwell.markdown/src/winterwell/markdown/editors/ColorManager.java new file mode 100644 index 000000000..ff5728a0c --- /dev/null +++ b/bundles/winterwell.markdown/src/winterwell/markdown/editors/ColorManager.java @@ -0,0 +1,28 @@ +package winterwell.markdown.editors; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; + +public class ColorManager { + + protected Map fColorTable = new HashMap(10); + + public void dispose() { + Iterator e = fColorTable.values().iterator(); + while (e.hasNext()) + ((Color) e.next()).dispose(); + } + public Color getColor(RGB rgb) { + Color color = (Color) fColorTable.get(rgb); + if (color == null) { + color = new Color(Display.getCurrent(), rgb); + fColorTable.put(rgb, color); + } + return color; + } +} diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/EmphasisRule.java b/bundles/winterwell.markdown/src/winterwell/markdown/editors/EmphasisRule.java new file mode 100644 index 000000000..06f14201d --- /dev/null +++ b/bundles/winterwell.markdown/src/winterwell/markdown/editors/EmphasisRule.java @@ -0,0 +1,112 @@ +/** + * Copyright winterwell Mathematics Ltd. + * @author Daniel Winterstein + * 11 Jan 2007 + */ +package winterwell.markdown.editors; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.text.rules.ICharacterScanner; +import org.eclipse.jface.text.rules.IRule; +import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.MultiLineRule; +import org.eclipse.jface.text.rules.Token; + +/** + * + * + * @author Daniel Winterstein + */ +public class EmphasisRule implements IRule { + private static char[][] fDelimiters = null; + private char[] fSequence; + protected IToken fToken; + + + public EmphasisRule(String marker, IToken token) { + assert marker.equals("*") || marker.equals("_") || marker.equals("**") + || marker.equals("***") || marker.equals("`") || marker.equals("``"); + Assert.isNotNull(token); + fSequence = marker.toCharArray(); + fToken = token; + } + + // Copied from org.eclipse.jface.text.rules.PatternRule + protected boolean sequenceDetected(ICharacterScanner scanner, char[] sequence, boolean eofAllowed) { + for (int i = 1; i < sequence.length; i++) { + int c = scanner.read(); + if (c == ICharacterScanner.EOF && eofAllowed) { + return true; + } else if (c != sequence[i]) { + // Non-matching character detected, rewind the scanner back to + // the start. + // Do not unread the first character. + for (int j = i; j > 0; j--) + scanner.unread(); + return false; + } + } + return true; + } + + /* + * @see IRule#evaluate(ICharacterScanner) + * + * @since 2.0 + */ + public IToken evaluate(ICharacterScanner scanner) { + // Should be connected only on the right side + scanner.unread(); + boolean sawSpaceBefore = Character.isWhitespace(scanner.read()); + if (!sawSpaceBefore && scanner.getColumn() != 0) { + return Token.UNDEFINED; + } + + int c = scanner.read(); + // Should be connected only on right side + if (c != fSequence[0] || !sequenceDetected(scanner, fSequence, false)) { + scanner.unread(); + return Token.UNDEFINED; + } + int readCount = fSequence.length; + if (fDelimiters == null) { + fDelimiters = scanner.getLegalLineDelimiters(); + } + // Start sequence detected + int delimiterFound = 0; + // Is it a list item marker, or just a floating *? + if (sawSpaceBefore) { + boolean after = Character.isWhitespace(scanner.read()); + scanner.unread(); + if (after) + delimiterFound = 2; + } + + while (delimiterFound < 2 + && (c = scanner.read()) != ICharacterScanner.EOF) { + readCount++; + + if (!sawSpaceBefore && c == fSequence[0] + && sequenceDetected(scanner, fSequence, false)) { + return fToken; + } + + int i; + for (i = 0; i < fDelimiters.length; i++) { + if (c == fDelimiters[i][0] + && sequenceDetected(scanner, fDelimiters[i], true)) { + delimiterFound++; + break; + } + } + if (i == fDelimiters.length) + delimiterFound = 0; + sawSpaceBefore = Character.isWhitespace(c); + } + // Reached ICharacterScanner.EOF + for (; readCount > 0; readCount--) + scanner.unread(); + return Token.UNDEFINED; + } + +} diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/ExportHTMLAction.java b/bundles/winterwell.markdown/src/winterwell/markdown/editors/ExportHTMLAction.java new file mode 100644 index 000000000..3c9d26e87 --- /dev/null +++ b/bundles/winterwell.markdown/src/winterwell/markdown/editors/ExportHTMLAction.java @@ -0,0 +1,37 @@ +package winterwell.markdown.editors; + +import java.io.File; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.jface.action.Action; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IPathEditorInput; + +import winterwell.utils.io.FileUtils; + + +public class ExportHTMLAction extends Action { + public ExportHTMLAction() { + super("Export to HTML"); + } + @Override + public void run() { + IEditorPart ed = ActionBarContributor.getActiveEditor(); + if (!(ed instanceof MarkdownEditor)) { + return; + } + MarkdownEditor editor = (MarkdownEditor) ed; + IEditorInput i = editor.getEditorInput(); + if (i instanceof IPathEditorInput) { + IPathEditorInput input = (IPathEditorInput) i; + IPath path = input.getPath(); + path = path.removeFileExtension(); + path = path.addFileExtension("html"); + File file = path.toFile(); + String html = editor.getMarkdownPage().html(); + FileUtils.write(file, html); + } + } + +} diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/FormatAction.java b/bundles/winterwell.markdown/src/winterwell/markdown/editors/FormatAction.java new file mode 100644 index 000000000..cd165892d --- /dev/null +++ b/bundles/winterwell.markdown/src/winterwell/markdown/editors/FormatAction.java @@ -0,0 +1,190 @@ +package winterwell.markdown.editors; + +import java.util.List; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; +import org.eclipse.core.commands.IHandlerListener; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.source.ISourceViewer; + +import winterwell.markdown.pagemodel.MarkdownFormatter; +import winterwell.markdown.pagemodel.MarkdownPage; +import winterwell.markdown.pagemodel.MarkdownPage.KLineType; +import winterwell.utils.containers.IntRange; + +/** + * TODO An action for formatting text (via hard wrapping, i.e. inserting returns). + * + * + * @author daniel + */ +public class FormatAction extends Action implements IHandler { + + public FormatAction() { + super("&Format paragraph"); + setActionDefinitionId("winterwell.markdown.formatParagraphCommand"); + setToolTipText("Format the paragraph under the caret by inserting/removing line-breaks"); + } + + @Override + public void run() { + try { + MarkdownEditor ed = (MarkdownEditor) ActionBarContributor.getActiveEditor(); + if (ed == null) return; // The active editor is not a markdown editor. + int cols = ed.getPrintColumns(); + // Do we have a selection? + ITextSelection s = (ITextSelection) ed.getSelectionProvider().getSelection(); + if (s != null && s.getLength() > 0) { + formatSelectedRegion(ed, s, cols); + return; + } + // Where is the caret? + ISourceViewer viewer = ed.getViewer(); + int caretOffset = viewer.getTextWidget().getCaretOffset(); + int lineNum = ed.getDocument().getLineOfOffset(caretOffset); + // Get a paragraph region + MarkdownPage page = ed.getMarkdownPage(); + IRegion pRegion = getParagraph(page, lineNum, ed.getDocument()); + if (pRegion==null) { + // Not in a paragraph - so give up + // TODO tell the user why we've given up + return; + } + String paragraph = ed.getDocument().get(pRegion.getOffset(), pRegion.getLength()); + // Format + String formatted = MarkdownFormatter.format(paragraph, cols); + if (formatted.equals(paragraph)) return; // No change! + // Replace the unformatted region with the new formatted one + ed.getDocument().replace(pRegion.getOffset(), pRegion.getLength(), formatted); + // Done + } catch (Exception ex) { + System.out.println(ex); + } + } + + private void formatSelectedRegion(MarkdownEditor ed, ITextSelection s, int cols) + throws BadLocationException { + int start = s.getStartLine(); + int end = s.getEndLine(); + IDocument doc = ed.getDocument(); + int soff = doc.getLineOffset(start); + int eoff = lineEndOffset(end, doc); + IntRange editedRegion = new IntRange(soff, eoff); + MarkdownPage page = ed.getMarkdownPage(); + StringBuilder sb = new StringBuilder(s.getLength()); + for(int i=start; i<=end; i++) { + IRegion para = getParagraph(page, i, ed.getDocument()); + if (para==null) { + sb.append(page.getText().get(i)); + continue; + } + String paragraph = ed.getDocument().get(para.getOffset(), para.getLength()); +// int lines = StrUtils.splitLines(paragraph).length; + String formatted = MarkdownFormatter.format(paragraph, cols); + // append formatted and move forward + sb.append(formatted); + CharSequence le = lineEnd(i, doc); + sb.append(le); + int pEnd = doc.getLineOfOffset(para.getOffset()+para.getLength()); + i = pEnd; + // Adjust edited region? + IntRange pr = new IntRange(para.getOffset(), + para.getOffset()+para.getLength()+le.length()); + editedRegion = new IntRange(Math.min(pr.low, editedRegion.low), + Math.max(pr.high, editedRegion.high)); + } + // Replace the unformatted region with the new formatted one + String old = doc.get(editedRegion.low, editedRegion.size()); + String newText = sb.toString(); + if (old.equals(newText)) return; + ed.getDocument().replace(editedRegion.low, editedRegion.size(), newText); + } + + private CharSequence lineEnd(int line, IDocument doc) throws BadLocationException { + int eoff = doc.getLineOffset(line) + doc.getLineInformation(line).getLength(); + char c = doc.getChar(eoff); + if (c=='\r' && doc.getLength() > eoff+1 + && doc.getChar(eoff+1) =='\n') return "\r\n"; + return ""+c; + } + + private int lineEndOffset(int end, IDocument doc) + throws BadLocationException { + int eoff = doc.getLineOffset(end) + doc.getLineInformation(end).getLength(); + // Include line end + char c = doc.getChar(eoff); + if (c=='\r' && doc.getLength() > eoff+1 + && doc.getChar(eoff+1) =='\n') eoff += 2; + else eoff += 1; + return eoff; + } + + /** + * + * @param page + * @param lineNum + * @param doc + * @return region of paragraph containing this line, or null + * @throws BadLocationException + */ + private IRegion getParagraph(MarkdownPage page, int lineNum, IDocument doc) + throws BadLocationException { + // Get doc info + List lines = page.getText(); + List lineInfo = page.getLineTypes(); + // Check we are in a paragraph or list + KLineType pType = lineInfo.get(lineNum); + switch(pType) { + case NORMAL: break; + default: // Not in a paragraph, so we cannot format. + return null; + } + // Work out the paragraph + // Beginning + int start; + for(start=lineNum; start>-1; start--) { + if (lineInfo.get(start) != pType) { + start++; + break; + } + } + // End + int end; + for(end=lineNum; end 0; j--) + scanner.unread(); + return false; + } + } + return true; + } + + /* + * @see IRule#evaluate(ICharacterScanner) + * @since 2.0 + */ + public IToken evaluate(ICharacterScanner scanner) { + int c; + if ((c = scanner.read()) != '[') { + if ((c != 'h' || ( !sequenceDetected(scanner, "http://".toCharArray(), false) && !sequenceDetected(scanner, "https://".toCharArray(), false) )) + && (c != 'f' || !sequenceDetected(scanner, "ftp://".toCharArray(), false)) ) { + // Not even a non-standard link + scanner.unread(); + return Token.UNDEFINED; + } + + //+ preventing NPE (Non-standard link should not be below as comment above suggests) by Paul Verest + if (fDelimiters == null) { + scanner.unread(); + return Token.UNDEFINED; + } + + // Non-standard link + while ((c = scanner.read()) != ICharacterScanner.EOF && !Character.isWhitespace(c)) { + for (int i = 0; i < fDelimiters.length; i++) { + if (c == fDelimiters[i][0] && sequenceDetected(scanner, fDelimiters[i], true)) { + return fToken; + } + } + } + return fToken; + } + if (fDelimiters == null) { + fDelimiters = scanner.getLegalLineDelimiters(); + } + int readCount = 1; + + // Find '](' and then find ')' + boolean sequenceFound = false; + int delimiterFound = 0; + while ((c = scanner.read()) != ICharacterScanner.EOF && delimiterFound < 2) { + readCount++; + if ( !sequenceFound && c == ']') { + c = scanner.read(); + if (c == '(') { + readCount++; + sequenceFound = true; + } else { + scanner.unread(); + } + } else if (c == ')') { // '](' is already found + return fToken; + } + + int i; + for (i = 0; i < fDelimiters.length; i++) { + if (c == fDelimiters[i][0] && sequenceDetected(scanner, fDelimiters[i], true)) { + delimiterFound ++; + break; + } + } + if (i == fDelimiters.length) + delimiterFound = 0; + } + + for (; readCount > 0; readCount--) + scanner.unread(); + return Token.UNDEFINED; + } + +} diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/ListRule.java b/bundles/winterwell.markdown/src/winterwell/markdown/editors/ListRule.java new file mode 100644 index 000000000..11ff3f052 --- /dev/null +++ b/bundles/winterwell.markdown/src/winterwell/markdown/editors/ListRule.java @@ -0,0 +1,77 @@ +/** + * Copyright winterwell Mathematics Ltd. + * @author Daniel Winterstein + * 11 Jan 2007 + */ +package winterwell.markdown.editors; + +import java.util.ArrayList; +import java.util.List; +import java.util.Arrays; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.text.rules.ICharacterScanner; +import org.eclipse.jface.text.rules.IRule; +import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.Token; + +/** + * + * + * @author Daniel Winterstein + */ +public class ListRule implements IRule { + private ArrayList markerList; + protected IToken fToken; + + public ListRule(IToken token) { + Assert.isNotNull(token); + fToken= token; + } + + + /* + * @see IRule#evaluate(ICharacterScanner) + * @since 2.0 + */ + public IToken evaluate(ICharacterScanner scanner) { + if (scanner.getColumn() != 0) { + return Token.UNDEFINED; + } +// // Fast mode +// if (scanner.read() != '-') { +// scanner.unread(); +// return Token.UNDEFINED; +// } +// if (Character.isWhitespace(scanner.read())) { +// return fToken; +// } +// scanner.unread(); +// scanner.unread(); +// return Token.UNDEFINED; +// // Fast mode + int readCount = 0; + int c; + while ((c = scanner.read()) != ICharacterScanner.EOF) { + readCount++; + if( !Character.isWhitespace( c ) ) { + int after = scanner.read(); +// readCount++; + scanner.unread(); +// if ( markerList.contains(c) && Character.isWhitespace( after ) ) { + if ( (c == '-' || c == '+' || c == '*') + && Character.isWhitespace( after ) ) { + return fToken; + } else { + for (; readCount > 0; readCount--) + scanner.unread(); + return Token.UNDEFINED; + } + } + } + // Reached ICharacterScanner.EOF + for (; readCount > 0; readCount--) + scanner.unread(); + return Token.UNDEFINED; + } +} diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/MDColorConstants.java b/bundles/winterwell.markdown/src/winterwell/markdown/editors/MDColorConstants.java new file mode 100644 index 000000000..7197f3179 --- /dev/null +++ b/bundles/winterwell.markdown/src/winterwell/markdown/editors/MDColorConstants.java @@ -0,0 +1,9 @@ +package winterwell.markdown.editors; + +import org.eclipse.swt.graphics.RGB; + +public interface MDColorConstants { + RGB COMMENT = new RGB(128, 0, 0); + RGB HEADER = new RGB(0, 0, 128); + RGB DEFAULT = new RGB(0, 0, 0); +} diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/MDConfiguration.java b/bundles/winterwell.markdown/src/winterwell/markdown/editors/MDConfiguration.java new file mode 100644 index 000000000..f20a64277 --- /dev/null +++ b/bundles/winterwell.markdown/src/winterwell/markdown/editors/MDConfiguration.java @@ -0,0 +1,81 @@ +package winterwell.markdown.editors; + +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextHover; +import org.eclipse.jface.text.presentation.IPresentationReconciler; +import org.eclipse.jface.text.presentation.PresentationReconciler; +import org.eclipse.jface.text.reconciler.DirtyRegion; +import org.eclipse.jface.text.reconciler.IReconciler; +import org.eclipse.jface.text.reconciler.IReconcilingStrategy; +import org.eclipse.jface.text.reconciler.MonoReconciler; +import org.eclipse.jface.text.rules.DefaultDamagerRepairer; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.ui.editors.text.TextSourceViewerConfiguration; + +public class MDConfiguration extends TextSourceViewerConfiguration { + private ColorManager colorManager; + + public MDConfiguration(ColorManager colorManager, IPreferenceStore prefStore) { + super(prefStore); + this.colorManager = colorManager; + } + + @Override + public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) { + MDScanner scanner = new MDScanner(colorManager); + PresentationReconciler pr = (PresentationReconciler) super.getPresentationReconciler(sourceViewer); // FIXME + DefaultDamagerRepairer ddr = new DefaultDamagerRepairer(scanner); + pr.setRepairer(ddr, IDocument.DEFAULT_CONTENT_TYPE); + pr.setDamager(ddr, IDocument.DEFAULT_CONTENT_TYPE); + return pr; + } + + + @Override + public IReconciler getReconciler(ISourceViewer sourceViewer) { + // This awful mess adds in update support + // Get super strategy + IReconciler rs = super.getReconciler(sourceViewer); + if (true) return rs; // Seems to work fine?! + final IReconcilingStrategy fsuperStrategy = rs==null? null : rs.getReconcilingStrategy("text"); + // Add our own + IReconcilingStrategy strategy = new IReconcilingStrategy() { + private IDocument doc; + public void reconcile(IRegion partition) { + MarkdownEditor ed = MarkdownEditor.getEditor(doc); + if (ed != null) ed.updatePage(partition); + if (fsuperStrategy!=null) fsuperStrategy.reconcile(partition); + } + public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) { + MarkdownEditor ed = MarkdownEditor.getEditor(doc); + if (ed != null) ed.updatePage(subRegion); + if (fsuperStrategy!=null) fsuperStrategy.reconcile(dirtyRegion, subRegion); + } + public void setDocument(IDocument document) { + this.doc = document; + if (fsuperStrategy!=null) fsuperStrategy.setDocument(document); + } + }; + // Make a reconciler + MonoReconciler m2 = new MonoReconciler(strategy, true); + m2.setIsIncrementalReconciler(true); + m2.setProgressMonitor(new NullProgressMonitor()); + m2.setDelay(500); + // Done + return m2; + } + + @SuppressWarnings("unused") + @Override + public ITextHover getTextHover(ISourceViewer sourceViewer, + String contentType) { + if (true) return super.getTextHover(sourceViewer, contentType); + // Add hover support for images + return new MDTextHover(); + } +} + + diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/MDScanner.java b/bundles/winterwell.markdown/src/winterwell/markdown/editors/MDScanner.java new file mode 100644 index 000000000..60a307b78 --- /dev/null +++ b/bundles/winterwell.markdown/src/winterwell/markdown/editors/MDScanner.java @@ -0,0 +1,61 @@ +/** + * Copyright winterwell Mathematics Ltd. + * @author Daniel Winterstein + * 13 Jan 2007 + */ +package winterwell.markdown.editors; + +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.PreferenceConverter; +import org.eclipse.jface.text.TextAttribute; +import org.eclipse.jface.text.rules.IRule; +import org.eclipse.jface.text.rules.IWhitespaceDetector; +import org.eclipse.jface.text.rules.MultiLineRule; +import org.eclipse.jface.text.rules.RuleBasedScanner; +import org.eclipse.jface.text.rules.Token; +import org.eclipse.jface.text.rules.WhitespaceRule; +import org.eclipse.swt.SWT; + +import winterwell.markdown.Activator; +import winterwell.markdown.preferences.MarkdownPreferencePage; + +/** + * + * + * @author Daniel Winterstein + */ +public class MDScanner extends RuleBasedScanner { + ColorManager cm; + public MDScanner(ColorManager cm) { + this.cm = cm; + IPreferenceStore pStore = Activator.getDefault().getPreferenceStore(); + Token heading = new Token(new TextAttribute(cm.getColor(PreferenceConverter.getColor(pStore, MarkdownPreferencePage.PREF_HEADER)), null, SWT.BOLD)); + Token comment = new Token(new TextAttribute(cm.getColor(PreferenceConverter.getColor(pStore, MarkdownPreferencePage.PREF_COMMENT)))); + Token emphasis = new Token(new TextAttribute(cm.getColor(PreferenceConverter.getColor(pStore, MarkdownPreferencePage.PREF_DEFUALT)), null, SWT.ITALIC)); + Token list = new Token(new TextAttribute(cm.getColor(PreferenceConverter.getColor(pStore, MarkdownPreferencePage.PREF_HEADER)), null, SWT.BOLD)); + Token link = new Token(new TextAttribute(cm.getColor(PreferenceConverter.getColor(pStore, MarkdownPreferencePage.PREF_LINK)), null, TextAttribute.UNDERLINE)); + Token code = new Token(new TextAttribute( + cm.getColor(PreferenceConverter.getColor(pStore, MarkdownPreferencePage.PREF_CODE)), + cm.getColor(PreferenceConverter.getColor(pStore, MarkdownPreferencePage.PREF_CODE_BG)), + SWT.NORMAL)); + setRules(new IRule[] { + new LinkRule(link), + new HeaderRule(heading), + new HeaderWithUnderlineRule(heading), + new ListRule(list), + new EmphasisRule("_", emphasis), + new EmphasisRule("***", emphasis), + new EmphasisRule("**", emphasis), + new EmphasisRule("*", emphasis), + new EmphasisRule("``", code), + new EmphasisRule("`", code), + new MultiLineRule("", comment), + // WhitespaceRule messes up with the rest of rules +// new WhitespaceRule(new IWhitespaceDetector() { +// public boolean isWhitespace(char c) { +// return Character.isWhitespace(c); +// } +// }), + }); + } +} diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/MDTextHover.java b/bundles/winterwell.markdown/src/winterwell/markdown/editors/MDTextHover.java new file mode 100644 index 000000000..04377a622 --- /dev/null +++ b/bundles/winterwell.markdown/src/winterwell/markdown/editors/MDTextHover.java @@ -0,0 +1,81 @@ +/** + * (c) Winterwell 2010 and ThinkTank Mathematics 2007 + */ +package winterwell.markdown.editors; + +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextHover; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.Region; + +import winterwell.markdown.StringMethods; +import winterwell.utils.containers.Pair; + +/** + * + * + * @author daniel + */ +public class MDTextHover implements ITextHover //, ITextHoverExtension +{ + + /* (non-Javadoc) + * @see org.eclipse.jface.text.ITextHover#getHoverInfo(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion) + */ + public String getHoverInfo(ITextViewer textViewer, IRegion region) { + try { + IDocument doc = textViewer.getDocument(); + String text = doc.get(region.getOffset(), region.getLength()); + return ""+text+""; + } catch (Exception e) { + return null; + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.ITextHover#getHoverRegion(org.eclipse.jface.text.ITextViewer, int) + */ + public IRegion getHoverRegion(ITextViewer textViewer, int offset) { + try { + IDocument doc = textViewer.getDocument(); + int line = doc.getLineOfOffset(offset); + int lineOffset = doc.getLineOffset(line); + int lineLength = doc.getLineLength(line); + String text = doc.get(lineOffset, lineLength); + // Look for image tags + Pair altRegion; + Pair urlRegion = + StringMethods.findEnclosingRegion(text, offset-lineOffset, '(', ')'); + if (urlRegion==null) { + altRegion = StringMethods.findEnclosingRegion(text, offset-lineOffset, '[', ']'); + if (altRegion == null) return null; + urlRegion = StringMethods.findEnclosingRegion(text, altRegion.second, '(', ')'); + } else { + altRegion = StringMethods.findEnclosingRegion(text, urlRegion.first-1, '[', ']'); + } + if (urlRegion==null || altRegion==null) return null; + // Is it an image link? + if (text.charAt(altRegion.first-1) != '!') return null; + Region r = new Region(urlRegion.first+1+lineOffset, urlRegion.second-urlRegion.first-2); + return r; + } catch (Exception ex) { + return null; + } + } + +// public IInformationControlCreator getHoverControlCreator() { +// return new IInformationControlCreator() { +// public IInformationControl createInformationControl(Shell parent) { +// int style= fIsFocusable ? SWT.V_SCROLL | SWT.H_SCROLL : SWT.NONE; +// +// if (BrowserInformationControl.isAvailable(parent)) { +// final int shellStyle= SWT.TOOL | (fIsFocusable ? SWT.RESIZE : SWT.NO_TRIM); +// return new BrowserInformationControl(parent, shellStyle, style, null); +// } +// return new DefaultInformationControl(parent, style, new HTMLTextPresenter()); +// } +// }; +// } + +} diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/MarkdownContentOutlinePage.java b/bundles/winterwell.markdown/src/winterwell/markdown/editors/MarkdownContentOutlinePage.java new file mode 100644 index 000000000..445a322d3 --- /dev/null +++ b/bundles/winterwell.markdown/src/winterwell/markdown/editors/MarkdownContentOutlinePage.java @@ -0,0 +1,538 @@ +/** + * Copyright winterwell Mathematics Ltd. + * @author Daniel Winterstein + * 11 Jan 2007 + */ +package winterwell.markdown.editors; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.DocumentEvent; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IDocumentListener; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.part.IPageSite; +import org.eclipse.ui.texteditor.IDocumentProvider; +import org.eclipse.ui.views.contentoutline.ContentOutlinePage; + +import winterwell.markdown.pagemodel.MarkdownPage; +import winterwell.markdown.pagemodel.MarkdownPage.Header; +import winterwell.markdown.pagemodel.MarkdownPage.KLineType; +import winterwell.utils.StrUtils; +import winterwell.utils.Utils; +import winterwell.utils.web.WebUtils; + +/** + * + * + * @author Daniel Winterstein + */ +public final class MarkdownContentOutlinePage extends ContentOutlinePage { + + /** + * + * + * @author Daniel Winterstein + */ + public final class ContentProvider implements ITreeContentProvider, + IDocumentListener { + + // protected final static String SEGMENTS= "__md_segments"; + // //$NON-NLS-1$ + // protected IPositionUpdater fPositionUpdater= new + // DefaultPositionUpdater(SEGMENTS); + private MarkdownPage fContent; + // protected List fContent= new ArrayList(10); + private MarkdownEditor fTextEditor; + + private void parse() { + fContent = fTextEditor.getMarkdownPage(); + } + + /* + * @see IContentProvider#inputChanged(Viewer, Object, Object) + */ + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + // Detach from old + if (oldInput != null) { + IDocument document = fDocumentProvider.getDocument(oldInput); + if (document != null) { + document.removeDocumentListener(this); + } + } + fContent = null; + // Attach to new + if (newInput == null) + return; + IDocument document = fDocumentProvider.getDocument(newInput); + if (document == null) + return; + fTextEditor = MarkdownEditor.getEditor(document); + document.addDocumentListener(this); + parse(); + } + + /* + * @see IContentProvider#dispose + */ + public void dispose() { + fContent = null; + } + + /* + * @see IContentProvider#isDeleted(Object) + */ + public boolean isDeleted(Object element) { + return false; + } + + /* + * @see IStructuredContentProvider#getElements(Object) + */ + public Object[] getElements(Object element) { + return fContent.getHeadings(null).toArray(); + } + + /* + * @see ITreeContentProvider#hasChildren(Object) + */ + public boolean hasChildren(Object element) { + if (element == fInput) { + return true; + } + if (element instanceof MarkdownPage.Header) { + MarkdownPage.Header header = (MarkdownPage.Header) element; + return header.getSubHeaders().size() > 0; + } + ; + return false; + } + + /* + * @see ITreeContentProvider#getParent(Object) + */ + public Object getParent(Object element) { + if (!(element instanceof MarkdownPage.Header)) + return null; + return ((MarkdownPage.Header) element).getParent(); + } + + /* + * @see ITreeContentProvider#getChildren(Object) + */ + public Object[] getChildren(Object element) { + if (element == fInput) { + return fContent.getHeadings(null).toArray(); + } + if (!(element instanceof MarkdownPage.Header)) + return null; + return ((MarkdownPage.Header) element).getSubHeaders().toArray(); + } + + public void documentAboutToBeChanged(DocumentEvent event) { + // nothing + } + + public void documentChanged(DocumentEvent event) { + parse(); + update(); + } + } + + private Object fInput = null; + private final IDocumentProvider fDocumentProvider; + private final MarkdownEditor fTextEditor; + protected boolean showWordCounts; + private List

selectedHeaders; + + /** + * @param documentProvider + * @param mdEditor + */ + public MarkdownContentOutlinePage(IDocumentProvider documentProvider, + MarkdownEditor mdEditor) { + fDocumentProvider = documentProvider; + fTextEditor = mdEditor; + } + + /* + * (non-Javadoc) Method declared on ContentOutlinePage + */ + @Override + public void createControl(Composite parent) { + super.createControl(parent); + TreeViewer viewer = getTreeViewer(); + viewer.setContentProvider(new ContentProvider()); + // Add word count annotations + viewer.setLabelProvider(new LabelProvider() { + @Override + public String getText(Object element) { + if (!(element instanceof MarkdownPage.Header)) + return super.getText(element); + Header header = ((MarkdownPage.Header) element); + String hText = header.toString(); + if (!showWordCounts) + return hText; + IRegion region = getRegion(header); + String text; + try { + text = fTextEditor.getDocument().get(region.getOffset(), + region.getLength()); + text = WebUtils.stripTags(text); + text = text.replaceAll("#", "").trim(); + assert text.startsWith(hText); + text = text.substring(hText.length()); + int wc = StrUtils.wordCount(text); + return hText + " (" + wc + ":" + text.length() + ")"; + } catch (BadLocationException e) { + return hText; + } + } + }); + viewer.addSelectionChangedListener(this); + + if (fInput != null) + viewer.setInput(fInput); + + // Buttons + IPageSite site = getSite(); + IActionBars bars = site.getActionBars(); + IToolBarManager toolbar = bars.getToolBarManager(); + // Word count action + Action action = new Action("123", IAction.AS_CHECK_BOX) { + @Override + public void run() { + showWordCounts = isChecked(); + update(); + } + }; + action.setToolTipText("Show/hide section word:character counts"); + toolbar.add(action); + // +/- actions + action = new Action("<") { + @Override + public void run() { + doPromoteDemote(-1); + } + }; + action.setToolTipText("Promote the selected section\n -- move it up a level."); + toolbar.add(action); + // + action = new Action(">") { + @Override + public void run() { + doPromoteDemote(1); + } + }; + action.setToolTipText("Demote the selected section\n -- move it down a level."); + toolbar.add(action); + // up/down actions + action = new Action("/\\") { + @Override + public void run() { + try { + doMove(-1); + } catch (BadLocationException e) { + throw Utils.runtime(e); + } + } + }; + action.setToolTipText("Move the selected section earlier"); + toolbar.add(action); + // + action = new Action("\\/") { + @Override + public void run() { + try { + doMove(1); + } catch (BadLocationException e) { + throw Utils.runtime(e); + } + } + }; + action.setToolTipText("Move the selected section later"); + toolbar.add(action); + // Collapse + ImageDescriptor id = ImageDescriptor.createFromFile(getClass(), "collapseall.gif"); + action = new Action("collapse", id) { + @Override + public void run() { + doCollapseAll(); + } + }; + action.setImageDescriptor(id); + action.setToolTipText("Collapse outline tree"); + toolbar.add(action); + // Sync + id = ImageDescriptor.createFromFile(getClass(), "synced.gif"); + action = new Action("sync") { + @Override + public void run() { + try { + doSyncToEditor(); + } catch (BadLocationException e) { + throw Utils.runtime(e); + } + } + }; + action.setImageDescriptor(id); + action.setToolTipText("Link with editor"); + toolbar.add(action); + // Add edit ability + viewer.getControl().addKeyListener(new KeyListener() { + public void keyPressed(KeyEvent e) { + if (e.keyCode==SWT.F2) { + doEditHeader(); + } + } + public void keyReleased(KeyEvent e) { + // + } + }); + } + + /** + * @throws BadLocationException + * + */ + protected void doSyncToEditor() throws BadLocationException { + TreeViewer viewer = getTreeViewer(); + if (viewer == null) return; + // Get header + MarkdownPage page = fTextEditor.getMarkdownPage(); + int caretOffset = fTextEditor.getViewer().getTextWidget().getCaretOffset(); + IDocument doc = fTextEditor.getDocument(); + int line = doc.getLineOfOffset(caretOffset); + List lineTypes = page.getLineTypes(); + for(; line>-1; line--) { + KLineType lt = lineTypes.get(line); + if (lt.toString().startsWith("H")) break; + } + if (line<0) return; + Header header = (Header) page.getPageObject(line); + // Set + IStructuredSelection selection = new StructuredSelection(header); + viewer.setSelection(selection , true); + } + + void doEditHeader() { + TreeViewer viewer = getTreeViewer(); + viewer.editElement(selectedHeaders.get(0), 0); + } + + protected void doCollapseAll() { + TreeViewer viewer = getTreeViewer(); + if (viewer == null) return; +// Control control = viewer.getControl(); +// if (control != null && !control.isDisposed()) { +// control.setRedraw(false); + viewer.collapseAll(); +// control.setRedraw(true); +// } + } + + /** + * Move the selected sections up/down + * @param i 1 or -1. 1==move later, -1=earlier + * @throws BadLocationException + */ + protected void doMove(int i) throws BadLocationException { + assert i==1 || i==-1; + if (selectedHeaders == null || selectedHeaders.size() == 0) + return; + // Get text region to move + MarkdownPage.Header first = selectedHeaders.get(0); + MarkdownPage.Header last = selectedHeaders.get(selectedHeaders.size()-1); + int start = fTextEditor.getDocument().getLineOffset( + first.getLineNumber()); + IRegion r = getRegion(last); + int end = r.getOffset() + r.getLength(); + int length = end - start; + // Get new insertion point + int insert; + if (i==1) { + Header nextSection = last.getNext(); + if (nextSection==null) return; + IRegion nr = getRegion(nextSection); + insert = nr.getOffset()+nr.getLength(); + } else { + Header prevSection = first.getPrevious(); + if (prevSection==null) return; + IRegion nr = getRegion(prevSection); + insert = nr.getOffset(); + } + // Get text + String text = fTextEditor.getDocument().get(); + // Move text + String section = text.substring(start, end); + String pre, post; + if (i==1) { + pre = text.substring(0, start) + text.substring(end, insert); + post = text.substring(insert); + } else { + pre = text.substring(0, insert); + post = text.substring(insert,start)+text.substring(end); + } + text = pre + section + post; + assert text.length() == fTextEditor.getDocument().get().length() : + text.length()-fTextEditor.getDocument().get().length()+" chars gained/lost"; + // Update doc + fTextEditor.getDocument().set(text); + } + + /** + * Does not support -------- / ========= underlining, only # headers + * @param upDown 1 for demote (e.g. h2 -> h3), -1 for promote (e.g. h2 -> h1) + */ + protected void doPromoteDemote(int upDown) { + assert upDown==1 || upDown==-1; + if (selectedHeaders == null || selectedHeaders.size() == 0) + return; + HashSet
toAdjust = new HashSet
(selectedHeaders); + HashSet
adjusted = new HashSet
(); + // Adjust + MarkdownPage mdPage = fTextEditor.getMarkdownPage(); + List lines = new ArrayList(mdPage.getText()); + while(toAdjust.size() != 0) { + Header h = toAdjust.iterator().next(); + toAdjust.remove(h); + adjusted.add(h); + String line = lines.get(h.getLineNumber()); + if (upDown==-1) { + if (h.getLevel() == 1) return; // Level 1; can't promote + if (line.startsWith("##")) line = line.substring(1); + else { + return; // TODO support for ------ / ======== + } + } else line = "#" + line; + int ln = h.getLineNumber(); + lines.set(ln, line); + // kids + ArrayList
kids = new ArrayList
(h.getSubHeaders()); + for (Header header : kids) { + if ( ! adjusted.contains(header)) toAdjust.add(header); + } + } + // Set + StringBuilder sb = new StringBuilder(); + for (String line : lines) { + sb.append(line); + } + fTextEditor.getDocument().set(sb.toString()); + } + + /** + * The region of text for this header. This includes the header itself. + * @param header + * @return + * @throws BadLocationException + */ + protected IRegion getRegion(Header header) { + try { + IDocument doc = fTextEditor.getDocument(); + // Line numbers + int start = header.getLineNumber(); + Header next = header.getNext(); + int end; + if (next != null) { + end = next.getLineNumber() - 1; + } else { + end = doc.getNumberOfLines() - 1; + } + int offset = doc.getLineOffset(start); + IRegion ei = doc.getLineInformation(end); + int length = ei.getOffset() + ei.getLength() - offset; + return new Region(offset, length); + } catch (BadLocationException ex) { + throw Utils.runtime(ex); + } + } + + /* + * (non-Javadoc) Method declared on ContentOutlinePage + */ + @Override + public void selectionChanged(SelectionChangedEvent event) { + super.selectionChanged(event); + selectedHeaders = null; + ISelection selection = event.getSelection(); + if (selection.isEmpty()) + return; + if (!(selection instanceof IStructuredSelection)) + return; + try { + IStructuredSelection strucSel = (IStructuredSelection) selection; + Object[] sections = strucSel.toArray(); + selectedHeaders = (List) Arrays.asList(sections); + MarkdownPage.Header first = (Header) sections[0]; + MarkdownPage.Header last = (Header) sections[sections.length - 1]; + int start = fTextEditor.getDocument().getLineOffset( + first.getLineNumber()); + int length; + if (first == last) { + length = fTextEditor.getDocument().getLineLength( + first.getLineNumber()); + } else { + IRegion r = getRegion(last); + int end = r.getOffset() + r.getLength(); + length = end - start; + } + fTextEditor.setHighlightRange(start, length, true); + } catch (Exception x) { + System.out.println(x.getStackTrace()); + fTextEditor.resetHighlightRange(); + } + } + + /** + * Sets the input of the outline page + * + * @param input + * the input of this outline page + */ + public void setInput(Object input) { + fInput = input; + update(); + } + + /** + * Updates the outline page. + */ + public void update() { + TreeViewer viewer = getTreeViewer(); + + if (viewer != null) { + Control control = viewer.getControl(); + if (control != null && !control.isDisposed()) { + control.setRedraw(false); + viewer.setInput(fInput); + viewer.expandAll(); + control.setRedraw(true); + } + } + } + +} diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/MarkdownEditor.java b/bundles/winterwell.markdown/src/winterwell/markdown/editors/MarkdownEditor.java new file mode 100644 index 000000000..86699c4b3 --- /dev/null +++ b/bundles/winterwell.markdown/src/winterwell/markdown/editors/MarkdownEditor.java @@ -0,0 +1,455 @@ +package winterwell.markdown.editors; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.text.DocumentEvent; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IDocumentListener; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.text.source.IVerticalRuler; +import org.eclipse.jface.text.source.projection.ProjectionAnnotation; +import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel; +import org.eclipse.jface.text.source.projection.ProjectionSupport; +import org.eclipse.jface.text.source.projection.ProjectionViewer; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IPathEditorInput; +import org.eclipse.ui.editors.text.TextEditor; +import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants; +import org.eclipse.ui.texteditor.IDocumentProvider; +import org.eclipse.ui.texteditor.SourceViewerDecorationSupport; +import org.eclipse.ui.views.contentoutline.IContentOutlinePage; + +import winterwell.markdown.Activator; +import winterwell.markdown.pagemodel.MarkdownPage; +import winterwell.markdown.pagemodel.MarkdownPage.Header; +import winterwell.markdown.preferences.MarkdownPreferencePage; +import winterwell.markdown.views.MarkdownPreview; + + +/** + * Text editor with markdown support. + * @author Daniel Winterstein + */ +public class MarkdownEditor extends TextEditor implements IDocumentListener +{ + + /** + * Maximum length for a task tag message + */ + private static final int MAX_TASK_MSG_LENGTH = 80; + private ColorManager colorManager; + private MarkdownContentOutlinePage fOutlinePage = null; + + IDocument oldDoc = null; + + private MarkdownPage page; + + + private boolean pageDirty = true; + + private ProjectionSupport projectionSupport; + private final IPreferenceStore pStore; + private IPropertyChangeListener prefChangeListener; + + + public MarkdownEditor() { + super(); + pStore = Activator.getDefault().getPreferenceStore(); + colorManager = new ColorManager(); + setSourceViewerConfiguration(new MDConfiguration(colorManager, getPreferenceStore())); + } + + + @Override + public void createPartControl(Composite parent) { + // Over-ride to add code-folding support + super.createPartControl(parent); + if (getSourceViewer() instanceof ProjectionViewer) { + ProjectionViewer viewer =(ProjectionViewer)getSourceViewer(); + projectionSupport = new ProjectionSupport(viewer,getAnnotationAccess(),getSharedColors()); + projectionSupport.install(); + //turn projection mode on + viewer.doOperation(ProjectionViewer.TOGGLE); + } + } + + /** + * Returns the editor's source viewer. May return null before the editor's part has been created and after disposal. + */ + public ISourceViewer getViewer() { + return getSourceViewer(); + } + + @Override + protected ISourceViewer createSourceViewer(Composite parent, + IVerticalRuler ruler, int styles) { +// if (true) return super.createSourceViewer(parent, ruler, styles); + // Create with code-folding + ISourceViewer viewer = new ProjectionViewer(parent, ruler, + getOverviewRuler(), isOverviewRulerVisible(), styles); + // ensure decoration support has been created and configured. + SourceViewerDecorationSupport decSupport = getSourceViewerDecorationSupport(viewer); +// SourceViewer viewer = (SourceViewer) super.createSourceViewer(parent, ruler, styles); + // Setup word-wrapping + final StyledText widget = viewer.getTextWidget(); + // Listen to pref changes + prefChangeListener = new IPropertyChangeListener() { + public void propertyChange(PropertyChangeEvent event) { + if (event.getProperty().equals(MarkdownPreferencePage.PREF_WORD_WRAP)) { + widget.setWordWrap(MarkdownPreferencePage.wordWrap()); + } + } + }; + pStore.addPropertyChangeListener(prefChangeListener); + // Switch on word-wrapping + if (MarkdownPreferencePage.wordWrap()) { + widget.setWordWrap(true); + } + return viewer; + } + + public void dispose() { + if (pStore != null) { + pStore.removePropertyChangeListener(prefChangeListener); + } + colorManager.dispose(); + super.dispose(); + } + public void documentAboutToBeChanged(DocumentEvent event) { + } + + public void documentChanged(DocumentEvent event) { + pageDirty = true; + } + + @Override + protected void doSetInput(IEditorInput input) throws CoreException { + // Detach from old + if (oldDoc!= null) { + oldDoc.removeDocumentListener(this); + if (doc2editor.get(oldDoc) == this) doc2editor.remove(oldDoc); + } + // Set + super.doSetInput(input); + // Attach as a listener to new doc + IDocument doc = getDocument(); + oldDoc = doc; + if (doc==null) return; + doc.addDocumentListener(this); + doc2editor.put(doc, this); + // Initialise code folding + haveRunFolding = false; + updateSectionFoldingAnnotations(null); + } + + @Override + protected void editorSaved() { + if (MarkdownPreview.preview != null) { + // Update the preview when the file is saved + MarkdownPreview.preview.update(); + } + } + + public Object getAdapter(Class required) { + if (IContentOutlinePage.class.equals(required)) { + if (fOutlinePage == null) { + fOutlinePage= new MarkdownContentOutlinePage(getDocumentProvider(), this); + if (getEditorInput() != null) + fOutlinePage.setInput(getEditorInput()); + } + return fOutlinePage; + } + return super.getAdapter(required); + } + public IDocument getDocument() { + IEditorInput input = getEditorInput(); + IDocumentProvider docProvider = getDocumentProvider(); + return docProvider==null? null : docProvider.getDocument(input); + } + /** + * + * @return The {@link MarkdownPage} for the document being edited, or null + * if unavailable. + */ + public MarkdownPage getMarkdownPage() { + if (pageDirty) updateMarkdownPage(); + return page; + } + + public int getPrintColumns() { + return getPreferenceStore().getInt(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_PRINT_MARGIN_COLUMN); + } + + /** + * @return The text of the editor's document, or null if unavailable. + */ + public String getText() { + IDocument doc = getDocument(); + return doc==null? null : doc.get(); + } + + private void updateMarkdownPage() { + String text = getText(); + if (text==null) text=""; + page = new MarkdownPage(text); + pageDirty = false; + } + + void updateTaskTags(IRegion region) { + try { + boolean useTags = pStore.getBoolean(MarkdownPreferencePage.PREF_TASK_TAGS); + if (!useTags) return; + // Get task tags +// IPreferenceStore peuistore = EditorsUI.getPreferenceStore(); +//// IPreferenceStore pStore_jdt = org.eclipse.jdt.core.compiler.getDefault().getPreferenceStore(); +// String tagString = peuistore.getString("org.eclipse.jdt.core.compiler.taskTags"); + String tagString = pStore.getString(MarkdownPreferencePage.PREF_TASK_TAGS_DEFINED); + List tags = Arrays.asList(tagString.split(",")); + // Get resource for editor + IFile docFile = getResource(this); + // Get existing tasks + IMarker[] taskMarkers = docFile.findMarkers(IMarker.TASK, true, IResource.DEPTH_INFINITE); + List markers = new ArrayList(Arrays.asList(taskMarkers)); +// Collections.sort(markers, c) sort for efficiency + // Find tags in doc + List text = getMarkdownPage().getText(); + for(int i=1; i<=text.size(); i++) { + String line = text.get(i-1); // wierd off-by-one bug + for (String tag : tags) { + tag = tag.trim(); + int tagIndex = line.indexOf(tag); + if (tagIndex == -1) continue; + IMarker exists = updateTaskTags2_checkExisting(i, tagIndex, line, markers); + if (exists!=null) { + markers.remove(exists); + continue; + } + IMarker marker = docFile.createMarker(IMarker.TASK); + //Once we have a marker object, we can set its attributes + marker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_NORMAL); + String msg = line.substring(line.indexOf(tag), Math.min(tagIndex+MAX_TASK_MSG_LENGTH, line.length()-1)); + marker.setAttribute(IMarker.MESSAGE, msg); + marker.setAttribute(IMarker.LINE_NUMBER, i); + } + } + // Remove old markers + for (IMarker m : markers) { + try { + m.delete(); + } catch (Exception ex) { + // + } + } + } catch (Exception ex) { + // + } + } + + /** + * Find an existing marker, if there is one. + * @param i + * @param tagIndex + * @param line + * @param markers + * @return + */ + private IMarker updateTaskTags2_checkExisting(int i, int tagIndex, + String line, List markers) { + String tagMessage = line.substring(tagIndex).trim(); + for (IMarker marker : markers) { + try { + Integer lineNum = (Integer) marker.getAttribute(IMarker.LINE_NUMBER); + if (i != lineNum) continue; + String txt = ((String) marker.getAttribute(IMarker.MESSAGE)).trim(); + if (tagMessage.equals(txt)) return marker; + } catch (Exception ex) { + // Ignore + } + } + return null; + } + + + private IFile getResource(MarkdownEditor markdownEditor) { + IPathEditorInput input = (IPathEditorInput) getEditorInput(); + IPath path = input.getPath(); + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + IWorkspaceRoot root = workspace.getRoot(); + IFile[] files = root.findFilesForLocation(path); + if (files.length != 1) return null; + IFile docFile = files[0]; + return docFile; + } + + + /** + * @param doc + * @return + */ + public static MarkdownEditor getEditor(IDocument doc) { + return doc2editor.get(doc); + } + + private static final Map doc2editor = new HashMap(); + + + /** + * @param region + * + */ + public void updatePage(IRegion region) { +// if (!pageDirty) return; + updateTaskTags(region); + updateSectionFoldingAnnotations(region); + } + + + private static final Annotation[] ANNOTATION_ARRAY = new Annotation[0]; + + private static final Position[] POSITION_ARRAY = new Position[0]; + + private boolean haveRunFolding = false; + private Map oldAnnotations = new HashMap(0); + + /** + * @param region can be null + */ + private void updateSectionFoldingAnnotations(IRegion region) { + if (!haveRunFolding) region = null; // Do the whole doc + if ( ! (getSourceViewer() instanceof ProjectionViewer)) return; + ProjectionViewer viewer = ((ProjectionViewer)getSourceViewer()); + MarkdownPage mPage = getMarkdownPage(); + List
headers = mPage.getHeadings(null); + // this will hold the new annotations along + // with their corresponding positions + Map annotations = new HashMap(); + IDocument doc = getDocument(); + updateSectionFoldingAnnotations2(doc, headers, annotations, doc.getLength()); + // Filter existing ones + Position[] newValues = annotations.values().toArray(POSITION_ARRAY); + List deletedAnnotations = new ArrayList(); + for(Entry ae : oldAnnotations.entrySet()) { + Position oldp = ae.getValue(); + boolean stillExists = false; + for (Position newp : newValues) { + if (oldp.equals(newp)) { + annotations.remove(newp); + stillExists = true; + break; + } + } + if (!stillExists && intersectsRegion(oldp, region)) { + deletedAnnotations.add(ae.getKey()); + } + } + // Filter out-of-region ones + for(Annotation a : annotations.keySet().toArray(ANNOTATION_ARRAY)) { + Position p = annotations.get(a); + if (!intersectsRegion(p , region)) annotations.remove(a); + } + // Adjust the page + ProjectionAnnotationModel annotationModel = viewer.getProjectionAnnotationModel(); + if (annotationModel==null) return; + annotationModel.modifyAnnotations(deletedAnnotations.toArray(ANNOTATION_ARRAY), annotations, null); + // Remember old values + oldAnnotations.putAll(annotations); + for (Annotation a : deletedAnnotations) { + oldAnnotations.remove(a); + } + haveRunFolding = true; + } + + + /** + * @param p + * @param region + * @return true if p overlaps with region, or if region is null + */ + private boolean intersectsRegion(Position p, IRegion region) { + if (region==null) return true; + if (p.offset > region.getOffset()+region.getLength()) return false; + if (p.offset+p.length < region.getOffset()) return false; + return true; + } + + + /** + * Calculate where to fold, sticking the info into newAnnotations + * @param doc + * @param headers + * @param newAnnotations + * @param endParent + */ + private void updateSectionFoldingAnnotations2(IDocument doc, List
headers, + Map newAnnotations, int endParent) { + for (int i=0; i subHeaders = header.getSubHeaders(); + if (subHeaders.size() > 0) { + updateSectionFoldingAnnotations2(doc, subHeaders, newAnnotations, end); + } + } catch (Exception ex) { + System.out.println(ex); + } + } + } + + +} + + + +/* + + +- + + + + IEditorPart editor = null; + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window != null) { + IWorkbenchPage activePage = window.getActivePage(); + if (activePage != null) editor = activePage.getActiveEditor(); + } + if (editor != null) { + // todo: Add operations for active editor + } + + + + + + + +*/ \ No newline at end of file diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/PrintAction.java b/bundles/winterwell.markdown/src/winterwell/markdown/editors/PrintAction.java new file mode 100644 index 000000000..8d089f16e --- /dev/null +++ b/bundles/winterwell.markdown/src/winterwell/markdown/editors/PrintAction.java @@ -0,0 +1,75 @@ +//package winterwell.markdown.editors; +// +//import java.util.List; +// +//import net.sf.paperclips.PaperClips; +//import net.sf.paperclips.Print; +//import net.sf.paperclips.PrintJob; +//import net.sf.paperclips.TextPrint; +// +//import org.eclipse.core.commands.ExecutionEvent; +//import org.eclipse.core.commands.ExecutionException; +//import org.eclipse.core.commands.IHandler; +//import org.eclipse.core.commands.IHandlerListener; +//import org.eclipse.jface.action.Action; +//import org.eclipse.jface.text.BadLocationException; +//import org.eclipse.jface.text.DocumentEvent; +//import org.eclipse.jface.text.IDocument; +//import org.eclipse.jface.text.IDocumentListener; +//import org.eclipse.jface.text.IRegion; +//import org.eclipse.jface.text.ITextSelection; +//import org.eclipse.jface.text.Region; +//import org.eclipse.jface.text.source.ISourceViewer; +//import org.eclipse.jface.viewers.ISelection; +//import org.eclipse.swt.SWT; +//import org.eclipse.swt.printing.PrintDialog; +//import org.eclipse.swt.printing.PrinterData; +//import org.eclipse.swt.widgets.Display; +//import org.eclipse.ui.IEditorPart; +//import org.eclipse.ui.IPropertyListener; +//import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants; +// +//import winterwell.markdown.pagemodel.MarkdownFormatter; +//import winterwell.markdown.pagemodel.MarkdownPage; +//import winterwell.markdown.pagemodel.MarkdownPage.KLineType; +//import winterwell.utils.containers.Pair; +//import winterwell.utils.containers.Range; +// +///** +// * Print the file +// * +// * +// * @author daniel +// */ +//public class PrintAction extends Action { +// +// public PrintAction() { +// super("Print..."); +// } +// +// @Override +// public void run() { +// try { +// MarkdownEditor ed = (MarkdownEditor) ActionBarContributor.getActiveEditor(); +// if (ed == null) return; // The active editor is not a markdown editor. +// PrintDialog dialog = new PrintDialog(Display.getDefault().getActiveShell(), SWT.NONE); +// PrinterData printerData = dialog.open (); +// if (printerData == null) return; +// Print doc = new TextPrint(ed.getText()); +// PrintJob job = new PrintJob(ed.getTitle(), doc ); +// PaperClips.print(job, printerData); +// // Done +// } catch (Exception ex) { +// System.out.println(ex); +// } +// } +// +// +// +// public void dispose() { +// // Ignore +// } +// +// +//} +// \ No newline at end of file diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/collapseall.gif b/bundles/winterwell.markdown/src/winterwell/markdown/editors/collapseall.gif new file mode 100644 index 000000000..a2d80a904 Binary files /dev/null and b/bundles/winterwell.markdown/src/winterwell/markdown/editors/collapseall.gif differ diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/synced.gif b/bundles/winterwell.markdown/src/winterwell/markdown/editors/synced.gif new file mode 100644 index 000000000..870934b69 Binary files /dev/null and b/bundles/winterwell.markdown/src/winterwell/markdown/editors/synced.gif differ diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/pagemodel/MarkdownFormatter.java b/bundles/winterwell.markdown/src/winterwell/markdown/pagemodel/MarkdownFormatter.java new file mode 100644 index 000000000..4c38f19e8 --- /dev/null +++ b/bundles/winterwell.markdown/src/winterwell/markdown/pagemodel/MarkdownFormatter.java @@ -0,0 +1,351 @@ + +package winterwell.markdown.pagemodel; + +import java.util.List; + +import winterwell.utils.StrUtils; + +/** + * Formats a string that is compatible with the Markdown syntax. + * Strings must not include headers. + * + * @author Howard Abrams + */ +public class MarkdownFormatter +{ + // Expect everyone to simply use the public static methods... + private MarkdownFormatter () + { + } + + /** + * Formats a collection of lines to a particular width and honors typical + * Markdown syntax and formatting. + * + * The method assumes that if the first line ends with a line + * termination character, all the other lines will as well. + * + * @param lines A list of strings that should be formatted and wrapped. + * @param lineWidth The width of the page + * @return A string containing each + */ + public static String format (List lines, int lineWidth) + { + if (lines == null) + return null; // Should we return an empty string? + + final String lineEndings; + if ( lines.get(0).endsWith ("\r\n") ) + lineEndings = "\r\n"; + else if ( lines.get(0).endsWith ("\r") ) + lineEndings = "\r"; + else + lineEndings = StrUtils.LINEEND; + + final StringBuilder buf = new StringBuilder(); + for (String line : lines) { + buf.append (line); + buf.append (' '); // We can add extra spaces with impunity, and this + // makes sure our lines don't run together. + } + return format ( buf.toString(), lineWidth, lineEndings ); + } + + + /** + * Formats a string of text. The formatting does line wrapping at the + * lineWidth boundary, but it also honors the formatting + * of initial paragraph lines, allowing indentation of the entire + * paragraph. + * + * @param text The line of text to format + * @param lineWidth The width of the lines + * @return A string containing the formatted text. + */ + public static String format ( final String text, final int lineWidth) + { + return format(text, lineWidth, StrUtils.LINEEND); + } + + /** + * Formats a string of text. The formatting does line wrapping at the + * lineWidth boundary, but it also honors the formatting + * of initial paragraph lines, allowing indentation of the entire + * paragraph. + * + * @param text The line of text to format + * @param lineWidth The width of the lines + * @param lineEnding The line ending that overrides the default System value + * @return A string containing the formatted text. + */ + public static String format (final String text, final int lineWidth, final String lineEnding) + { + return new String( format(text.toCharArray (), lineWidth, lineEnding)); + } + + /** + * The available cursor position states as it sits in the buffer. + */ + private enum StatePosition { + /** The beginning of a paragraph ... the start of the buffer */ + BEGIN_FIRST_LINE, + + /** The beginning of the next line, which may be completely ignored. */ + BEGIN_OTHER_LINE, + + /** The beginning of a new line that will not be ignored, but appended. */ + BEGIN_NEW_LINE, + + /** The middle of a line. */ + MIDDLE_OF_LINE + } + + /** + * The method that does the work of formatting a string of text. The text, + * however, is a character array, which is more efficient to work with. + * + * TODO: Should we make the format(char[]) method public? + * + * @param text The line of text to format + * @param lineWidth The width of the lines + * @param lineEnding The line ending that overrides the default System value + * @return A string containing the formatted text. + */ + static char[] format ( final char[] text, final int lineWidth, final String lineEnding ) + { + final StringBuilder word = new StringBuilder(); + final StringBuilder indent = new StringBuilder(); + final StringBuilder buffer = new StringBuilder(text.length + 10); + + StatePosition state = StatePosition.BEGIN_FIRST_LINE; + int lineLength = 0; + + // There are times when we will run across a character(s) that will + // cause us to stop doing word wrap until we get to the + // "end of non-wordwrap" character(s). + // + // If this string is set to null, it tells us to "do" word-wrapping. + char endWordwrap1 = 0; + char endWordwrap2 = 0; + + // We loop one character past the end of the loop, and when we get to + // this position, we assign 'c' to be 0 ... as a marker for the end of + // the string... + + for (int i = 0; i <= text.length; i++) + { + final char c; + if (i < text.length) + c = text[i]; + else + c = 0; + + final char nextChar; + if (i+1 < text.length) + nextChar = text[i+1]; + else + nextChar = 0; + + // Are we actually word-wrapping? + if (endWordwrap1 != 0) { + // Did we get the ending sequence of the non-word-wrap? + if ( ( endWordwrap2 == 0 && c == endWordwrap1 ) || + ( c == endWordwrap1 && nextChar == endWordwrap2 ) ) + endWordwrap1 = 0; + buffer.append (c); + lineLength++; + + if (endWordwrap1 == 0 && endWordwrap2 != 0) { + buffer.append (nextChar); + lineLength++; + i++; + } + continue; + } + + // Check to see if we got one of our special non-word-wrapping + // character sequences ... + + if ( c == '[' ) { // [Hyperlink] + endWordwrap1 = ']'; + } + else if ( c == '*' && nextChar == '*' ) { // **Bold** + endWordwrap1 = '*'; + endWordwrap2 = '*'; + } // *Italics* + else if ( c == '*' && state == StatePosition.MIDDLE_OF_LINE ) { + endWordwrap1 = '*'; + } + else if ( c == '`' ) { // `code` + endWordwrap1 = '`'; + } + else if ( c == '(' && nextChar == '(' ) { // ((Footnote)) + endWordwrap1 = ')'; + endWordwrap2 = ')'; + } + else if ( c == '!' && nextChar == '[' ) { // ![Image] + endWordwrap1 = ')'; + } + + // We are no longer doing word-wrapping, so tidy the situation up... + if (endWordwrap1 != 0) { + if (word.length() > 0) + lineLength = addWordToBuffer (lineWidth, lineEnding, word, indent, buffer, lineLength); + else if (buffer.length() > 0 && buffer.charAt (buffer.length()-1) != ']' ) + buffer.append(' '); + // We are adding an extra space for most situations, unless we get a + // [link][ref] where we want them to be together without a space. + + buffer.append (c); + lineLength++; + continue; + } + + // Normal word-wrapping processing continues ... + + if (state == StatePosition.BEGIN_FIRST_LINE) + { + if ( c == '\n' || c == '\r' ) { // Keep, but ignore initial line feeds + buffer.append (c); + lineLength = 0; + continue; + } + + if (Character.isWhitespace (c)) + indent.append (c); + else if ( (c == '*' || c == '-' || c == '.' ) && + Character.isWhitespace (nextChar) ) + indent.append (' '); + else if ( Character.isDigit (c) && nextChar == '.' && + Character.isWhitespace (text[i+2])) + indent.append (' '); + else if ( c == '>' ) + indent.append ('>'); + else + state = StatePosition.MIDDLE_OF_LINE; + + // If we are still in the initial state, then put 'er in... + if (state == StatePosition.BEGIN_FIRST_LINE) { + buffer.append (c); + lineLength++; + } + } + + // While it would be more accurate to explicitely state the range of + // possibilities, with something like: + // EnumSet.range (StatePosition.BEGIN_OTHER_LINE, StatePosition.MIDDLE_OF_LINE ).contains (state) + // We know that what is left is just the BEGIN_FIRST_LINE ... + + if ( state != StatePosition.BEGIN_FIRST_LINE ) + { + // If not the middle of the line, then it must be at the first of a line + // Either BEGIN_OTHER_LINE or BEGIN_NEW_LINE + if (state != StatePosition.MIDDLE_OF_LINE) + { + if ( Character.isWhitespace(c) || c == '>' || c == '.' ) + word.append (c); + else if ( ( ( c == '*' || c == '-' ) && Character.isWhitespace (nextChar) ) || + ( Character.isDigit(c) && nextChar == '.' && Character.isWhitespace( text[i+2] ) ) ) { + word.append (c); + state = StatePosition.BEGIN_NEW_LINE; + } + else { + if (state == StatePosition.BEGIN_NEW_LINE) { + buffer.append (word); + lineLength = word.substring ( word.indexOf("\n")+1 ).length(); + } + word.setLength (0); + state = StatePosition.MIDDLE_OF_LINE; + } + } + + if (state == StatePosition.MIDDLE_OF_LINE) + { + // Are we at the end of a word? Then we need to calculate whether + // to wrap the line or not. + // + // This condition does double duty, in that is also serves to + // ignore multiple spaces and special characters that may be at + // the beginning of the line. + if ( Character.isWhitespace(c) || c == 0 ) + { + if ( word.length() > 0) { + lineLength = addWordToBuffer (lineWidth, lineEnding, word, indent, buffer, lineLength); + } + // Do we we two spaces at the end of the line? Honor this... + else if ( c == ' ' && ( nextChar == '\r' || nextChar == '\n' ) && + state != StatePosition.BEGIN_OTHER_LINE ) { + buffer.append (" "); + buffer.append (lineEnding); + lineLength = 0; + } + + if ( c == '\r' || c == '\n' ) { + state = StatePosition.BEGIN_OTHER_LINE; + word.append(c); + } + + // Linefeeds are completely ignored and just treated as whitespace, + // unless, of course, there are two of 'em... and of course, end of + // lines are simply evil on Windows machines. + + if ( (c == '\n' && nextChar == '\n') || // Unix-style line-ends + ( c == '\r' && nextChar == '\n' && // Windows-style line-ends + text[i+2] == '\r' && text[i+3] == '\n' ) ) + { + state = StatePosition.BEGIN_FIRST_LINE; + word.setLength(0); + indent.setLength (0); + lineLength = 0; + + if (c == '\r') { // If we are dealing with Windows-style line-ends, + i++; // we need to skip past the next character... + buffer.append("\r\n"); + } else + buffer.append(c); + } + + } else { + word.append (c); + state = StatePosition.MIDDLE_OF_LINE; + } + } + } + } + + return buffer.toString().toCharArray(); + } + + /** + * Adds a word to the buffer, performing word wrap if necessary. + * @param lineWidth The current width of the line + * @param lineEnding The line ending to append, if necessary + * @param word The word to append + * @param indent The indentation string to insert, if necesary + * @param buffer The buffer to perform all this stuff to + * @param lineLength The current length of the current line + * @return The new length of the current line + */ + private static int addWordToBuffer (final int lineWidth, final String lineEnding, + final StringBuilder word, + final StringBuilder indent, + final StringBuilder buffer, int lineLength) + { + if ( word.length() + lineLength + 1 > lineWidth ) + { + buffer.append (lineEnding); + buffer.append (indent); + buffer.append (word); + + lineLength = indent.length() + word.length(); + } + else { + if ( lineLength > indent.length() ) + buffer.append (' '); + buffer.append (word); + lineLength += word.length() + 1; + } + word.setLength (0); + return lineLength; + } +} diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/pagemodel/MarkdownFormatterTest.java b/bundles/winterwell.markdown/src/winterwell/markdown/pagemodel/MarkdownFormatterTest.java new file mode 100644 index 000000000..4e4dd75a2 --- /dev/null +++ b/bundles/winterwell.markdown/src/winterwell/markdown/pagemodel/MarkdownFormatterTest.java @@ -0,0 +1,537 @@ +//package winterwell.markdown.pagemodel; +// +//import java.util.Arrays; +//import java.util.List; +// +//import junit.framework.TestCase; +//// import winterwell.utils.MarkdownFormatter; +// +///** +// * Test methods in the StringMethods utility class. +// */ +//public class MarkdownFormatterTest extends TestCase +//{ +// /** +// * The local line-end string. \n on unix, \r\n on windows. +// * I really want to run through all of these tests with both styles. +// * We'll come back to that sort of a trick. +// */ +// // public String LINEEND = System.getProperty("line.separator"); +// public static final String LINEEND = "\r\n"; +// +// /** +// * Test default word wrapping of a long line of normal text. +// */ +// public void testFormatStringInt () +// { +// final String LONG_LINE = +// "Now is the time for all good " + +// "chickens to come to the aid of " + +// "their coopertino lattes, and " + +// "begin the process of singing."; +// final String EXPECTED = +// "Now is the time for all good" + LINEEND + +// "chickens to come to the aid of" + LINEEND + // This line is 30 characters +// "their coopertino lattes, and" + LINEEND + +// "begin the process of singing."; +// assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 30, LINEEND)); +// } +// +// /** +// * If the initial part of the line contains some spaces, we use that as +// * the "indentation" for every other line. +// * @throws Exception +// */ +// public void testIndentOfSpaces () throws Exception +// { +// final String LONG_LINE = +// " Now is the time for all good " + +// "chickens to come to the aid of " + +// "their coopertino lattes, and " + +// "begin the process of singing."; +// final String EXPECTED = +// " Now is the time for all good" + LINEEND + +// " chickens to come to the aid of" + LINEEND + +// " their coopertino lattes, and" + LINEEND + +// " begin the process of singing."; +// assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 34, LINEEND)); +// } +// +// /** +// * Can we maintain the format of text that is already formatted? +// * @throws Exception +// */ +// public void testAlreadyFormatted () throws Exception +// { +// final String LONG_LINE = +// " Now is the time for all good" + LINEEND + +// " chickens to come to the aid of" + LINEEND + +// " their coopertino lattes, and" + LINEEND + +// " begin the process of singing."; +// assertEquals (LONG_LINE, MarkdownFormatter.format (LONG_LINE, 34, LINEEND)); +// } +// +// /** +// * Formatting a single line is all fine and dandy, but what about +// * formatting multiple paragraphs, that is, blank lines. +// * @throws Exception +// */ +// public void testMultipleParagraphs () throws Exception +// { +// final String LONG_LINE = +// " Now is the time for all good " + +// "chickens to come to their aid." + LINEEND + LINEEND + +// " And drink coopertino lattes, and " + +// "begin the process of singing."; +// final String EXPECTED = +// " Now is the time for all good" + LINEEND + +// " chickens to come to their aid." + LINEEND + LINEEND + +// " And drink coopertino lattes," + LINEEND + +// " and begin the process of" + LINEEND + " singing."; +// assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 34, LINEEND)); +// } +// +// /** +// * What if the section we are formatting, begins with line feeds? +// * Do we keep 'em? Might as well. :-) +// * @throws Exception +// */ +// public void testInitialLineFeeds () throws Exception +// { +// final String LONG_LINE = LINEEND + LINEEND + LINEEND + +// " Now is the time for all good" + LINEEND + +// " chickens to come to the aid of" + LINEEND + +// " their coopertino lattes, and" + LINEEND + +// " begin the process of singing."; +// assertEquals (LONG_LINE, MarkdownFormatter.format (LONG_LINE, 34, LINEEND)); +// } +// +// /** +// * We need to be able to format bulleted lists appropriately. +// * @throws Exception +// */ +// public void testSingleBulletedList () throws Exception +// { +// final String LONG_LINE = +// " * Now is the time for all good " + +// "chickens to come to the aid of " + LINEEND + +// "their coopertino lattes, and " + +// "begin the process of singing."; +// final String EXPECTED = +// " * Now is the time for all good" + LINEEND + +// " chickens to come to the aid of" + LINEEND + +// " their coopertino lattes, and" + LINEEND + +// " begin the process of singing."; +// assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 34, LINEEND)); +// } +// +// /** +// * What about dealing with multiple bulleted lists. +// * @throws Exception +// */ +// public void testMultipleBulletedList () throws Exception +// { +// final String LONG_LINE = +// "Now is the time for all good " + +// "chickens to:" + LINEEND + LINEEND + +// " * Cluck" + LINEEND + +// " * Sing" + LINEEND + +// " * Drink coopertino lattes."; +// final String EXPECTED = +// "Now is the time for all good" + LINEEND + +// "chickens to:" + LINEEND + LINEEND + +// " * Cluck" + LINEEND + +// " * Sing" + LINEEND + +// " * Drink coopertino lattes."; +// assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 34, LINEEND)); +// } +// +// /** +// * What about dealing with multiple bulleted lists. +// * @throws Exception +// */ +// public void testMultipleDashedBulletedList () throws Exception +// { +// final String LONG_LINE = +// "Now is the time for all good " + +// "chickens to:" + LINEEND + LINEEND + +// " - Cluck" + LINEEND + +// " - Sing" + LINEEND + +// " - Drink coopertino lattes."; +// final String EXPECTED = +// "Now is the time for all good" + LINEEND + +// "chickens to:" + LINEEND + LINEEND + +// " - Cluck" + LINEEND + +// " - Sing" + LINEEND + +// " - Drink coopertino lattes."; +// assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 34, LINEEND)); +// } +// +// /** +// * Tests whether we can have nested bulleted lists. +// * @throws Exception +// */ +// public void testSubindentedBulletedLists () throws Exception +// { +// final String LONG_LINE = +// "Now is the time for all good " + +// "chickens to:" + LINEEND + LINEEND + +// " * Cluck, cluck, cluck till their little feets hurt:" + LINEEND + +// " * Do it again and again and again and again." + LINEEND + +// " * And maybe again and again if their mommy's say so." + LINEEND + +// " * We can indent really, really, deep with three levels of subitems." + LINEEND + +// " * But we aren't sure if this is getting ridiculous or just plain expected." + LINEEND + +// " * Sing, sing, sing till their little voices break:" + LINEEND + +// " * Do it again and again and again and again." + LINEEND + +// " * And maybe again and again if their mommy's say so." + LINEEND + +// " * Drink coopertino lattes."; +// final String EXPECTED = +// "Now is the time for all good" + LINEEND + +// "chickens to:" + LINEEND + LINEEND + +// " * Cluck, cluck, cluck till their" + LINEEND + +// " little feets hurt:" + LINEEND + +// " * Do it again and again and" + LINEEND + +// " again and again." + LINEEND + +// " * And maybe again and again if" + LINEEND + +// " their mommy's say so." + LINEEND + +// " * We can indent really," + LINEEND + +// " really, deep with three" + LINEEND + +// " levels of subitems." + LINEEND + +// " * But we aren't sure if this" + LINEEND + +// " is getting ridiculous or " + LINEEND + +// " just plain expected." + LINEEND + +// " * Sing, sing, sing till their" + LINEEND + +// " little voices break:" + LINEEND + +// " * Do it again and again and" + LINEEND + +// " again and again." + LINEEND + +// " * And maybe again and again if" + LINEEND + +// " their mommy's say so." + LINEEND + +// " * Drink coopertino lattes."; +// assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 34, LINEEND)); +// } +// +// /** +// * Tests whether we can have nested bulleted lists. +// * @throws Exception +// */ +// public void testSubindentedBulletedLists2 () throws Exception +// { +// final String LONG_LINE = +// "Now is the time for all good " + +// "chickens to:" + LINEEND + LINEEND + +// " * Cluck, cluck, cluck till their little feets hurt:" + LINEEND + LINEEND + +// " * Do it again and again and again and again." + LINEEND + LINEEND + +// " * And maybe again and again if their mommy's say so." + LINEEND + LINEEND + +// " * We can indent really, really, deep with three levels of subitems." + LINEEND + LINEEND + +// " * But we aren't sure if this is getting ridiculous or just plain expected." + LINEEND + LINEEND + +// " * Sing, sing, sing till their little voices break:" + LINEEND + LINEEND + +// " * Do it again and again and again and again." + LINEEND + LINEEND + +// " * And maybe again and again if their mommy's say so." + LINEEND + LINEEND + +// " * Drink coopertino lattes."; +// final String EXPECTED = +// "Now is the time for all good" + LINEEND + +// "chickens to:" + LINEEND + LINEEND + +// " * Cluck, cluck, cluck till their" + LINEEND + +// " little feets hurt:" + LINEEND + LINEEND + +// " * Do it again and again and" + LINEEND + +// " again and again." + LINEEND + LINEEND + +// " * And maybe again and again if" + LINEEND + +// " their mommy's say so." + LINEEND + LINEEND + +// " * We can indent really," + LINEEND + +// " really, deep with three" + LINEEND + +// " levels of subitems." + LINEEND + LINEEND + +// " * But we aren't sure if this" + LINEEND + +// " is getting ridiculous or" + LINEEND + +// " just plain expected." + LINEEND + LINEEND + +// " * Sing, sing, sing till their" + LINEEND + +// " little voices break:" + LINEEND + LINEEND + +// " * Do it again and again and" + LINEEND + +// " again and again." + LINEEND + LINEEND + +// " * And maybe again and again if" + LINEEND + +// " their mommy's say so." + LINEEND + LINEEND + +// " * Drink coopertino lattes."; +// assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 34, LINEEND)); +// } +// +// /** +// * What about dealing with a numeric list? +// * @throws Exception +// */ +// public void testSingleNumericList () throws Exception +// { +// final String LONG_LINE = +// " 2. Now is the time for all good " + +// "chickens to come to the aid of " + +// "their coopertino lattes, and " + +// "begin the process of singing."; +// final String EXPECTED = +// " 2. Now is the time for all good" + LINEEND + +// " chickens to come to the aid of" + LINEEND + +// " their coopertino lattes, and" + LINEEND + +// " begin the process of singing."; +// assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 34, LINEEND)); +// } +// +// /** +// * What about dealing with multiple bulleted lists. +// * @throws Exception +// */ +// public void testMultipleNumericList () throws Exception +// { +// final String LONG_LINE = +// "Now is the time for all good " + +// "chickens to:" + LINEEND + LINEEND + +// " 1. Cluck" + LINEEND + +// " 2. Sing" + LINEEND + +// " 3. Drink coopertino lattes."; +// final String EXPECTED = +// "Now is the time for all good" + LINEEND + +// "chickens to:" + LINEEND + LINEEND + +// " 1. Cluck" + LINEEND + +// " 2. Sing" + LINEEND + +// " 3. Drink coopertino lattes."; +// assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 34, LINEEND)); +// } +// +// /** +// * What about dealing with sections that should not be word wrapped, like +// * the text between brackets (since they are hyperlinks). +// * @throws Exception +// */ +// public void testNoWordWrapBracket() throws Exception +// { +// final String LONG_LINE = +// "Now is the time for all good " + +// "chickens to come to [the spurious and costly][3] " + +// "aid of their coopertino cups, " + +// "and begin sing."; +// final String EXPECTED = +// "Now is the time for all good" + LINEEND + +// "chickens to come to [the spurious and costly][3]" + LINEEND + +// "aid of their coopertino cups, and" + LINEEND + +// "begin sing."; +// assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 34, LINEEND)); +// } +// /** +// * What about dealing with bracketed sections with no extra white space +// * @throws Exception +// */ +// public void testNoWordWrapBracket2() throws Exception +// { +// final String LONG_LINE = +// "Now is the time for all good " + +// "chickens to come to[the spurious and costly][3] " + +// "aid of their coopertino cups, " + +// "and begin sing."; +// final String EXPECTED = +// "Now is the time for all good" + LINEEND + +// "chickens to come to[the spurious and costly][3]" + LINEEND + +// "aid of their coopertino cups, and" + LINEEND + +// "begin sing."; +// assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 34, LINEEND)); +// } +// +// /** +// * What about dealing with bold sections that should not be word wrapped. +// * @throws Exception +// */ +// public void testNoWordWrapDoubleAsterix() throws Exception +// { +// final String LONG_LINE = +// "Now is the time for all good " + +// "chickens to come to **the spurious and costly** " + +// "aid of their coopertino cups, " + +// "and begin sing."; +// final String EXPECTED = +// "Now is the time for all good" + LINEEND + +// "chickens to come to **the spurious and costly**" + LINEEND + +// "aid of their coopertino cups, and" + LINEEND + +// "begin sing."; +// assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 34, LINEEND)); +// } +// +// /** +// * What about dealing with italic sections that should not be word wrapped +// * @throws Exception +// */ +// public void testNoWordWrapSingleAsterix() throws Exception +// { +// final String LONG_LINE = +// "Now is the time for all good " + +// "chickens to come to *the spurious and costly* " + +// "aid of their coopertino cups, " + +// "and begin sing."; +// final String EXPECTED = +// "Now is the time for all good" + LINEEND + +// "chickens to come to *the spurious and costly*" + LINEEND + +// "aid of their coopertino cups, and" + LINEEND + +// "begin sing."; +// assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 34, LINEEND)); +// } +// +// /** +// * What about dealing with sections that are code should not be broken. +// * @throws Exception +// */ +// public void testNoWordWrapCode() throws Exception +// { +// final String LONG_LINE = +// "Now is the time for all good " + +// "chickens to come to `the spurious and costly` " + +// "aid of their coopertino cups, " + +// "and begin sing."; +// final String EXPECTED = +// "Now is the time for all good" + LINEEND + +// "chickens to come to `the spurious and costly`" + LINEEND + +// "aid of their coopertino cups, and" + LINEEND + +// "begin sing."; +// assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 34, LINEEND)); +// } +// +// /** +// * What about dealing with double parenthesis sections ... these shouldn't +// * be broken up. +// * @throws Exception +// */ +// public void testNoWordWrapDoubleParens() throws Exception +// { +// final String LONG_LINE = +// "Now is the time for all good " + +// "chickens to come to ((the spurious and costly)) " + +// "aid of their coopertino cups, " + +// "and begin sing."; +// final String EXPECTED = +// "Now is the time for all good" + LINEEND + +// "chickens to come to ((the spurious and costly))" + LINEEND + +// "aid of their coopertino cups, and" + LINEEND + +// "begin sing."; +// assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 34, LINEEND)); +// } +// +// +// /** +// * If a line, embedded in a paragraph has two spaces at the end of the line, +// * these need to be honored and maintained. +// * @throws Exception +// */ +// public void testLineBreaksHonored () throws Exception +// { +// final String LONG_LINE = +// "Now is the time for all good " + +// "chickens to come " + LINEEND + +// "to the aid of their coopertino lattes, and " + +// "begin the process of singing."; +// final String EXPECTED = +// "Now is the time for all good" + LINEEND + +// "chickens to come " + LINEEND + +// "to the aid of their coopertino" + LINEEND + +// "lattes, and begin the process of" + LINEEND + +// "singing."; +// assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 33, LINEEND)); +// } +// +// /** +// * A "blockquote" in Markdown can accept > characters at the beginning +// * of all of the lines. +// * @throws Exception +// */ +// public void testBlockQuoteSimple () throws Exception +// { +// final String LONG_LINE = +// " > Now is the time for all good " + +// "chickens to come to the aid of " + +// "their coopertino , and " + +// "begin the process of singing."; +// final String EXPECTED = +// " > Now is the time for all good" + LINEEND + +// " > chickens to come to the aid of" + LINEEND + +// " > their coopertino , and" + LINEEND + +// " > begin the process of singing."; +// assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 33, LINEEND)); +// } +// +// /** +// * A "blockquote" in Markdown can accept > characters at the beginning +// * of all of the lines. Can we accept a version that is already formatted? +// * @throws Exception +// */ +// public void testBlockQuoteAlreadyFormatted () throws Exception +// { +// final String EXPECTED = +// " > Now is the time for all good" + LINEEND + +// " > chickens to come to the aid of" + LINEEND + +// " > their coopertino , and" + LINEEND + +// " > begin the process of singing."; +// assertEquals (EXPECTED, MarkdownFormatter.format (EXPECTED, 33, LINEEND)); +// } +// +// /** +// * Tests that the "list" interface works if each string does not have +// * carriage returns. +// * @throws Exception +// */ +// public void testListWithoutLinefeeds () throws Exception +// { +// final String lineend = System.getProperty("line.separator"); +// +// final List lines = Arrays.asList ( new String[] { +// "Now is the time for all good", +// "chickens to come to the aid of", +// "their coopertino lattes, and", +// "begin the process of singing." +// } ); +// final String EXPECTED = +// "Now is the time for all good" + lineend + +// "chickens to come to the aid of" + lineend + // This line is 30 characters +// "their coopertino lattes, and" + lineend + +// "begin the process of singing."; +// +// final String RESULTS = MarkdownFormatter.format (lines, 30); +// assertEquals (EXPECTED, RESULTS); +// } +// +// /** +// * Tests that the "list" interface works if each string has carriage returns. +// * @throws Exception +// */ +// public void testListWithLinefeeds () throws Exception +// { +// final List lines = Arrays.asList ( new String[] { +// "Now is the time for all good chickens to come" + LINEEND, +// "to the aid of" + LINEEND, +// "their coopertino lattes, and" + LINEEND, +// "begin the process of singing." +// } ); +// final String EXPECTED = +// "Now is the time for all good" + LINEEND + +// "chickens to come to the aid of" + LINEEND + // This line is 30 characters +// "their coopertino lattes, and" + LINEEND + +// "begin the process of singing."; +// +// final String RESULTS = MarkdownFormatter.format (lines, 30); +// assertEquals (EXPECTED, RESULTS); +// } +// +// /** +// * Tests that we don't break up image tags. +// * @throws Exception +// */ +// public void testImageTags () throws Exception +// { +// final List lines = Arrays.asList ( new String[] { +// "Now is the time for all good chickens to come " + +// "to the aid ![Some text description](http://www.google.com/images/logo.gif)" + LINEEND, +// "their coopertino lattes, and" + LINEEND, +// "begin the process of singing." +// } ); +// final String EXPECTED = +// "Now is the time for all good" + LINEEND + +// "chickens to come to the aid " + // This line is 30 characters +// "![Some text description](http://www.google.com/images/logo.gif)" + LINEEND + +// "their coopertino lattes, and" + LINEEND + +// "begin the process of singing."; +// +// final String RESULTS = MarkdownFormatter.format (lines, 30); +// assertEquals (EXPECTED, RESULTS); +// } +//} diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/pagemodel/MarkdownPage.java b/bundles/winterwell.markdown/src/winterwell/markdown/pagemodel/MarkdownPage.java new file mode 100644 index 000000000..a18a5ded6 --- /dev/null +++ b/bundles/winterwell.markdown/src/winterwell/markdown/pagemodel/MarkdownPage.java @@ -0,0 +1,617 @@ +/** + * Copyright winterwell Mathematics Ltd. + * @author Daniel Winterstein + * 11 Jan 2007 + */ +package winterwell.markdown.pagemodel; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.jface.preference.IPreferenceStore; + +import winterwell.markdown.Activator; +import winterwell.markdown.StringMethods; +import winterwell.markdown.preferences.MarkdownPreferencePage; +import winterwell.utils.FailureException; +import winterwell.utils.Process; +import winterwell.utils.StrUtils; +import winterwell.utils.Utils; +import winterwell.utils.io.FileUtils; + +import com.petebevin.markdown.MarkdownProcessor; + +/** + * Understands Markdown syntax. + * + * @author Daniel Winterstein + */ +public class MarkdownPage { + + /** + * Strip leading and trailing #s and whitespace + * + * @param line + * @return cleaned up line + */ + private String cleanHeader(String line) { + for (int j = 0; j < line.length(); j++) { + char c = line.charAt(j); + if (c != '#' && !Character.isWhitespace(c)) { + line = line.substring(j); + break; + } + } + for (int j = line.length() - 1; j > 0; j--) { + char c = line.charAt(j); + if (c != '#' && !Character.isWhitespace(c)) { + line = line.substring(0, j + 1); + break; + } + } + return line; + } + + /** + * Represents information about a section header. E.g. ## Misc Warblings + * + * @author daniel + */ + public class Header { + /** + * 1 = top-level (i.e. #), 2= 2nd-level (i.e. ##), etc. + */ + final int level; + /** + * The text of the Header + */ + final String heading; + /** + * Sub-sections, if any + */ + final List
subHeaders = new ArrayList
(); + /** + * The line on which this header occurs. + */ + final int lineNumber; + + public int getLineNumber() { + return lineNumber; + } + + /** + * + * @return the next section (at this depth if possible), null if none + */ + public Header getNext() { + if (parent == null) { + int ti = level1Headers.indexOf(this); + if (ti == -1 || ti == level1Headers.size() - 1) + return null; + return level1Headers.get(ti + 1); + } + int i = parent.subHeaders.indexOf(this); + assert i != -1 : this; + if (i == parent.subHeaders.size() - 1) + return parent.getNext(); + return parent.subHeaders.get(i + 1); + } + /** + * + * @return the next section (at this depth if possible), null if none + */ + public Header getPrevious() { + if (parent == null) { + int ti = level1Headers.indexOf(this); + if (ti == -1 || ti == 0) + return null; + return level1Headers.get(ti - 1); + } + int i = parent.subHeaders.indexOf(this); + assert i != -1 : this; + if (i == 0) + return parent.getPrevious(); + return parent.subHeaders.get(i - 1); + } + + + /** + * The parent section. Can be null. + */ + private Header parent; + + /** + * Create a marker for a section Header + * + * @param level + * 1 = top-level (i.e. #), 2= 2nd-level (i.e. ##), etc. + * @param lineNumber + * The line on which this header occurs + * @param heading + * The text of the Header, trimmed of #s + * @param currentHeader + * The previous Header. This is used to find the parent + * section if there is one. Can be null. + */ + Header(int level, int lineNumber, String heading, Header currentHeader) { + this.lineNumber = lineNumber; + this.level = level; + this.heading = cleanHeader(heading); + // Heading Tree + setParent(currentHeader); + } + + private void setParent(Header currentHeader) { + if (currentHeader == null) { + parent = null; + return; + } + if (currentHeader.level < level) { + parent = currentHeader; + parent.subHeaders.add(this); + return; + } + setParent(currentHeader.parent); + } + + public Header getParent() { + return parent; + } + + /** + * Sub-sections. May be zero-length, never null. + */ + public List
getSubHeaders() { + return subHeaders; + } + + @Override + public String toString() { + return heading; + } + + public int getLevel() { + return level; + } + } + + /** + * The raw text, broken up into individual lines. + */ + private List lines; + + /** + * The raw text, broken up into individual lines. + */ + public List getText() { + return Collections.unmodifiableList(lines); + } + + public enum KLineType { + NORMAL, H1, H2, H3, H4, H5, H6, BLANK, + // TODO LIST, BLOCKQUOTE, + /** A line marking Markdown info about the preceding line, e.g. ====== */ + MARKER, + /** A line containing meta-data, e.g. title: My Page */ + META + } + + /** + * Information about each line. + */ + private List lineTypes; + private Map pageObjects = new HashMap(); + + // TODO meta-data, footnotes, tables, link & image attributes + private static Pattern multiMarkdownTag = Pattern.compile("^([\\w].*):(.*)"); + private Map multiMarkdownTags = new HashMap(); + + // Regular expression for Github support + private static Pattern githubURLDetection = Pattern.compile("((https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|])"); + + /** + * The top-level headers. FIXME handle documents which have a 2nd level + * header before any 1st level ones + */ + private final List
level1Headers = new ArrayList
(); + private final IPreferenceStore pStore; + + /** + * Create a page. + * + * @param text + */ + public MarkdownPage(String text) { + pStore = Activator.getDefault().getPreferenceStore(); + setText(text); + } + + /** + * Reset the text for this page. + * + * @param text + */ + private void setText(String text) { + // Get lines + lines = StringMethods.splitLines(text); + // Clean out old + level1Headers.clear(); + lineTypes = new ArrayList(lines.size()); + pageObjects.clear(); + // Dummy level-1 header in case there are none + Header dummyTopHeader = new Header(1, 0, "", null); + level1Headers.add(dummyTopHeader); + Header currentHeader = dummyTopHeader; + // Identify line types + int lineNum = 0; + + // Check if we should support the Multi-Markdown Metadata + boolean multiMarkdownMetadataSupport = + pStore.getBoolean(MarkdownPreferencePage.PREF_MULTIMARKDOWN_METADATA); + + // Multi-markdown header + if (multiMarkdownMetadataSupport) { + // The key is the text before the colon, and the data is the text + // after the + // colon. In the above example, notice that there are two lines of + // information + // for the Author key. If you end a line with “space-space-newline”, + // the newline + // will be included when converted to other formats. + // + // There must not be any whitespace above the metadata, and the + // metadata block + // ends with the first whitespace only line. The metadata is + // stripped from the + // document before it is passed on to the syntax parser. + + // + // Check if the Metdatas are valid + // + boolean validMetadata = true; + for (lineNum = 0; lineNum < lines.size(); lineNum++) { + String line = lines.get(lineNum); + if (Utils.isBlank(line)) { + break; + } + Matcher m = multiMarkdownTag.matcher(line); + if (!m.find()) { + if (lineNum == 0) { + // No MultiMarkdown metadata + validMetadata = false; + break; + } else if (!line.matches("^\\s.*\n")) { + // The next line was not intended (ie. it does not start + // with a whitespace) + validMetadata = false; + break; + } + } + } + + // Valid Metadatas have been found. We need to retrieve these keys/values. + if (validMetadata) { + String data = ""; + String tag = ""; + for (lineNum = 0; lineNum < lines.size(); lineNum++) { + String line = lines.get(lineNum); + if (Utils.isBlank(line)) { + break; + } + Matcher m = multiMarkdownTag.matcher(line); + if (!m.find()) { + if (lineNum == 0) { + break; + } + // Multi-line tag + lineTypes.add(KLineType.META); + data += StrUtils.LINEEND + line.trim(); + multiMarkdownTags.put(tag, data); + } else { + lineTypes.add(KLineType.META); + tag = m.group(0); + data = m.group(1).trim(); + if (m.group(1).endsWith(line)) + multiMarkdownTags.put(tag, data); + } + } + } else { + lineNum = 0; + } + } + for (; lineNum < lines.size(); lineNum++) { + String line = lines.get(lineNum); + // Headings + int h = numHash(line); + String hLine = line; + int hLineNum = lineNum; + int underline = -1; + if (lineNum != 0) { + underline = just(line, '=') ? 1 : just(line, '-') ? 2 : -1; + } + if (underline != -1) { + h = underline; + hLineNum = lineNum - 1; + hLine = lines.get(lineNum - 1); + lineTypes.set(hLineNum, KLineType.values()[h]); + lineTypes.add(KLineType.MARKER); + } + // Create a Header object + if (h > 0) { + if (underline == -1) + lineTypes.add(KLineType.values()[h]); + Header header = new Header(h, hLineNum, hLine, currentHeader); + if (h == 1) { + level1Headers.add(header); + } + pageObjects.put(hLineNum, header); + currentHeader = header; + continue; + } + // TODO List + // TODO Block quote + // Blank line + if (Utils.isBlank(line)) { + lineTypes.add(KLineType.BLANK); + continue; + } + // Normal + lineTypes.add(KLineType.NORMAL); + } // end line-loop + // Remove dummy header? + if (dummyTopHeader.getSubHeaders().size() == 0) { + level1Headers.remove(dummyTopHeader); + } + + boolean githubSyntaxSupport = + pStore.getBoolean(MarkdownPreferencePage.PREF_GITHUB_SYNTAX); + if (githubSyntaxSupport) { + /* + * Support Code block + */ + boolean inCodeBlock = false; + for (lineNum = 0; lineNum < lines.size(); lineNum++) { + String line = lines.get(lineNum); + // Found the start or end of a code block + if (line.matches("^```.*\n")) { + // We reverse the boolean value + inCodeBlock = !inCodeBlock; + + // We force the line to be blank. But we mark it as normal + // to prevent to be stripped + lines.set(lineNum, "\n"); + lineTypes.set(lineNum, KLineType.NORMAL); + continue; + } + if (inCodeBlock) { + lines.set(lineNum, " " + line); + } + } + + /* + * Support for URL Detection + * We search for links that are not captured by Markdown syntax + */ + for (lineNum = 0; lineNum < lines.size(); lineNum++) { + String line = lines.get(lineNum); + // When a link has been replaced we need to scan again the string + // as the offsets have changed (we add '<' and '>' to the link to + // be interpreted by the markdown library) + boolean urlReplaced; + + do { + urlReplaced = false; + Matcher m = githubURLDetection.matcher(line); + while (m.find()) { + // Ignore the URL following the format + if ((m.start() - 1 >= 0) && (m.end() < line.length()) && + (line.charAt(m.start() - 1) == '<') && + (line.charAt(m.end()) == '>')) + { + continue; + } + + // Ignore the URL following the format [description](link) + if ((m.start() - 2 >= 0) && (m.end() < line.length()) && + (line.charAt(m.start() - 2) == ']') && + (line.charAt(m.start() - 1) == '(') && + (line.charAt(m.end()) == ')')) + { + continue; + } + + // Ignore the URL following the format [description](link "title") + if ((m.start() - 2 >= 0) && (m.end() + 1 < line.length()) && + (line.charAt(m.start() - 2) == ']') && + (line.charAt(m.start() - 1) == '(') && + (line.charAt(m.end()) == ' ') && + (line.charAt(m.end() + 1) == '"')) + { + continue; + } + + if (m.start() - 1 >= 0) { + // Case when the link is at the beginning of the string + line = line.substring(0, m.start()) + "<" + m.group(0) + ">" + line.substring(m.end()); + } else { + line = "<" + m.group(0) + ">" + line.substring(m.end()); + } + + // We replaced the string in the array + lines.set(lineNum, line); + urlReplaced = true; + break; + } + } while (urlReplaced); + } + } + } + + /** + * @param line + * @param c + * @return true if line is just cs (and whitespace at the start/end) + */ + boolean just(String line, char c) { + return line.matches("\\s*"+c+"+\\s*"); + } + + /** + * @param line + * @return The number of # symbols prepending the line. + */ + private int numHash(String line) { + for (int i = 0; i < line.length(); i++) { + if (line.charAt(i) != '#') + return i; + } + return line.length(); + } + + /** + * + * @param parent + * Can be null for top-level + * @return List of sub-headers. Never null. FIXME handle documents which + * have a 2nd level header before any 1st level ones + */ + public List
getHeadings(Header parent) { + if (parent == null) { + return Collections.unmodifiableList(level1Headers); + } + return Collections.unmodifiableList(parent.subHeaders); + } + + // public WebPage getWebPage() { + // WebPage page = new WebPage(); + // // Add the lines, one by one + // boolean inParagraph = false; + // for (int i=0; i"); + // line = cleanHeader(line); + // page.addText("<"+type+">"+line+""); + // continue; + // case MARKER: // Ignore + // continue; + // // TODO List? + // // TODO Block quote? + // } + // // Paragraph end? + // if (Utils.isBlank(line)) { + // if (inParagraph) page.addText("

"); + // continue; + // } + // // Paragraph start? + // if (!inParagraph) { + // page.addText("

"); + // inParagraph = true; + // } + // // Plain text + // page.addText(line); + // } + // return page; + // } + + /** + * Get the HTML for this page. Uses the MarkdownJ project. + */ + public String html() { + // Section numbers?? + boolean sectionNumbers = pStore + .getBoolean(MarkdownPreferencePage.PREF_SECTION_NUMBERS); + // Chop out multi-markdown header + StringBuilder sb = new StringBuilder(); + assert lines.size() == lineTypes.size(); + for (int i = 0, n = lines.size(); i < n; i++) { + KLineType type = lineTypes.get(i); + if (type == KLineType.META) + continue; + String line = lines.get(i); + if (sectionNumbers && isHeader(type) && line.contains("$section")) { + // TODO Header section = headers.get(i); + // String secNum = section.getSectionNumber(); + // line.replace("$section", secNum); + } + sb.append(line); + } + String text = sb.toString(); + // Use external converter? + final String cmd = pStore + .getString(MarkdownPreferencePage.PREF_MARKDOWN_COMMAND); + if (Utils.isBlank(cmd) + || (cmd.startsWith("(") && cmd.contains("MarkdownJ"))) { + // Use MarkdownJ + MarkdownProcessor markdown = new MarkdownProcessor(); + // MarkdownJ doesn't convert £s for some reason + text = text.replace("£", "£"); + String html = markdown.markdown(text); + return html; + } + // Attempt to run external command + try { + final File md = File.createTempFile("tmp", ".md"); + FileUtils.write(md, text); + Process process = new Process(cmd+" "+md.getAbsolutePath()); + process.run(); + int ok = process.waitFor(10000); + if (ok != 0) throw new FailureException(cmd+" failed:\n"+process.getError()); + String html = process.getOutput(); + FileUtils.delete(md); + return html; + } catch (Exception e) { + throw Utils.runtime(e); + } + } + + /** + * @param type + * @return + */ + private boolean isHeader(KLineType type) { + return type == KLineType.H1 || type == KLineType.H2 + || type == KLineType.H3 || type == KLineType.H4 + || type == KLineType.H5 || type == KLineType.H6; + } + + /** + * Return the raw text of this page. + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + for (String line : lines) { + sb.append(line); + } + return sb.toString(); + } + + /** + * Line type information for the raw text. + * + * @return + */ + public List getLineTypes() { + return Collections.unmodifiableList(lineTypes); + } + + /** + * @param line + * @return + */ + public Object getPageObject(int line) { + return pageObjects.get(line); + } + +} diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/pagemodel/MarkdownPageTest.java b/bundles/winterwell.markdown/src/winterwell/markdown/pagemodel/MarkdownPageTest.java new file mode 100644 index 000000000..244d43789 --- /dev/null +++ b/bundles/winterwell.markdown/src/winterwell/markdown/pagemodel/MarkdownPageTest.java @@ -0,0 +1,30 @@ +package winterwell.markdown.pagemodel; + +import java.io.File; +import java.util.List; + +import winterwell.markdown.pagemodel.MarkdownPage.Header; +import winterwell.utils.io.FileUtils; + + + +public class MarkdownPageTest //extends TestCase +{ + + public static void main(String[] args) { + MarkdownPageTest mpt = new MarkdownPageTest(); + mpt.testGetHeadings(); + } + + public void testGetHeadings() { + // problem caused by a line beginning --, now fixed + String txt = FileUtils.read(new File( + "/home/daniel/winterwell/companies/DTC/projects/DTC-bayes/report1.txt")); + MarkdownPage p = new MarkdownPage(txt); + List

h1s = p.getHeadings(null); + Header h1 = h1s.get(0); + List
h2s = h1.getSubHeaders(); + assert h2s.size() > 2; + } + +} diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/preferences/MarkdownPreferencePage.java b/bundles/winterwell.markdown/src/winterwell/markdown/preferences/MarkdownPreferencePage.java new file mode 100644 index 000000000..36dadbc4c --- /dev/null +++ b/bundles/winterwell.markdown/src/winterwell/markdown/preferences/MarkdownPreferencePage.java @@ -0,0 +1,214 @@ +package winterwell.markdown.preferences; + +import org.eclipse.jface.preference.BooleanFieldEditor; +import org.eclipse.jface.preference.ColorFieldEditor; +import org.eclipse.jface.preference.FieldEditor; +import org.eclipse.jface.preference.FieldEditorPreferencePage; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.PreferenceConverter; +import org.eclipse.jface.preference.StringFieldEditor; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; + +import winterwell.markdown.Activator; + +/** + * This class represents a preference page that + * is contributed to the Preferences dialog. By + * subclassing FieldEditorPreferencePage, we + * can use the field support built into JFace that allows + * us to create a page that is small and knows how to + * save, restore and apply itself. + *

+ * This page is used to modify preferences only. They + * are stored in the preference store that belongs to + * the main plug-in class. That way, preferences can + * be accessed directly via the preference store. + */ + +public class MarkdownPreferencePage + extends FieldEditorPreferencePage + implements IWorkbenchPreferencePage { + + public static final String PREF_FOLDING = "Pref_Folding"; + public static final String PREF_WORD_WRAP = "Pref_WordWrap"; + public static final String PREF_TASK_TAGS = "Pref_TaskTagsOn"; + public static final String PREF_TASK_TAGS_DEFINED = "Pref_TaskTags"; + public static final String PREF_SECTION_NUMBERS = "Pref_SectionNumbers"; + + public static final String PREF_MARKDOWN_COMMAND = "Pref_Markdown_Command"; + private static final String MARKDOWNJ = "(use built-in MarkdownJ converter)"; + + + public static final String PREF_DEFUALT = "Pref_Default"; + public static final String PREF_COMMENT = "Pref_Comment"; + public static final String PREF_HEADER = "Pref_Header"; + public static final String PREF_LINK = "Pref_Link"; + public static final String PREF_CODE = "Pref_Code"; + public static final String PREF_CODE_BG = "Pref_Code_Background"; + + public static final String PREF_GITHUB_SYNTAX = "Pref_Github_Syntax"; + public static final String PREF_MULTIMARKDOWN_METADATA = "Pref_MultiMarkdown_Metadata"; + + private static final RGB DEF_DEFAULT = new RGB(0, 0, 0); + private static final RGB DEF_COMMENT = new RGB(128, 0, 0); + private static final RGB DEF_HEADER = new RGB(0, 128, 0); + private static final RGB DEF_LINK = new RGB(106, 131, 199); + private static final RGB DEF_CODE = new RGB(0, 0, 0); + private static final RGB DEF_CODE_BG = new RGB(244,244,244); + + public MarkdownPreferencePage() { + super(GRID); + IPreferenceStore pStore = Activator.getDefault().getPreferenceStore(); + setDefaultPreferences(pStore); + setPreferenceStore(pStore); + setDescription("Settings for the Markdown text editor. See also the general text editor preferences."); + } + + public static void setDefaultPreferences(IPreferenceStore pStore) { + pStore.setDefault(PREF_WORD_WRAP, false); + pStore.setDefault(PREF_FOLDING, true); + pStore.setDefault(PREF_TASK_TAGS, true); + pStore.setDefault(PREF_TASK_TAGS_DEFINED, "TODO,FIXME,??"); + pStore.setDefault(PREF_MARKDOWN_COMMAND, MARKDOWNJ); + pStore.setDefault(PREF_SECTION_NUMBERS, true); + pStore.setDefault(PREF_GITHUB_SYNTAX, true); + pStore.setDefault(PREF_MULTIMARKDOWN_METADATA, false); + + PreferenceConverter.setDefault(pStore, PREF_DEFUALT, DEF_DEFAULT); + PreferenceConverter.setDefault(pStore, PREF_COMMENT, DEF_COMMENT); + PreferenceConverter.setDefault(pStore, PREF_HEADER, DEF_HEADER); + PreferenceConverter.setDefault(pStore, PREF_LINK, DEF_LINK); + PreferenceConverter.setDefault(pStore, PREF_CODE, DEF_CODE); + PreferenceConverter.setDefault(pStore, PREF_CODE_BG, DEF_CODE_BG); + } + + /** + * Creates the field editors. Field editors are abstractions of + * the common GUI blocks needed to manipulate various types + * of preferences. Each field editor knows how to save and + * restore itself. + */ + @Override + public void createFieldEditors() { + // Word wrap + BooleanFieldEditor fd = new BooleanFieldEditor(PREF_WORD_WRAP, + "Soft word wrapping \r\n" ++"Note: may cause line numbers and related \r\n" + + "functionality to act a bit strangely", + getFieldEditorParent()); + addField(fd); + // Task tags + fd = new BooleanFieldEditor(PREF_TASK_TAGS, + "Manage tasks using task tags \r\n" + + "If true, this will add and delete tags in sync with edits.", + getFieldEditorParent()); + addField(fd); + StringFieldEditor tags = new StringFieldEditor(PREF_TASK_TAGS_DEFINED, + "Task tags\nComma separated list of recognised task tags.", getFieldEditorParent()); + addField(tags); + // Code folding + fd = new BooleanFieldEditor(PREF_FOLDING, + "Document folding, a.k.a. outline support", + getFieldEditorParent()); + addField(fd); + // Command line +// addField(new DummyField() { +// protected void makeComponent(Composite parent) { +// Label label = new Label(parent, 0); +// label.setText("Hello!"); +// GridData gd = new GridData(100, 20); +// label.setLayoutData(gd); +// } +// }); + StringFieldEditor cmd = new StringFieldEditor(PREF_MARKDOWN_COMMAND, + "UNSTABLE: Command-line to run Markdown.\r\n" + + "This should take in a file and output to std-out.\n" + + "Leave blank to use the built-in Java converter.", getFieldEditorParent()); + addField(cmd); + + ColorFieldEditor def = new ColorFieldEditor(PREF_DEFUALT, "Default text", getFieldEditorParent()); + addField(def); + + ColorFieldEditor com = new ColorFieldEditor(PREF_COMMENT, "Comment", getFieldEditorParent()); + addField(com); + + ColorFieldEditor link = new ColorFieldEditor(PREF_LINK, "Link", getFieldEditorParent()); + addField(link); + + ColorFieldEditor head = new ColorFieldEditor(PREF_HEADER, "Header and List indicator", getFieldEditorParent()); + addField(head); + + ColorFieldEditor code = new ColorFieldEditor(PREF_CODE, "Code", getFieldEditorParent()); + addField(code); + + ColorFieldEditor codeBg = new ColorFieldEditor(PREF_CODE_BG, "Code Background", getFieldEditorParent()); + addField(codeBg); + + /* + * Fields for the preview window + */ + + // Github Syntax support + fd = new BooleanFieldEditor(PREF_GITHUB_SYNTAX, + "Support Github Syntax", + getFieldEditorParent()); + addField(fd); + + // Multi-Markdown support + fd = new BooleanFieldEditor(PREF_MULTIMARKDOWN_METADATA, + "Support Multi-Markdown Metadata", + getFieldEditorParent()); + addField(fd); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench) + */ + public void init(IWorkbench workbench) { + + } + + public static boolean wordWrap() { + IPreferenceStore pStore = Activator.getDefault().getPreferenceStore(); + if (! pStore.contains(MarkdownPreferencePage.PREF_WORD_WRAP)) { + return false; + } + return pStore.getBoolean(MarkdownPreferencePage.PREF_WORD_WRAP); + } + +} + +abstract class DummyField extends FieldEditor { + @Override + protected void adjustForNumColumns(int numColumns) { + // do nothing + } + @Override + protected void doFillIntoGrid(Composite parent, int numColumns) { + makeComponent(parent); + } + abstract protected void makeComponent(Composite parent); + + @Override + protected void doLoad() { + // + } + @Override + protected void doLoadDefault() { + // + } + + @Override + protected void doStore() { + // + } + + @Override + public int getNumberOfControls() { + return 1; + } + +} \ No newline at end of file diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/views/MarkdownPreview.java b/bundles/winterwell.markdown/src/winterwell/markdown/views/MarkdownPreview.java new file mode 100644 index 000000000..c10395316 --- /dev/null +++ b/bundles/winterwell.markdown/src/winterwell/markdown/views/MarkdownPreview.java @@ -0,0 +1,100 @@ +package winterwell.markdown.views; + + +import java.io.File; +import java.net.URI; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.swt.SWT; +import org.eclipse.swt.browser.Browser; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IPathEditorInput; +import org.eclipse.ui.part.ViewPart; + +import winterwell.markdown.editors.ActionBarContributor; +import winterwell.markdown.editors.MarkdownEditor; +import winterwell.markdown.pagemodel.MarkdownPage; + + + + +public class MarkdownPreview extends ViewPart { + + public static MarkdownPreview preview = null; + + private Browser viewer = null; + + /** + * The constructor. + */ + public MarkdownPreview() { + preview = this; + } + + /** + * This is a callback that will allow us + * to create the viewer and initialize it. + */ + @Override + public void createPartControl(Composite parent) { + viewer = new Browser(parent, SWT.MULTI); // | SWT.H_SCROLL | SWT.V_SCROLL + } + + + + + /** + * Passing the focus request to the viewer's control. + */ + @Override + public void setFocus() { + if (viewer==null) return; + viewer.setFocus(); + update(); + } + + public void update() { + if (viewer==null) return; + try { + IEditorPart editor = ActionBarContributor.getActiveEditor(); + if (!(editor instanceof MarkdownEditor)) { + viewer.setText(""); + return; + } + MarkdownEditor ed = (MarkdownEditor) editor; + MarkdownPage page = ed.getMarkdownPage(); + String html = page.html(); + html = addBaseURL(editor, html); + if (page != null) viewer.setText(html); + else viewer.setText(""); + } catch (Exception ex) { + // Smother + System.out.println(ex); + + if (viewer != null && !viewer.isDisposed()) + viewer.setText(ex.getMessage()); + } + } + + /** + * Adjust the URL base to be the file's directory. + * @param editor + * @param html + * @return + */ + private String addBaseURL(IEditorPart editor, String html) { + try { + IPathEditorInput input = (IPathEditorInput) editor.getEditorInput(); + IPath path = input.getPath(); + path = path.removeLastSegments(1); + File f = path.toFile(); + URI fileURI = f.toURI(); + String html2 = "\r\n"+html + +"\r\n"; + return html2; + } catch (Exception ex) { + return html; + } + } +} \ No newline at end of file diff --git a/features/com.lowagie.text.feature/.gitignore b/features/com.lowagie.text.feature/.gitignore new file mode 100644 index 000000000..46281dc83 --- /dev/null +++ b/features/com.lowagie.text.feature/.gitignore @@ -0,0 +1 @@ +/target/** diff --git a/features/com.lowagie.text.feature/.project b/features/com.lowagie.text.feature/.project new file mode 100644 index 000000000..d825fa3b8 --- /dev/null +++ b/features/com.lowagie.text.feature/.project @@ -0,0 +1,17 @@ + + + com.lowagie.text.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/features/com.lowagie.text.feature/build.properties b/features/com.lowagie.text.feature/build.properties new file mode 100644 index 000000000..82ab19c62 --- /dev/null +++ b/features/com.lowagie.text.feature/build.properties @@ -0,0 +1 @@ +bin.includes = feature.xml diff --git a/features/com.lowagie.text.feature/feature.xml b/features/com.lowagie.text.feature/feature.xml new file mode 100644 index 000000000..e5a23fa70 --- /dev/null +++ b/features/com.lowagie.text.feature/feature.xml @@ -0,0 +1,514 @@ + + + + + iText is a library that allows you to generate PDF files on the +fly. + + + + Copyright © 1999-2007 by Bruno Lowagie, Adolf Baeyensstraat 121, 9040 Gent, BELGIUM + + + + MOZILLA PUBLIC LICENSE + Version 1.1 + + --------------- + +1. Definitions. + + 1.0.1. "Commercial Use" means distribution or otherwise making the + Covered Code available to a third party. + + 1.1. "Contributor" means each entity that creates or contributes to + the creation of Modifications. + + 1.2. "Contributor Version" means the combination of the Original + Code, prior Modifications used by a Contributor, and the Modifications + made by that particular Contributor. + + 1.3. "Covered Code" means the Original Code or Modifications or the + combination of the Original Code and Modifications, in each case + including portions thereof. + + 1.4. "Electronic Distribution Mechanism" means a mechanism generally + accepted in the software development community for the electronic + transfer of data. + + 1.5. "Executable" means Covered Code in any form other than Source + Code. + + 1.6. "Initial Developer" means the individual or entity identified + as the Initial Developer in the Source Code notice required by Exhibit + A. + + 1.7. "Larger Work" means a work which combines Covered Code or + portions thereof with code not governed by the terms of this License. + + 1.8. "License" means this document. + + 1.8.1. "Licensable" means having the right to grant, to the maximum + extent possible, whether at the time of the initial grant or + subsequently acquired, any and all of the rights conveyed herein. + + 1.9. "Modifications" means any addition to or deletion from the + substance or structure of either the Original Code or any previous + Modifications. When Covered Code is released as a series of files, a + Modification is: + A. Any addition to or deletion from the contents of a file + containing Original Code or previous Modifications. + + B. Any new file that contains any part of the Original Code or + previous Modifications. + + 1.10. "Original Code" means Source Code of computer software code + which is described in the Source Code notice required by Exhibit A as + Original Code, and which, at the time of its release under this + License is not already Covered Code governed by this License. + + 1.10.1. "Patent Claims" means any patent claim(s), now owned or + hereafter acquired, including without limitation, method, process, + and apparatus claims, in any patent Licensable by grantor. + + 1.11. "Source Code" means the preferred form of the Covered Code for + making modifications to it, including all modules it contains, plus + any associated interface definition files, scripts used to control + compilation and installation of an Executable, or source code + differential comparisons against either the Original Code or another + well known, available Covered Code of the Contributor's choice. The + Source Code can be in a compressed or archival form, provided the + appropriate decompression or de-archiving software is widely available + for no charge. + + 1.12. "You" (or "Your") means an individual or a legal entity + exercising rights under, and complying with all of the terms of, this + License or a future version of this License issued under Section 6.1. + For legal entities, "You" includes any entity which controls, is + controlled by, or is under common control with You. For purposes of + this definition, "control" means (a) the power, direct or indirect, + to cause the direction or management of such entity, whether by + contract or otherwise, or (b) ownership of more than fifty percent + (50%) of the outstanding shares or beneficial ownership of such + entity. + +2. Source Code License. + + 2.1. The Initial Developer Grant. + The Initial Developer hereby grants You a world-wide, royalty-free, + non-exclusive license, subject to third party intellectual property + claims: + (a) under intellectual property rights (other than patent or + trademark) Licensable by Initial Developer to use, reproduce, + modify, display, perform, sublicense and distribute the Original + Code (or portions thereof) with or without Modifications, and/or + as part of a Larger Work; and + + (b) under Patents Claims infringed by the making, using or + selling of Original Code, to make, have made, use, practice, + sell, and offer for sale, and/or otherwise dispose of the + Original Code (or portions thereof). + + (c) the licenses granted in this Section 2.1(a) and (b) are + effective on the date Initial Developer first distributes + Original Code under the terms of this License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is + granted: 1) for code that You delete from the Original Code; 2) + separate from the Original Code; or 3) for infringements caused + by: i) the modification of the Original Code or ii) the + combination of the Original Code with other software or devices. + + 2.2. Contributor Grant. + Subject to third party intellectual property claims, each Contributor + hereby grants You a world-wide, royalty-free, non-exclusive license + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Contributor, to use, reproduce, modify, + display, perform, sublicense and distribute the Modifications + created by such Contributor (or portions thereof) either on an + unmodified basis, with other Modifications, as Covered Code + and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or + selling of Modifications made by that Contributor either alone + and/or in combination with its Contributor Version (or portions + of such combination), to make, use, sell, offer for sale, have + made, and/or otherwise dispose of: 1) Modifications made by that + Contributor (or portions thereof); and 2) the combination of + Modifications made by that Contributor with its Contributor + Version (or portions of such combination). + + (c) the licenses granted in Sections 2.2(a) and 2.2(b) are + effective on the date Contributor first makes Commercial Use of + the Covered Code. + + (d) Notwithstanding Section 2.2(b) above, no patent license is + granted: 1) for any code that Contributor has deleted from the + Contributor Version; 2) separate from the Contributor Version; + 3) for infringements caused by: i) third party modifications of + Contributor Version or ii) the combination of Modifications made + by that Contributor with other software (except as part of the + Contributor Version) or other devices; or 4) under Patent Claims + infringed by Covered Code in the absence of Modifications made by + that Contributor. + +3. Distribution Obligations. + + 3.1. Application of License. + The Modifications which You create or to which You contribute are + governed by the terms of this License, including without limitation + Section 2.2. The Source Code version of Covered Code may be + distributed only under the terms of this License or a future version + of this License released under Section 6.1, and You must include a + copy of this License with every copy of the Source Code You + distribute. You may not offer or impose any terms on any Source Code + version that alters or restricts the applicable version of this + License or the recipients' rights hereunder. However, You may include + an additional document offering the additional rights described in + Section 3.5. + + 3.2. Availability of Source Code. + Any Modification which You create or to which You contribute must be + made available in Source Code form under the terms of this License + either on the same media as an Executable version or via an accepted + Electronic Distribution Mechanism to anyone to whom you made an + Executable version available; and if made available via Electronic + Distribution Mechanism, must remain available for at least twelve (12) + months after the date it initially became available, or at least six + (6) months after a subsequent version of that particular Modification + has been made available to such recipients. You are responsible for + ensuring that the Source Code version remains available even if the + Electronic Distribution Mechanism is maintained by a third party. + + 3.3. Description of Modifications. + You must cause all Covered Code to which You contribute to contain a + file documenting the changes You made to create that Covered Code and + the date of any change. You must include a prominent statement that + the Modification is derived, directly or indirectly, from Original + Code provided by the Initial Developer and including the name of the + Initial Developer in (a) the Source Code, and (b) in any notice in an + Executable version or related documentation in which You describe the + origin or ownership of the Covered Code. + + 3.4. Intellectual Property Matters + (a) Third Party Claims. + If Contributor has knowledge that a license under a third party's + intellectual property rights is required to exercise the rights + granted by such Contributor under Sections 2.1 or 2.2, + Contributor must include a text file with the Source Code + distribution titled "LEGAL" which describes the claim and the + party making the claim in sufficient detail that a recipient will + know whom to contact. If Contributor obtains such knowledge after + the Modification is made available as described in Section 3.2, + Contributor shall promptly modify the LEGAL file in all copies + Contributor makes available thereafter and shall take other steps + (such as notifying appropriate mailing lists or newsgroups) + reasonably calculated to inform those who received the Covered + Code that new knowledge has been obtained. + + (b) Contributor APIs. + If Contributor's Modifications include an application programming + interface and Contributor has knowledge of patent licenses which + are reasonably necessary to implement that API, Contributor must + also include this information in the LEGAL file. + + (c) Representations. + Contributor represents that, except as disclosed pursuant to + Section 3.4(a) above, Contributor believes that Contributor's + Modifications are Contributor's original creation(s) and/or + Contributor has sufficient rights to grant the rights conveyed by + this License. + + 3.5. Required Notices. + You must duplicate the notice in Exhibit A in each file of the Source + Code. If it is not possible to put such notice in a particular Source + Code file due to its structure, then You must include such notice in a + location (such as a relevant directory) where a user would be likely + to look for such a notice. If You created one or more Modification(s) + You may add your name as a Contributor to the notice described in + Exhibit A. You must also duplicate this License in any documentation + for the Source Code where You describe recipients' rights or ownership + rights relating to Covered Code. You may choose to offer, and to + charge a fee for, warranty, support, indemnity or liability + obligations to one or more recipients of Covered Code. However, You + may do so only on Your own behalf, and not on behalf of the Initial + Developer or any Contributor. You must make it absolutely clear than + any such warranty, support, indemnity or liability obligation is + offered by You alone, and You hereby agree to indemnify the Initial + Developer and every Contributor for any liability incurred by the + Initial Developer or such Contributor as a result of warranty, + support, indemnity or liability terms You offer. + + 3.6. Distribution of Executable Versions. + You may distribute Covered Code in Executable form only if the + requirements of Section 3.1-3.5 have been met for that Covered Code, + and if You include a notice stating that the Source Code version of + the Covered Code is available under the terms of this License, + including a description of how and where You have fulfilled the + obligations of Section 3.2. The notice must be conspicuously included + in any notice in an Executable version, related documentation or + collateral in which You describe recipients' rights relating to the + Covered Code. You may distribute the Executable version of Covered + Code or ownership rights under a license of Your choice, which may + contain terms different from this License, provided that You are in + compliance with the terms of this License and that the license for the + Executable version does not attempt to limit or alter the recipient's + rights in the Source Code version from the rights set forth in this + License. If You distribute the Executable version under a different + license You must make it absolutely clear that any terms which differ + from this License are offered by You alone, not by the Initial + Developer or any Contributor. You hereby agree to indemnify the + Initial Developer and every Contributor for any liability incurred by + the Initial Developer or such Contributor as a result of any such + terms You offer. + + 3.7. Larger Works. + You may create a Larger Work by combining Covered Code with other code + not governed by the terms of this License and distribute the Larger + Work as a single product. In such a case, You must make sure the + requirements of this License are fulfilled for the Covered Code. + +4. Inability to Comply Due to Statute or Regulation. + + If it is impossible for You to comply with any of the terms of this + License with respect to some or all of the Covered Code due to + statute, judicial order, or regulation then You must: (a) comply with + the terms of this License to the maximum extent possible; and (b) + describe the limitations and the code they affect. Such description + must be included in the LEGAL file described in Section 3.4 and must + be included with all distributions of the Source Code. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + +5. Application of this License. + + This License applies to code to which the Initial Developer has + attached the notice in Exhibit A and to related Covered Code. + +6. Versions of the License. + + 6.1. New Versions. + Netscape Communications Corporation ("Netscape") may publish revised + and/or new versions of the License from time to time. Each version + will be given a distinguishing version number. + + 6.2. Effect of New Versions. + Once Covered Code has been published under a particular version of the + License, You may always continue to use it under the terms of that + version. You may also choose to use such Covered Code under the terms + of any subsequent version of the License published by Netscape. No one + other than Netscape has the right to modify the terms applicable to + Covered Code created under this License. + + 6.3. Derivative Works. + If You create or use a modified version of this License (which you may + only do in order to apply it to code which is not already Covered Code + governed by this License), You must (a) rename Your license so that + the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", + "MPL", "NPL" or any confusingly similar phrase do not appear in your + license (except to note that your license differs from this License) + and (b) otherwise make it clear that Your version of the license + contains terms which differ from the Mozilla Public License and + Netscape Public License. (Filling in the name of the Initial + Developer, Original Code or Contributor in the notice described in + Exhibit A shall not of themselves be deemed to be modifications of + this License.) + +7. DISCLAIMER OF WARRANTY. + + COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF + DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. + THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE + IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, + YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE + COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER + OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF + ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +8. TERMINATION. + + 8.1. This License and the rights granted hereunder will terminate + automatically if You fail to comply with terms herein and fail to cure + such breach within 30 days of becoming aware of the breach. All + sublicenses to the Covered Code which are properly granted shall + survive any termination of this License. Provisions which, by their + nature, must remain in effect beyond the termination of this License + shall survive. + + 8.2. If You initiate litigation by asserting a patent infringement + claim (excluding declatory judgment actions) against Initial Developer + or a Contributor (the Initial Developer or Contributor against whom + You file such action is referred to as "Participant") alleging that: + + (a) such Participant's Contributor Version directly or indirectly + infringes any patent, then any and all rights granted by such + Participant to You under Sections 2.1 and/or 2.2 of this License + shall, upon 60 days notice from Participant terminate prospectively, + unless if within 60 days after receipt of notice You either: (i) + agree in writing to pay Participant a mutually agreeable reasonable + royalty for Your past and future use of Modifications made by such + Participant, or (ii) withdraw Your litigation claim with respect to + the Contributor Version against such Participant. If within 60 days + of notice, a reasonable royalty and payment arrangement are not + mutually agreed upon in writing by the parties or the litigation claim + is not withdrawn, the rights granted by Participant to You under + Sections 2.1 and/or 2.2 automatically terminate at the expiration of + the 60 day notice period specified above. + + (b) any software, hardware, or device, other than such Participant's + Contributor Version, directly or indirectly infringes any patent, then + any rights granted to You by such Participant under Sections 2.1(b) + and 2.2(b) are revoked effective as of the date You first made, used, + sold, distributed, or had made, Modifications made by that + Participant. + + 8.3. If You assert a patent infringement claim against Participant + alleging that such Participant's Contributor Version directly or + indirectly infringes any patent where such claim is resolved (such as + by license or settlement) prior to the initiation of patent + infringement litigation, then the reasonable value of the licenses + granted by such Participant under Sections 2.1 or 2.2 shall be taken + into account in determining the amount or value of any payment or + license. + + 8.4. In the event of termination under Sections 8.1 or 8.2 above, + all end user license agreements (excluding distributors and resellers) + which have been validly granted by You or any distributor hereunder + prior to termination shall survive termination. + +9. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT + (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL + DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, + OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR + ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY + CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, + WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER + COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN + INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF + LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY + RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW + PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE + EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO + THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + +10. U.S. GOVERNMENT END USERS. + + The Covered Code is a "commercial item," as that term is defined in + 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer + software" and "commercial computer software documentation," as such + terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 + C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), + all U.S. Government End Users acquire Covered Code with only those + rights set forth herein. + +11. MISCELLANEOUS. + + This License represents the complete agreement concerning subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. This License shall be governed by + California law provisions (except to the extent applicable law, if + any, provides otherwise), excluding its conflict-of-law provisions. + With respect to disputes in which at least one party is a citizen of, + or an entity chartered or registered to do business in the United + States of America, any litigation relating to this License shall be + subject to the jurisdiction of the Federal Courts of the Northern + District of California, with venue lying in Santa Clara County, + California, with the losing party responsible for costs, including + without limitation, court costs and reasonable attorneys' fees and + expenses. The application of the United Nations Convention on + Contracts for the International Sale of Goods is expressly excluded. + Any law or regulation which provides that the language of a contract + shall be construed against the drafter shall not apply to this + License. + +12. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is + responsible for claims and damages arising, directly or indirectly, + out of its utilization of rights under this License and You agree to + work with Initial Developer and Contributors to distribute such + responsibility on an equitable basis. Nothing herein is intended or + shall be deemed to constitute any admission of liability. + +13. MULTIPLE-LICENSED CODE. + + Initial Developer may designate portions of the Covered Code as + "Multiple-Licensed". "Multiple-Licensed" means that the Initial + Developer permits you to utilize portions of the Covered Code under + Your choice of the NPL or the alternative licenses, if any, specified + by the Initial Developer in the file described in Exhibit A. + +EXHIBIT A -Mozilla Public License. + + ``The contents of this file are subject to the Mozilla Public License + Version 1.1 (the "License"); you may not use this file except in + compliance with the License. You may obtain a copy of the License at + http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + License for the specific language governing rights and limitations + under the License. + + The Original Code is ______________________________________. + + The Initial Developer of the Original Code is ________________________. + Portions created by ______________________ are Copyright (C) ______ + _______________________. All Rights Reserved. + + Contributor(s): ______________________________________. + + Alternatively, the contents of this file may be used under the terms + of the _____ license (the "[___] License"), in which case the + provisions of [______] License are applicable instead of those + above. If you wish to allow use of your version of this file only + under the terms of the [____] License and not to allow others to use + your version of this file under the MPL, indicate your decision by + deleting the provisions above and replace them with the notice and + other provisions required by the [___] License. If you do not delete + the provisions above, a recipient may use your version of this file + under either the MPL or the [___] License." + + [NOTE: The text of this Exhibit A may differ slightly from the text of + the notices in the Source Code files of the Original Code. You should + use the text of this Exhibit A rather than the text found in the + Original Code Source Code for Your Modifications.] + + + + + + + + + + + diff --git a/features/org.apache.lucene4.feature/.gitignore b/features/org.apache.lucene4.feature/.gitignore new file mode 100644 index 000000000..46281dc83 --- /dev/null +++ b/features/org.apache.lucene4.feature/.gitignore @@ -0,0 +1 @@ +/target/** diff --git a/features/org.apache.lucene4.feature/.project b/features/org.apache.lucene4.feature/.project new file mode 100644 index 000000000..14d6d133c --- /dev/null +++ b/features/org.apache.lucene4.feature/.project @@ -0,0 +1,17 @@ + + + org.apache.lucene4.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/features/org.apache.lucene4.feature/build.properties b/features/org.apache.lucene4.feature/build.properties new file mode 100644 index 000000000..82ab19c62 --- /dev/null +++ b/features/org.apache.lucene4.feature/build.properties @@ -0,0 +1 @@ +bin.includes = feature.xml diff --git a/features/org.apache.lucene4.feature/feature.xml b/features/org.apache.lucene4.feature/feature.xml new file mode 100644 index 000000000..3dd2c5011 --- /dev/null +++ b/features/org.apache.lucene4.feature/feature.xml @@ -0,0 +1,255 @@ + + + + + Apache Lucene is a high-performance, full-featured text search engine library written entirely in Java. It is a technology suitable for nearly any application that requires full-text search, especially cross-platform. + + + + Copyright © 2006 The Apache Software Foundation. + + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + + + + + + + + + + + diff --git a/features/org.simantics.eclipsec.launcher.feature/.project b/features/org.simantics.eclipsec.launcher.feature/.project new file mode 100644 index 000000000..31de9e105 --- /dev/null +++ b/features/org.simantics.eclipsec.launcher.feature/.project @@ -0,0 +1,17 @@ + + + org.simantics.eclipsec.launcher.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/features/org.simantics.eclipsec.launcher.feature/build.properties b/features/org.simantics.eclipsec.launcher.feature/build.properties new file mode 100644 index 000000000..b91d19e0e --- /dev/null +++ b/features/org.simantics.eclipsec.launcher.feature/build.properties @@ -0,0 +1,15 @@ +############################################################################### +# Copyright (c) 2007, 2015 Association for Decentralized Information Management +# in Industry THTH ry. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# VTT Technical Research Centre of Finland - initial API and implementation +# Semantum Oy - update to Eclipse Mars.1 (4.5.1) +############################################################################### +bin.includes=features.xml +root.win32.win32.x86=bin/win32/win32/x86 +root.win32.win32.x86_64=bin/win32/win32/x86_64 \ No newline at end of file diff --git a/features/org.simantics.eclipsec.launcher.feature/feature.xml b/features/org.simantics.eclipsec.launcher.feature/feature.xml new file mode 100644 index 000000000..3c5005e4d --- /dev/null +++ b/features/org.simantics.eclipsec.launcher.feature/feature.xml @@ -0,0 +1,31 @@ + + + + + + This is a build-time feature that only includes standard eclipsec launcher executables for platforms where available since the standard org.eclipse.equinox.launcher feature does not include these. The eclipsec executables are valuable for debugging purposes where native code crashes the whole program. With the normal launcher all your possible debug information will be lost forever. Using eclipsec you will see everything put in standard output and standard error in the same very console where you launched eclipsec. + + + + [Enter Copyright Description here.] + + + + [Enter License Description here.] + + + diff --git a/features/org.simantics.sdk.feature/feature.xml b/features/org.simantics.sdk.feature/feature.xml index ed5ed345c..41c08423a 100644 --- a/features/org.simantics.sdk.feature/feature.xml +++ b/features/org.simantics.sdk.feature/feature.xml @@ -134,11 +134,7 @@ + version="0.0.0"/> - + com.lowagie.text.feature + org.apache.lucene4.feature org.simantics.browsing.ui.feature org.simantics.charts.feature org.simantics.data.feature @@ -22,6 +24,7 @@ org.simantics.document.base.feature org.simantics.document.linking.feature org.simantics.document.swt.feature + org.simantics.eclipsec.launcher.feature org.simantics.event.feature org.simantics.export.feature org.simantics.g2d.feature