I would like to get started on a new Spoofax project by cloning an existing project, i.e. duplicating the directory (forking a repository) and renaming the language, file extension, etc. What is the best way to do that?

Asked by Eelco Visser on 15 January 2013 at 18:08

Currently, the only way is to manually rename several names used in the project. In Spoofax there are 4 different names that are used in several files, that need to be renamed:

  • Project name
  • Language name
  • Plugin ID (also called package name)
  • Extension

I will be using ProjectName, LanguageName, PluginID and ext to denote the old names and NewProjectName, NewLanguageName, NewPluginID and newext to denote the new renamed names. Note that capitalization matters! The following operations need to be performed to rename.

Deletions

The following directories should be deleted:

  • .cache
  • bin
  • include
  • lib
  • lib-refactoring

Changes

The following files need to be changed. For each file first the old names are shown and after that the renamed names.

build.main.xml

<project name="LanguageName" default="all">
    
    <!-- Key input modules -->
    <property name="sdfmodule" value="LanguageName"/>
    <property name="metasdfmodule" value="Stratego-LanguageName"/>
    <property name="esvmodule" value="LanguageName"/>
    <property name="strmodule" value="languagename"/>

<project name="NewLanguageName" default="all">
    
    <!-- Key input modules -->
    <property name="sdfmodule" value="NewLanguageName"/>
    <property name="metasdfmodule" value="Stratego-NewLanguageName"/>
    <property name="esvmodule" value="NewLanguageName"/>
    <property name="strmodule" value="newlanguagename"/>

plugin.xml

<plugin>
   <extension point="org.eclipse.imp.runtime.languageDescription">
      <language extensions="ext" description="LanguageName" language="LanguageName" derivedFrom="DynamicRoot" validator="PluginID.LanguageNameValidator"  validatorClass="PluginID.LanguageNameValidator"></language>
   </extension>
   <extension id="PluginID.parser" name="LanguageName Parser" point="org.eclipse.imp.runtime.parser">
      <parser class="PluginID.LanguageNameParseController" language="LanguageName">
      </parser>
   </extension>    
</plugin>

<plugin>
   <extension point="org.eclipse.imp.runtime.languageDescription">
      <language extensions="newext" description="NewLanguageName" language="NewLanguageName" derivedFrom="DynamicRoot" validator="NewPluginID.NewLanguageNameValidator" validatorClass="NewPluginID.NewLanguageNameValidator"></language>
   </extension>
   <extension id="NewPluginID.parser" name="NewLanguageName Parser" point="org.eclipse.imp.runtime.parser">
      <parser class="NewPluginID.NewLanguageNameParseController" language="NewLanguageName">
      </parser>
   </extension>    
</plugin>

META-INF/MANIFEST.MF

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: LanguageName Plug-in
Bundle-SymbolicName: PluginID; singleton:=true
Bundle-Version: 1.0.0
Bundle-Activator: PluginID.Activator
Import-Package: org.osgi.framework;version="1.3.0"
Require-Bundle: org.eclipse.core.runtime,
  org.eclipse.core.resources,
  org.eclipse.imp.runtime,
  org.eclipse.ui,
  lpg.runtime,
  org.eclipse.jface.text,
  org.eclipse.ui.editors,
  org.eclipse.ui.workbench.texteditor,
  org.strategoxt.imp.runtime,
  org.spoofax.jsglr,
  org.strategoxt.strj
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Bundle-ActivationPolicy: lazy
Export-Package: PluginID
Eclipse-RegisterBuddy: org.strategoxt.imp.runtime

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: NewLanguageName Plug-in
Bundle-SymbolicName: NewPluginID; singleton:=true
Bundle-Version: 1.0.0
Bundle-Activator: NewPluginID.Activator
Import-Package: org.osgi.framework;version="1.3.0"
Require-Bundle: org.eclipse.core.runtime,
  org.eclipse.core.resources,
  org.eclipse.imp.runtime,
  org.eclipse.ui,
  lpg.runtime,
  org.eclipse.jface.text,
  org.eclipse.ui.editors,
  org.eclipse.ui.workbench.texteditor,
  org.strategoxt.imp.runtime,
  org.spoofax.jsglr,
  org.strategoxt.strj
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Bundle-ActivationPolicy: lazy
Export-Package: NewPluginID
Eclipse-RegisterBuddy: org.strategoxt.imp.runtime

.externalToolBuilders/LanguageName build.main.xml.launch

<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/ProjectName/build.main.xml}"/>

<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/ProjectName}"/>

<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/NewProjectName/build.main.xml}"/>

<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/NewProjectName}"/>

.externalToolBuilders/LanguageName build.main.xml.launch

  <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="ProjectName"/>
  <stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/ProjectName/build.main.xml}"/>

  <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="NewProjectName"/>
  <stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/NewProjectName/build.main.xml}"/>

editor/LanguageName.main.esv

module LanguageName.main

imports LanguageName-Builders LanguageName-Refactorings LanguageName-Colorer LanguageName-Completions LanguageName-Folding LanguageName-Outliner LanguageName-References LanguageName-Syntax

language General properties

  name          : LanguageName
  id            : PluginID
  extends       : Root
                  
  description   : "Spoofax/IMP-generated editor for the LanguageName language"
  url           : http://strategoxt.org
                  
  extensions    : ext
  table         : include/LanguageName.tbl
  start symbols : Start

module NewLanguageName.main

imports LanguageName-Builders LanguageName-Refactorings LanguageName-Colorer LanguageName-Completions LanguageName-Folding LanguageName-Outliner LanguageName-References LanguageName-Syntax

language General properties

  name          : NewLanguageName
  id            : NewPluginID
  extends       : Root
                  
  description   : "Spoofax/IMP-generated editor for the LanguageName language"
  url           : http://strategoxt.org
                  
  extensions    : newext
  table         : include/NewLanguageName.tbl
  start symbols : Start

syntax/LanguageName.SDF

module LanguageName

module NewLanguageName

trans/languagename.str

module languagename

module newlanguagename

editor/LanguageName-Refactorings.esv

pretty-print : pp-languagename-string

pretty-print : pp-newlanguagename-string

editor/LanguageName-Builders.esv

provider : include/languagename.ctree
provider : include/languagename-java.jar

provider : include/newlanguagename.ctree
provider : include/newlanguagename-java.jar

editor/java/PluginID/Activator.java

package PluginID;

import org.eclipse.imp.preferences.PreferencesService;
import org.eclipse.imp.runtime.PluginBase;
import org.osgi.framework.BundleContext;

public class Activator extends PluginBase 
{ 
  public static final String kPluginID = "LanguageName";

  public static final String kLanguageName = "LanguageName";

package NewPluginID;

import org.eclipse.imp.preferences.PreferencesService;
import org.eclipse.imp.runtime.PluginBase;
import org.osgi.framework.BundleContext;

public class Activator extends PluginBase 
{ 
  public static final String kPluginID = "NewLanguageName";

  public static final String kLanguageName = "NewLanguageName";

editor/java/PluginID/LanguageNameParseController.java

package PluginID;

package NewPluginID;

editor/java/PluginID/LanguageNameValidator.java

package PluginID;

package NewPluginID;

editor/java/PluginID/strategies/InteropRegisterer.java

package PluginID.strategies;

package NewPluginID.strategies;

editor/java/PluginID/strategies/InteropRegisterer.java

package PluginID.strategies;

package NewPluginID.strategies;

editor/java/PluginID/strategies/InteropRegisterer.java

package PluginID.strategies;

package NewPluginID.strategies;

Renames

The following directores need to be renamed:

  • editor/java/PluginID -> editor/java/NewPluginID

The following files need to be renamed:

  • editor/LanguageName.main.esv -> editor/NewLanguageName.main.esv
  • syntax/LanguageName.pp -> syntax/NewLanguageName.pp
  • syntax/LanguageName.sdf -> syntax/NewLanguageName.sdf
  • Your other SDF files may need to be updated to use the new module name.
  • trans/languagename.str -> trans/newlanguagename.str
  • Your other Stratego files may need to be updated to use the new module name.

Conclusion

If I missed any changes or renames please correct me.
Most of these changes can be performed using project wide find & replace in Eclipse, be careful with capitalization though.
Renaming a project in Spoofax is hell and needs to be fixed. Hopefully we can use this answer to fix it some day!

Answered by Gabriƫl Konat on 16 January 2013 at 12:14