mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-24 03:52:50 -06:00
added daniels' version of the Java editor
This commit is contained in:
29
src/JavaGUI2/LICENCE_jargs
Normal file
29
src/JavaGUI2/LICENCE_jargs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
Copyright (c) 2001-2003 Steve Purcell.
|
||||||
|
Copyright (c) 2002 Vidar Holen.
|
||||||
|
Copyright (c) 2002 Michal Ceresna.
|
||||||
|
Copyright (c) 2005 Ewan Mellor.
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met: Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer. Redistributions in
|
||||||
|
binary form must reproduce the above copyright notice, this list of
|
||||||
|
conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution. Neither the name of the copyright
|
||||||
|
holder nor the names of its contributors may be used to endorse or promote
|
||||||
|
products derived from this software without specific prior written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
3
src/JavaGUI2/ManifestMain.txt
Normal file
3
src/JavaGUI2/ManifestMain.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Manifest-Version: 1.0
|
||||||
|
Main-Class: de.uka.ilkd.key.ocl.gf.GFEditor2
|
||||||
|
Class-Path: log4j-1.2.8.jar jargs-1.0.jar
|
||||||
172
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/AbstractProber.java
Normal file
172
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/AbstractProber.java
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
package de.uka.ilkd.key.ocl.gf;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class that offers a basic readGfEdit method with a lot of
|
||||||
|
* hot spots where subclasses can plug in
|
||||||
|
* @author daniels
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
abstract class AbstractProber {
|
||||||
|
protected final BufferedReader fromProc;
|
||||||
|
protected final BufferedWriter toProc;
|
||||||
|
protected static Logger logger = Logger.getLogger(AbstractProber.class.getName());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A constructor which sets some fields
|
||||||
|
* @param fromGf the stdout from the GF process
|
||||||
|
* @param toGf the stdin from the GF process
|
||||||
|
*/
|
||||||
|
public AbstractProber(BufferedReader fromGf, BufferedWriter toGf) {
|
||||||
|
this.fromProc = fromGf;
|
||||||
|
this.toProc = toGf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reads the hmsg part
|
||||||
|
* @param readresult the first line
|
||||||
|
* @return the first line of the next XML child.
|
||||||
|
* if no hmsg is present @see readresult is returned.
|
||||||
|
*/
|
||||||
|
protected String readHmsg(String readresult) {
|
||||||
|
if (readresult.equals("<hmsg>")) {
|
||||||
|
skipChild("<hmsg>");
|
||||||
|
try {
|
||||||
|
String next = fromProc.readLine();
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("2 " + next);
|
||||||
|
}
|
||||||
|
return next;
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println("Could not read from external process:\n" + e);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return readresult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reads the linearization subtree.
|
||||||
|
* The first line should be already read
|
||||||
|
* @param readresult the first line with the opening tag
|
||||||
|
*/
|
||||||
|
protected void readLinearizations(String readresult) {
|
||||||
|
skipChild("<linearizations>");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Reads the tree child of the XML from beginning to end */
|
||||||
|
protected void readTree() {
|
||||||
|
skipChild("<tree>");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Reads the message child of the XML from beginning to end */
|
||||||
|
protected void readMessage() {
|
||||||
|
skipChild("<message>");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Reads the menu child of the XML from beginning to end */
|
||||||
|
protected void readMenu() {
|
||||||
|
skipChild("<menu>");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reads the output from GF starting with >gfedit<
|
||||||
|
* and last reads >/gfedit<.
|
||||||
|
*/
|
||||||
|
protected void readGfedit() {
|
||||||
|
try {
|
||||||
|
String next = "";
|
||||||
|
//read <gfedit>
|
||||||
|
String readresult = fromProc.readLine();
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("1 " + next);
|
||||||
|
}
|
||||||
|
//read either <hsmg> or <lineatization>
|
||||||
|
readresult = fromProc.readLine();
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("1 " + next);
|
||||||
|
}
|
||||||
|
|
||||||
|
next = readHmsg(readresult);
|
||||||
|
|
||||||
|
//in case there comes sth. unexpected before <linearizations>
|
||||||
|
//usually the while body is never entered
|
||||||
|
// %%%
|
||||||
|
while ((next!=null)&&((next.length()==0)||(!next.trim().equals("<linearizations>")))) {
|
||||||
|
next = fromProc.readLine();
|
||||||
|
if (next!=null){
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("1 " + next);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
readLinearizations(next);
|
||||||
|
readTree();
|
||||||
|
readMessage();
|
||||||
|
readMenu();
|
||||||
|
|
||||||
|
for (int i=0; i<3 && !next.equals(""); i++){
|
||||||
|
next = fromProc.readLine();
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("1 " + next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println("Could not read from external process:\n" + e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the output from GF until the ending tag corresponding to the
|
||||||
|
* given opening tag is read.
|
||||||
|
* @param opening tag in the format of >gfinit<
|
||||||
|
*/
|
||||||
|
protected void skipChild(String opening) {
|
||||||
|
String closing = (new StringBuffer(opening)).insert(1, '/').toString();
|
||||||
|
try {
|
||||||
|
String nextRead = fromProc.readLine();
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("3 " + nextRead);
|
||||||
|
}
|
||||||
|
while (!nextRead.trim().equals(closing)) {
|
||||||
|
nextRead = fromProc.readLine();
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("3 " + nextRead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println("Could not read from external process:\n" + e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* send a command to GF
|
||||||
|
* @param text the command, exactly the string that is going to be sent
|
||||||
|
*/
|
||||||
|
protected void send(String text) {
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("## send: '" + text + "'");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
toProc.write(text, 0, text.length());
|
||||||
|
toProc.newLine();
|
||||||
|
toProc.flush();
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println("Could not write to external process " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
30
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/AstNodeData.java
Normal file
30
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/AstNodeData.java
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Created on 27.04.2005
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package de.uka.ilkd.key.ocl.gf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hdaniels
|
||||||
|
* An object of this type knows how it self should be rendered,
|
||||||
|
* via Printname how its children should be rendered.
|
||||||
|
* This means the tooltip information it got from there.
|
||||||
|
*/
|
||||||
|
interface AstNodeData {
|
||||||
|
/**
|
||||||
|
* @return the printname associated with this object
|
||||||
|
*/
|
||||||
|
public abstract Printname getPrintname();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the parameter tooltip that this node has as a child
|
||||||
|
* of its parent (who gave it to it depending on its position)
|
||||||
|
*/
|
||||||
|
public abstract String getParamTooltip();
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return true iff this node represents an open leaf
|
||||||
|
*/
|
||||||
|
public abstract boolean isMeta();
|
||||||
|
}
|
||||||
40
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/ConstraintCallback.java
Normal file
40
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/ConstraintCallback.java
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package de.uka.ilkd.key.ocl.gf;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author daniels
|
||||||
|
* Offers the interface that GFEditor2 uses to send back the constraint after editing.
|
||||||
|
* Has no dependancies on KeY or TogetherCC.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
abstract class ConstraintCallback {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does the logging. What else should it do?
|
||||||
|
*/
|
||||||
|
protected static Logger logger = Logger.getLogger(ConstraintCallback.class.getName());
|
||||||
|
|
||||||
|
String grammarsDir;
|
||||||
|
/**
|
||||||
|
* sets the directory where the grammars reside
|
||||||
|
* @param grammarsDir
|
||||||
|
*/
|
||||||
|
void setGrammarsDir(final String grammarsDir) {
|
||||||
|
this.grammarsDir = grammarsDir;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* gets the directory where the grammars reside
|
||||||
|
*/
|
||||||
|
String getGrammarsDir() {
|
||||||
|
return this.grammarsDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends the finished OCL constraint back to Together to save it
|
||||||
|
* as a JavaDoc comment.
|
||||||
|
* @param constraint The OCL constraint in question.
|
||||||
|
*/
|
||||||
|
abstract void sendConstraint(String constraint);
|
||||||
|
|
||||||
|
}
|
||||||
202
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/Display.java
Normal file
202
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/Display.java
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
package de.uka.ilkd.key.ocl.gf;
|
||||||
|
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.Rectangle;
|
||||||
|
import java.util.Vector;
|
||||||
|
import javax.swing.JEditorPane;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author daniels
|
||||||
|
* Takes care of collecting the linearized text and the length calculations
|
||||||
|
*/
|
||||||
|
class Display {
|
||||||
|
private final boolean doText;
|
||||||
|
private final boolean doHtml;
|
||||||
|
/**
|
||||||
|
* collects the linearization after each append.
|
||||||
|
* what's in here are Strings
|
||||||
|
*/
|
||||||
|
private Vector linStagesHtml = new Vector();
|
||||||
|
/**
|
||||||
|
* collects the linearization after each append.
|
||||||
|
* what's in here are Strings
|
||||||
|
*/
|
||||||
|
private Vector linStagesText = new Vector();
|
||||||
|
/**
|
||||||
|
* Is used to calculate the length of a HTML snipplet.
|
||||||
|
* This pane is not displayed in hope to avoid any actual renderings
|
||||||
|
* which would just slow the length calculation down.
|
||||||
|
* Perhaps that's an abuse ...
|
||||||
|
* And perhaps this pane is not needed
|
||||||
|
*/
|
||||||
|
private JEditorPane htmlLengthPane = new JEditorPane();
|
||||||
|
|
||||||
|
/** initializes this object, nothing special
|
||||||
|
* @param dt 1 if only text is to be shown, 2 for only HTML, 3 for both.
|
||||||
|
* Other values are forbidden.
|
||||||
|
*/
|
||||||
|
public Display(int dt) {
|
||||||
|
switch (dt) {
|
||||||
|
case 1:
|
||||||
|
doText = true;
|
||||||
|
doHtml = false;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
doText = false;
|
||||||
|
doHtml = true;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
doText = true;
|
||||||
|
doHtml = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
doText = true;
|
||||||
|
doHtml = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.htmlLengthPane.setContentType("text/html");
|
||||||
|
this.htmlLengthPane.setEditable(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param font The Font, that is to be used. If null, the default of JTextPane is taken.
|
||||||
|
* @return the collected HTML text, that has been added to this object.
|
||||||
|
* <html> tags are wrapped around the result, if not already there.
|
||||||
|
*/
|
||||||
|
protected String getHtml(Font font) {
|
||||||
|
if (!doHtml) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
String result;
|
||||||
|
if (this.linStagesHtml.size() > 0) {
|
||||||
|
String fontface;
|
||||||
|
if (font != null) {
|
||||||
|
//fontface = " style=\"font-size:" + font.getSize()+ "pt\"";
|
||||||
|
fontface = " style=\"font: " + font.getSize()+ "pt " + font.getName() + "\"";
|
||||||
|
} else {
|
||||||
|
fontface = "";
|
||||||
|
}
|
||||||
|
result ="<html><body" + fontface + ">" + this.linStagesHtml.get(this.linStagesHtml.size() - 1).toString() + "</body></html>";
|
||||||
|
} else {
|
||||||
|
result = "";
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The collected pure text, that has been added to this object.
|
||||||
|
*/
|
||||||
|
protected String getText() {
|
||||||
|
if (!doText) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
String result;
|
||||||
|
if (this.linStagesText.size() > 0) {
|
||||||
|
result = this.linStagesText.lastElement().toString();
|
||||||
|
} else {
|
||||||
|
result = "";
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends the given text to the respective fields from
|
||||||
|
* where it can be displayed later
|
||||||
|
* @param text The pure text that is to be appended.
|
||||||
|
* @param html The HTML text that is to be appended.
|
||||||
|
* Most likely the same as text
|
||||||
|
*/
|
||||||
|
protected void addToStages(final String text, final String html) {
|
||||||
|
//add to HTML
|
||||||
|
if (doHtml) {
|
||||||
|
final String newStageHtml;
|
||||||
|
if (this.linStagesHtml.size() > 0) {
|
||||||
|
newStageHtml = this.linStagesHtml.get(this.linStagesHtml.size() - 1) + html;
|
||||||
|
} else {
|
||||||
|
newStageHtml = html;
|
||||||
|
}
|
||||||
|
this.linStagesHtml.add(newStageHtml);
|
||||||
|
}
|
||||||
|
|
||||||
|
//add to Text
|
||||||
|
if (doText) {
|
||||||
|
final String newStageText;
|
||||||
|
if (this.linStagesText.size() > 0) {
|
||||||
|
newStageText = linStagesText.get(linStagesText.size() - 1) + text;
|
||||||
|
} else {
|
||||||
|
newStageText = text;
|
||||||
|
}
|
||||||
|
this.linStagesText.add(newStageText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds toAdd to both the pure text as the HTML fields, they are inherently the same,
|
||||||
|
* since they are mapped to the same position in the AST.
|
||||||
|
* On the way of adding, some length calculations are done, which are used to
|
||||||
|
* create an HtmlMarkedArea object, which is ready to be used in GFEditor2.
|
||||||
|
* @param toAdd The String that the to-be-produced MarkedArea should represent
|
||||||
|
* @param position The position String in Haskell notation
|
||||||
|
* @return the HtmlMarkedArea object that represents the given information
|
||||||
|
* and knows about its beginning and end in the display areas.
|
||||||
|
*/
|
||||||
|
protected HtmlMarkedArea addAsMarked(String toAdd, LinPosition position) {
|
||||||
|
/** the length of the displayed HTML before the current append */
|
||||||
|
int oldLengthHtml = 0;
|
||||||
|
if (doHtml) {
|
||||||
|
if (this.linStagesHtml.size() > 0) {
|
||||||
|
// is still in there. Does not absolutely need to be
|
||||||
|
// cached in a global variable
|
||||||
|
oldLengthHtml = this.htmlLengthPane.getDocument().getLength();
|
||||||
|
} else {
|
||||||
|
oldLengthHtml = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/** the length of the text before the current append */
|
||||||
|
int oldLengthText = 0;
|
||||||
|
if (doText) {
|
||||||
|
if (this.linStagesText.size() > 0) {
|
||||||
|
// is still in there. Does not absolutely need to be
|
||||||
|
// cached in a global variable
|
||||||
|
oldLengthText = this.linStagesText.lastElement().toString().length();
|
||||||
|
} else {
|
||||||
|
oldLengthText = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addToStages(toAdd, toAdd);
|
||||||
|
//calculate beginning and end
|
||||||
|
//for HTML
|
||||||
|
int newLengthHtml = 0;
|
||||||
|
if (doHtml) {
|
||||||
|
final String newStageHtml = this.linStagesHtml.lastElement().toString();
|
||||||
|
final String newHtml = Printname.htmlPrepend(newStageHtml, "");
|
||||||
|
//yeah, daniels admits, this IS probably expensive
|
||||||
|
this.htmlLengthPane.setText(newHtml);
|
||||||
|
newLengthHtml = htmlLengthPane.getDocument().getLength();
|
||||||
|
if (newLengthHtml < oldLengthHtml) {
|
||||||
|
newLengthHtml = oldLengthHtml;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//for text
|
||||||
|
int newLengthText = 0;
|
||||||
|
if (doText) {
|
||||||
|
newLengthText = this.linStagesText.lastElement().toString().length();
|
||||||
|
}
|
||||||
|
final HtmlMarkedArea hma = new HtmlMarkedArea(oldLengthText, newLengthText, position, toAdd, oldLengthHtml, newLengthHtml);
|
||||||
|
return hma;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To store the scroll state of the pure text linearization area
|
||||||
|
*/
|
||||||
|
Rectangle recText = new Rectangle();
|
||||||
|
/**
|
||||||
|
* To store the scroll state of the HTML linearization area
|
||||||
|
*/
|
||||||
|
Rectangle recHtml = new Rectangle();
|
||||||
|
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return getText();
|
||||||
|
}
|
||||||
|
}
|
||||||
347
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/DynamicTree2.java
Normal file
347
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/DynamicTree2.java
Normal file
@@ -0,0 +1,347 @@
|
|||||||
|
package de.uka.ilkd.key.ocl.gf;
|
||||||
|
/*
|
||||||
|
* This code is based on an example provided by Richard Stanford,
|
||||||
|
* a tutorial reader.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import javax.swing.*;
|
||||||
|
import javax.swing.tree.*;
|
||||||
|
import javax.swing.event.*;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
//import de.uka.ilkd.key.util.KeYResourceManager;
|
||||||
|
|
||||||
|
import java.awt.event.*;
|
||||||
|
//import java.net.URL;
|
||||||
|
|
||||||
|
public class DynamicTree2 extends JPanel implements KeyListener,
|
||||||
|
ActionListener{
|
||||||
|
protected static Logger logger = Logger.getLogger(DynamicTree2.class.getName());
|
||||||
|
|
||||||
|
public DefaultMutableTreeNode rootNode;
|
||||||
|
protected DefaultTreeModel treeModel;
|
||||||
|
public JTree tree;
|
||||||
|
public int oldSelection = 0;
|
||||||
|
private Toolkit toolkit = Toolkit.getDefaultToolkit();
|
||||||
|
public JPopupMenu popup = new JPopupMenu();
|
||||||
|
JMenuItem menuItem;
|
||||||
|
private GFEditor2 gfeditor;
|
||||||
|
|
||||||
|
public DynamicTree2(GFEditor2 gfe) {
|
||||||
|
|
||||||
|
this.gfeditor = gfe;
|
||||||
|
rootNode = new DefaultMutableTreeNode("Root Node");
|
||||||
|
treeModel = new DefaultTreeModel(rootNode);
|
||||||
|
treeModel.addTreeModelListener(new MyTreeModelListener());
|
||||||
|
|
||||||
|
tree = new JTree(treeModel);
|
||||||
|
tree.setRootVisible(false);
|
||||||
|
tree.setEditable(false);
|
||||||
|
tree.getSelectionModel().setSelectionMode
|
||||||
|
(TreeSelectionModel.SINGLE_TREE_SELECTION);
|
||||||
|
tree.addKeyListener(this);
|
||||||
|
menuItem = new JMenuItem("Paste");
|
||||||
|
menuItem.addActionListener(this);
|
||||||
|
popup.add(menuItem);
|
||||||
|
|
||||||
|
//Add listener to components that can bring up popup menus.
|
||||||
|
MouseListener popupListener = new PopupListener();
|
||||||
|
tree.addMouseListener(popupListener);
|
||||||
|
|
||||||
|
tree.addTreeSelectionListener(new TreeSelectionListener() {
|
||||||
|
/**
|
||||||
|
* the following is assumed:
|
||||||
|
* in GF we can only switch to the last or the next editing position.
|
||||||
|
* In the displayed tree, we can click everywhere.
|
||||||
|
* We navigate through the GF tree by giving the direction
|
||||||
|
* and the number of steps
|
||||||
|
*/
|
||||||
|
public void valueChanged(TreeSelectionEvent e) {
|
||||||
|
if (tree.getSelectionRows() != null) {
|
||||||
|
if (gfeditor.nodeTable == null) {
|
||||||
|
if (GFEditor2.treeLogger.isDebugEnabled()) {
|
||||||
|
GFEditor2.treeLogger.debug("null node table");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (GFEditor2.treeLogger.isDebugEnabled()) {
|
||||||
|
GFEditor2.treeLogger.debug("node table: " + gfeditor.nodeTable.contains(new Integer(0)) + " " + gfeditor.nodeTable.keys().nextElement());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tree.getSelectionPath() == null) {
|
||||||
|
if (GFEditor2.treeLogger.isDebugEnabled()) {
|
||||||
|
GFEditor2.treeLogger.debug("null root path");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (GFEditor2.treeLogger.isDebugEnabled()) {
|
||||||
|
GFEditor2.treeLogger.debug("selected path" + tree.getSelectionPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int i = ((Integer) gfeditor.nodeTable.get(tree.getSelectionPath())).intValue();
|
||||||
|
int j = oldSelection;
|
||||||
|
gfeditor.treeChanged = true;
|
||||||
|
if (i > j)
|
||||||
|
gfeditor.send("> " + String.valueOf(i - j));
|
||||||
|
else
|
||||||
|
gfeditor.send("< " + String.valueOf(j - i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
tree.setCellRenderer(new MyRenderer());
|
||||||
|
tree.setShowsRootHandles(true);
|
||||||
|
ToolTipManager.sharedInstance().registerComponent(tree);
|
||||||
|
ToolTipManager.sharedInstance().setDismissDelay(60000);
|
||||||
|
setPreferredSize(new Dimension(200, 100));
|
||||||
|
JScrollPane scrollPane = new JScrollPane(tree);
|
||||||
|
setLayout(new GridLayout(1,0));
|
||||||
|
add(scrollPane);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Remove all nodes except the root node. */
|
||||||
|
public void clear() {
|
||||||
|
rootNode.removeAllChildren();
|
||||||
|
treeModel.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Remove the currently selected node. */
|
||||||
|
public void removeCurrentNode() {
|
||||||
|
TreePath currentSelection = tree.getSelectionPath();
|
||||||
|
if (currentSelection != null) {
|
||||||
|
DefaultMutableTreeNode currentNode = (DefaultMutableTreeNode)
|
||||||
|
(currentSelection.getLastPathComponent());
|
||||||
|
MutableTreeNode parent = (MutableTreeNode)(currentNode.getParent());
|
||||||
|
if (parent != null) {
|
||||||
|
treeModel.removeNodeFromParent(currentNode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Either there was no selection, or the root was selected.
|
||||||
|
toolkit.beep();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add child to the root node.
|
||||||
|
* It will come last in this node.
|
||||||
|
* @param child the payload of the new node
|
||||||
|
* @return the tree node having child as the node data
|
||||||
|
*/
|
||||||
|
public DefaultMutableTreeNode addObject(Object child) {
|
||||||
|
DefaultMutableTreeNode parentNode = null;
|
||||||
|
TreePath parentPath = tree.getSelectionPath();
|
||||||
|
|
||||||
|
if (parentPath == null) {
|
||||||
|
parentNode = rootNode;
|
||||||
|
} else {
|
||||||
|
parentNode = (DefaultMutableTreeNode)
|
||||||
|
(parentPath.getLastPathComponent());
|
||||||
|
}
|
||||||
|
|
||||||
|
return addObject(parentNode, child, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new node containing child to the node parent.
|
||||||
|
* It will come last in this node.
|
||||||
|
* This method gets actually called
|
||||||
|
* @param parent the parent node of the to be created node
|
||||||
|
* @param child the wannabe node data
|
||||||
|
* @return the tree node having child as the node data and parent as the parent
|
||||||
|
*/
|
||||||
|
public DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent,
|
||||||
|
Object child) {
|
||||||
|
return addObject(parent, child, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add child to the currently selected node (parent?).
|
||||||
|
* It will come last in this node.
|
||||||
|
* @param parent the parent node of the to be created node
|
||||||
|
* @param child the wannabe node data
|
||||||
|
* @param shouldBeVisible true iff the viewport should show the
|
||||||
|
* new node afterwards
|
||||||
|
* @return the tree node having child as the node data and parent
|
||||||
|
* as the parent
|
||||||
|
*/
|
||||||
|
public DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent, Object child, boolean shouldBeVisible) {
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("node added: '" + child + "', parent: '" + parent + "'");
|
||||||
|
}
|
||||||
|
DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(child);
|
||||||
|
|
||||||
|
if (parent == null) {
|
||||||
|
parent = rootNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
treeModel.insertNodeInto(childNode, parent,
|
||||||
|
parent.getChildCount());
|
||||||
|
|
||||||
|
// Make sure the user can see the lovely new node.
|
||||||
|
if (shouldBeVisible) {
|
||||||
|
tree.scrollPathToVisible(new TreePath(childNode.getPath()));
|
||||||
|
}
|
||||||
|
return childNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyTreeModelListener implements TreeModelListener {
|
||||||
|
public void treeNodesChanged(TreeModelEvent e) {
|
||||||
|
DefaultMutableTreeNode node;
|
||||||
|
node = (DefaultMutableTreeNode)
|
||||||
|
(e.getTreePath().getLastPathComponent());
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the event lists children, then the changed
|
||||||
|
* node is the child of the node we've already
|
||||||
|
* gotten. Otherwise, the changed node and the
|
||||||
|
* specified node are the same.
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
int index = e.getChildIndices()[0];
|
||||||
|
node = (DefaultMutableTreeNode)(node.getChildAt(index));
|
||||||
|
} catch (NullPointerException exc) {
|
||||||
|
System.err.println(exc.getMessage());
|
||||||
|
exc.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GFEditor2.treeLogger.isDebugEnabled()) {
|
||||||
|
GFEditor2.treeLogger.debug("The user has finished editing the node.");
|
||||||
|
GFEditor2.treeLogger.debug("New value: " + node.getUserObject());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void treeNodesInserted(TreeModelEvent e) {
|
||||||
|
//nothing to be done here
|
||||||
|
}
|
||||||
|
public void treeNodesRemoved(TreeModelEvent e) {
|
||||||
|
//nothing to be done here
|
||||||
|
}
|
||||||
|
public void treeStructureChanged(TreeModelEvent e) {
|
||||||
|
//nothing to be done here
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class MyRenderer extends DefaultTreeCellRenderer {
|
||||||
|
//int counter = 0;
|
||||||
|
//final ImageIcon iconFilled;
|
||||||
|
//final ImageIcon iconOpen;
|
||||||
|
|
||||||
|
// public MyRenderer() {
|
||||||
|
// final URL urlOpen = KeYResourceManager.getManager().getResourceFile(DynamicTree2.class, "metal_leaf_open.png");
|
||||||
|
// final URL urlFilled = KeYResourceManager.getManager().getResourceFile(DynamicTree2.class, "metal_leaf_filled.png");
|
||||||
|
// iconOpen = new ImageIcon(urlOpen);
|
||||||
|
// iconFilled = new ImageIcon(urlFilled);
|
||||||
|
// }
|
||||||
|
|
||||||
|
public Component getTreeCellRendererComponent(
|
||||||
|
JTree tree,
|
||||||
|
Object value,
|
||||||
|
boolean sel,
|
||||||
|
boolean expanded,
|
||||||
|
boolean leaf,
|
||||||
|
int row,
|
||||||
|
boolean hasFocus) {
|
||||||
|
|
||||||
|
super.getTreeCellRendererComponent(
|
||||||
|
tree, value, sel,
|
||||||
|
expanded, leaf, row,
|
||||||
|
hasFocus);
|
||||||
|
if (value instanceof DefaultMutableTreeNode) {
|
||||||
|
DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
|
||||||
|
if (node.getUserObject() instanceof AstNodeData) {
|
||||||
|
AstNodeData and = (AstNodeData)node.getUserObject();
|
||||||
|
String ptt = and.getParamTooltip();
|
||||||
|
this.setToolTipText(ptt);
|
||||||
|
this.setText(and.toString());
|
||||||
|
// if (and.isMeta()) {
|
||||||
|
// this.setLeafIcon(this.iconOpen);
|
||||||
|
// } else {
|
||||||
|
// this.setLeafIcon(this.iconFilled);
|
||||||
|
// }
|
||||||
|
} else {
|
||||||
|
this.setToolTipText(null);
|
||||||
|
this.setText(value.toString());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.setToolTipText(null);
|
||||||
|
this.setText(value.toString());
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the current node represents an open metavariable
|
||||||
|
* or question mark
|
||||||
|
* @param value The payload of the node
|
||||||
|
* @return true iff value begins with a '?'
|
||||||
|
*/
|
||||||
|
protected boolean isMetavariable(Object value) {
|
||||||
|
try {
|
||||||
|
DefaultMutableTreeNode node =
|
||||||
|
(DefaultMutableTreeNode)value;
|
||||||
|
String nodeInfo =
|
||||||
|
(String)(node.getUserObject());
|
||||||
|
if (nodeInfo.indexOf("?") == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}//class
|
||||||
|
|
||||||
|
class PopupListener extends MouseAdapter {
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
int selRow = tree.getRowForLocation(e.getX(), e.getY());
|
||||||
|
tree.setSelectionRow(selRow);
|
||||||
|
if (GFEditor2.treeLogger.isDebugEnabled()) {
|
||||||
|
GFEditor2.treeLogger.debug("selection changed!");
|
||||||
|
}
|
||||||
|
maybeShowPopup(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mouseReleased(MouseEvent e) {
|
||||||
|
//nothing to be done here
|
||||||
|
}
|
||||||
|
void maybeShowPopup(MouseEvent e) {
|
||||||
|
if (GFEditor2.treeLogger.isDebugEnabled()) {
|
||||||
|
GFEditor2.treeLogger.debug("may be show Popup!");
|
||||||
|
}
|
||||||
|
if (e.isPopupTrigger()) {
|
||||||
|
if (GFEditor2.treeLogger.isDebugEnabled()) {
|
||||||
|
GFEditor2.treeLogger.debug("changing menu!");
|
||||||
|
}
|
||||||
|
popup = gfeditor.producePopup();
|
||||||
|
popup.show(e.getComponent(), e.getX(), e.getY());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void actionPerformed(ActionEvent ae) {
|
||||||
|
//nothing to be done here
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Handle the key pressed event. */
|
||||||
|
public void keyPressed(KeyEvent e) {
|
||||||
|
int keyCode = e.getKeyCode();
|
||||||
|
switch (keyCode){
|
||||||
|
case KeyEvent.VK_SPACE : gfeditor.send("'"); break;
|
||||||
|
case KeyEvent.VK_DELETE : gfeditor.send("d"); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/** Handle the key typed event. */
|
||||||
|
public void keyTyped(KeyEvent e) {
|
||||||
|
//nothing to be done here
|
||||||
|
}
|
||||||
|
/** Handle the key released event. */
|
||||||
|
public void keyReleased(KeyEvent e) {
|
||||||
|
//nothing to be done here
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
104
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/GFCommand.java
Normal file
104
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/GFCommand.java
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* Created on 20.04.2005
|
||||||
|
*/
|
||||||
|
package de.uka.ilkd.key.ocl.gf;
|
||||||
|
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author daniels
|
||||||
|
* A class that represents a GF command together with its printname.
|
||||||
|
* It also gives easy access to all the abuses of the printname like
|
||||||
|
* the subcategory, the tooltip, it knows about wrapping and so on.
|
||||||
|
*
|
||||||
|
* The static stuff could produce problems if the editor is started
|
||||||
|
* several times without closing it first. It probably should be moved
|
||||||
|
* into a manager class.
|
||||||
|
* Or the instances that get generated during one run all share the same
|
||||||
|
* "pseudo-static" Hashtables. This is probably better.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
abstract class GFCommand implements Comparable{
|
||||||
|
|
||||||
|
protected static Logger subcatLogger = Logger.getLogger(GFEditor2.class.getName() + "_subcat");
|
||||||
|
|
||||||
|
/** the subcategory of this command */
|
||||||
|
public abstract String getSubcat();
|
||||||
|
/** the type of the command, r,w,ch,d,ac,... */
|
||||||
|
protected String commandType;
|
||||||
|
/** the type of the command, r,w,ch,d,ac,... */
|
||||||
|
public String getCommandType(){
|
||||||
|
return commandType;
|
||||||
|
}
|
||||||
|
/** for wrap, the number of the argument the current node should become */
|
||||||
|
protected int argument;
|
||||||
|
|
||||||
|
/**the actual command that this object should represent */
|
||||||
|
protected String command;
|
||||||
|
/**the actual command that this object should represent */
|
||||||
|
public String getCommand() {
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**the Printname corresponding to the GF fun of this command*/
|
||||||
|
protected Printname printname;
|
||||||
|
/**the Printname corresponding to the GF fun of this command*/
|
||||||
|
public Printname getPrintname(){
|
||||||
|
return printname;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**the text that is to be displayed as the tooltip */
|
||||||
|
public abstract String getTooltipText();
|
||||||
|
|
||||||
|
/** the text that is to be displayed in the refinement lists */
|
||||||
|
public abstract String getDisplayText();
|
||||||
|
|
||||||
|
/** the name of the fun that is used in this command */
|
||||||
|
protected String funName;
|
||||||
|
|
||||||
|
/** if this is the first occurence of the current subcat */
|
||||||
|
protected boolean newSubcat;
|
||||||
|
/** if this is the first occurence of the current subcat */
|
||||||
|
public boolean isNewSubcat() {
|
||||||
|
return newSubcat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares two GFCommands.
|
||||||
|
* LinkCommands are the least. InputCommands the greatest. If that does not decide,
|
||||||
|
* the display name as a String does.
|
||||||
|
* @param o the other command.
|
||||||
|
* @return see above.
|
||||||
|
*/
|
||||||
|
public int compareTo(Object o) {
|
||||||
|
if (this.equals(o)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (this instanceof LinkCommand && !(o instanceof LinkCommand)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!(this instanceof LinkCommand) && (o instanceof LinkCommand)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (this instanceof InputCommand && !(o instanceof InputCommand)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!(this instanceof InputCommand) && (o instanceof InputCommand)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (! (o instanceof GFCommand)) {
|
||||||
|
//This should never occur!
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
GFCommand ocmd = (GFCommand)o;
|
||||||
|
return this.getDisplayText().compareTo(ocmd.getDisplayText());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return getDisplayText() + " \n " + getTooltipText();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
4033
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/GFEditor2.java
Normal file
4033
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/GFEditor2.java
Normal file
File diff suppressed because it is too large
Load Diff
123
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/GfAstNode.java
Normal file
123
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/GfAstNode.java
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
* Created on 06.05.2005
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package de.uka.ilkd.key.ocl.gf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author daniels
|
||||||
|
* This Class represents a parsed node in the GF AST.
|
||||||
|
*/
|
||||||
|
class GfAstNode {
|
||||||
|
protected final String[] boundTypes;
|
||||||
|
protected final String[] boundNames;
|
||||||
|
/** The type of this AST node */
|
||||||
|
private final String type;
|
||||||
|
/**
|
||||||
|
* @return The type of this AST node
|
||||||
|
*/
|
||||||
|
protected String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
/** the fun represented in this AST node */
|
||||||
|
private final String fun;
|
||||||
|
/**
|
||||||
|
* @return the fun represented in this AST node.
|
||||||
|
* Can be a metavariable like "?1"
|
||||||
|
*/
|
||||||
|
protected String getFun() {
|
||||||
|
return fun;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return true iff the node is a metavariable, i.e. open and not
|
||||||
|
* yet refined.
|
||||||
|
*/
|
||||||
|
protected boolean isMeta() {
|
||||||
|
return fun.startsWith("?");
|
||||||
|
}
|
||||||
|
/** the line that was used to build this node */
|
||||||
|
private final String line;
|
||||||
|
/**
|
||||||
|
* @return the line that was used to build this node
|
||||||
|
*/
|
||||||
|
protected String getLine() {
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* feed this constructor the line that appears in the GF AST and
|
||||||
|
* it will get chopped at the right points.
|
||||||
|
* @param line The line from GF without the * in the beginning.
|
||||||
|
*/
|
||||||
|
protected GfAstNode(final String line) {
|
||||||
|
this.line = line.trim();
|
||||||
|
final int index = this.line.lastIndexOf(" : ");
|
||||||
|
this.type = this.line.substring(index + 3);
|
||||||
|
String myFun = this.line.substring(0, index);
|
||||||
|
if (myFun.startsWith("\\(")) {
|
||||||
|
final int end = myFun.lastIndexOf(") -> ");
|
||||||
|
String boundPart = myFun.substring(2, end);
|
||||||
|
String[] bounds = boundPart.split("\\)\\s*\\,\\s*\\(");
|
||||||
|
this.boundNames = new String[bounds.length];
|
||||||
|
this.boundTypes = new String[bounds.length];
|
||||||
|
for (int i = 0; i < bounds.length;i++) {
|
||||||
|
//System.out.print("+" + bounds[i] + "-");
|
||||||
|
int colon = bounds[i].indexOf(" : ");
|
||||||
|
this.boundNames[i] = bounds[i].substring(0, colon);
|
||||||
|
this.boundTypes[i] = bounds[i].substring(colon + 3);
|
||||||
|
//System.out.println(boundNames[i] + " ;; " + boundTypes[i]);
|
||||||
|
}
|
||||||
|
myFun = myFun.substring(end + 5);
|
||||||
|
} else {
|
||||||
|
this.boundNames = new String[0];
|
||||||
|
this.boundTypes = new String[0];
|
||||||
|
}
|
||||||
|
this.fun = myFun;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return this.line;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
String[] lines = {"?1 : Sent",
|
||||||
|
"Two : Instance Integer",
|
||||||
|
"?3 : Instance (Collection (?{this:=this{-0-}}))",
|
||||||
|
"NOPACKAGEP_StartC_Constr : Constraint {Constraint<>NOPACKAGEP_StartC_Constr (\\this -> invCt ?)}",
|
||||||
|
"\\(this : VarSelf NOPACKAGEP_StartC) -> invCt : ClassConstraintBody",
|
||||||
|
"\\(x_0 : Instance Integer) -> ?6 : Sent",
|
||||||
|
"\\(selfGF : VarSelf NOPACKAGEP_PayCardC),(amount : Instance Integer) -> preC : OperConstraintBody",
|
||||||
|
"\\(selfGF : VarSelf NOPACKAGEP_PayCardC),(amount : Instance Integer) -> ?0 : OperConstraintBody"
|
||||||
|
};
|
||||||
|
String[] funs = {"?1",
|
||||||
|
"Two",
|
||||||
|
"?3",
|
||||||
|
"NOPACKAGEP_StartC_Constr",
|
||||||
|
"invCt",
|
||||||
|
"?6",
|
||||||
|
"preC",
|
||||||
|
"?0"
|
||||||
|
};
|
||||||
|
String[] types = {"Sent",
|
||||||
|
"Instance Integer",
|
||||||
|
"Instance (Collection (?{this:=this{-0-}}))",
|
||||||
|
"Constraint {Constraint<>NOPACKAGEP_StartC_Constr (\\this -> invCt ?)}",
|
||||||
|
"ClassConstraintBody",
|
||||||
|
"Sent",
|
||||||
|
"OperConstraintBody",
|
||||||
|
"OperConstraintBody"
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 0; i < lines.length; i++) {
|
||||||
|
System.out.println("* " + lines[i]);
|
||||||
|
GfAstNode gfa = new GfAstNode(lines[i]);
|
||||||
|
if (!gfa.getFun().equals(funs[i])) {
|
||||||
|
System.out.println(" fun mismatch: expected '" + funs[i] + "', got '" + gfa.getFun() + "'");
|
||||||
|
}
|
||||||
|
if (!gfa.getType().equals(types[i])) {
|
||||||
|
System.out.println(" type mismatch: expected '" + types[i] + "', got '" + gfa.getType() + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
40
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/GrammarFilter.java
Normal file
40
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/GrammarFilter.java
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
// This file is part of KeY - Integrated Deductive Software Design
|
||||||
|
// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany
|
||||||
|
// Universitaet Koblenz-Landau, Germany
|
||||||
|
// Chalmers University of Technology, Sweden
|
||||||
|
//
|
||||||
|
// The KeY system is protected by the GNU General Public License.
|
||||||
|
// See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
package de.uka.ilkd.key.ocl.gf;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import javax.swing.filechooser.*;
|
||||||
|
|
||||||
|
public class GrammarFilter extends FileFilter {
|
||||||
|
|
||||||
|
// Accept all directories and all gf, gfm files.
|
||||||
|
public boolean accept(File f) {
|
||||||
|
if (f.isDirectory()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
String extension = Utils.getExtension(f);
|
||||||
|
if (extension != null) {
|
||||||
|
if (extension.equals(Utils.gf) ||
|
||||||
|
extension.equals(Utils.gfm)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The description of this filter
|
||||||
|
public String getDescription() {
|
||||||
|
return "Just Grammars (*.gf, *.gfm)";
|
||||||
|
}
|
||||||
|
}
|
||||||
47
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/HtmlMarkedArea.java
Normal file
47
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/HtmlMarkedArea.java
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
package de.uka.ilkd.key.ocl.gf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author daniels
|
||||||
|
*
|
||||||
|
* An extender of MarkedArea that adds additional fields for the click-in
|
||||||
|
* functionality for HTML
|
||||||
|
*/
|
||||||
|
class HtmlMarkedArea extends MarkedArea {
|
||||||
|
|
||||||
|
/** the start index in the HTML area */
|
||||||
|
final public int htmlBegin;
|
||||||
|
/** the end index in the HTML area */
|
||||||
|
final public int htmlEnd;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A stand-alone constuctor which takes all values as arguments
|
||||||
|
* @param b The starting position of the stored words
|
||||||
|
* @param e The ending position of the stored words
|
||||||
|
* @param p The position in the AST
|
||||||
|
* @param w The actual text of this area
|
||||||
|
* @param hb the start index in the HTML area
|
||||||
|
* @param he the end index in the HTML area
|
||||||
|
*/
|
||||||
|
public HtmlMarkedArea(int b, int e, LinPosition p, String w, int hb, int he) {
|
||||||
|
super(b, e, p, w);
|
||||||
|
this.htmlBegin = hb;
|
||||||
|
this.htmlEnd = he;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a copy of orig, but with additional fields for the click-
|
||||||
|
* in functionality for HTML
|
||||||
|
* @param orig the original MarkedArea that should be extended
|
||||||
|
* @param hb the start index in the HTML area
|
||||||
|
* @param he the end index in the HTML area
|
||||||
|
*/
|
||||||
|
HtmlMarkedArea(final MarkedArea orig, final int hb, final int he) {
|
||||||
|
super(orig.begin, orig.end, orig.position, orig.words);
|
||||||
|
this.htmlBegin = hb;
|
||||||
|
this.htmlEnd = he;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return begin + " - " + end + " : " + position + " = '" + words + "' ; HTML: " + htmlBegin + " - " + htmlEnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
104
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/InputCommand.java
Normal file
104
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/InputCommand.java
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
package de.uka.ilkd.key.ocl.gf;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author daniels
|
||||||
|
*
|
||||||
|
* This class represents a fake command, i.e. nothing is send to GF here.
|
||||||
|
* Instead this class acts more like a placeholder for the input dialog.
|
||||||
|
* This dialog is handled in GFEditor2 when a InputCommand is executed.
|
||||||
|
* Reason: No GUI stuff in the command.
|
||||||
|
*/
|
||||||
|
class InputCommand extends GFCommand {
|
||||||
|
protected final static Logger logger = Logger.getLogger(Printname.class.getName());
|
||||||
|
public static InputCommand intInputCommand = new InputCommand("read in Integer",
|
||||||
|
"opens a dialog window in which an Integer can be entered",
|
||||||
|
int.class,
|
||||||
|
"Please enter an Integer");
|
||||||
|
public static InputCommand stringInputCommand = new InputCommand("read in String",
|
||||||
|
"opens a dialog window in which a String can be entered",
|
||||||
|
String.class,
|
||||||
|
"Please enter a String");
|
||||||
|
|
||||||
|
protected InputCommand(final String description, final String ttt, Class type, final String title) {
|
||||||
|
this.type = type;
|
||||||
|
this.tooltipText = ttt;
|
||||||
|
this.displayText = description;
|
||||||
|
this.titleText = title;
|
||||||
|
this.command = type.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Class type;
|
||||||
|
|
||||||
|
/**the text that is to be displayed as the title in the input window */
|
||||||
|
protected final String titleText;
|
||||||
|
/**the text that is to be displayed as the title in the input window */
|
||||||
|
public String getTitleText() {
|
||||||
|
return titleText;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**the text that is to be displayed as the tooltip */
|
||||||
|
protected final String tooltipText;
|
||||||
|
/**the text that is to be displayed as the tooltip */
|
||||||
|
public String getTooltipText() {
|
||||||
|
return tooltipText;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** the text that is to be displayed in the refinement lists */
|
||||||
|
protected final String displayText;
|
||||||
|
/** the text that is to be displayed in the refinement lists */
|
||||||
|
public String getDisplayText() {
|
||||||
|
return displayText;
|
||||||
|
}
|
||||||
|
/** the subcategory of this command */
|
||||||
|
public String getSubcat() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the given String can be converted into
|
||||||
|
* the Type of this InputCommand (int or String)
|
||||||
|
* @param o The String the user has typed
|
||||||
|
* @param reason If the entered String is not parseable as the expected
|
||||||
|
* type, an error message is appended to this StringBuffer, so better
|
||||||
|
* give an empty one.
|
||||||
|
* @return an Object whose toString() should send the right
|
||||||
|
* thing to GF.
|
||||||
|
* Maybe null, if this "conversion" failed.
|
||||||
|
*/
|
||||||
|
protected Object validate(String o, StringBuffer reason) {
|
||||||
|
Object result = null;
|
||||||
|
if (type == int.class) {
|
||||||
|
int i;
|
||||||
|
try {
|
||||||
|
i = Integer.parseInt(o);
|
||||||
|
result = new Integer(i);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
reason.append("Input format error: '" + o + "' is no Integer");
|
||||||
|
}
|
||||||
|
} else if (type == String.class) {
|
||||||
|
if (o != null) {
|
||||||
|
result = "\"" + o.toString() + "\"";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* selects the suiting InputCommand for the given full name of a type
|
||||||
|
* @param typeName at the moment, either int.class.getName() or String.class.getName()
|
||||||
|
* @return intInputCommand for int, stringInputCommand for String or null otherwise
|
||||||
|
*/
|
||||||
|
protected static InputCommand forTypeName(String typeName) {
|
||||||
|
InputCommand ic = null;
|
||||||
|
if (typeName.equals(int.class.getName())) {
|
||||||
|
ic = InputCommand.intInputCommand;
|
||||||
|
} else if (typeName.equals(String.class.getName())) {
|
||||||
|
ic = InputCommand.stringInputCommand;
|
||||||
|
}
|
||||||
|
return ic;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
34
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/LinPosition.java
Normal file
34
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/LinPosition.java
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package de.uka.ilkd.key.ocl.gf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* represents a position in the AST in Haskell notation together
|
||||||
|
* with a flag that indicates whether at least one constraint does not hold or
|
||||||
|
* if all hold (correct/incorrect).
|
||||||
|
* Class is immutable.
|
||||||
|
*/
|
||||||
|
public class LinPosition {
|
||||||
|
/**
|
||||||
|
* a position in the AST in Haskell notation
|
||||||
|
*/
|
||||||
|
final public String position;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* true means green, false means red (janna guesses)
|
||||||
|
*/
|
||||||
|
final public boolean correctPosition;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates a LinPosition
|
||||||
|
* @param p the position in the AST in Haskell notation like [0,1,2]
|
||||||
|
* @param cor false iff there are violated constraints
|
||||||
|
*/
|
||||||
|
LinPosition(String p, boolean cor) {
|
||||||
|
position = p;
|
||||||
|
correctPosition = cor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return position + (correctPosition ? " correct" : " incorrect");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
55
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/LinkCommand.java
Normal file
55
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/LinkCommand.java
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Created on 21.04.2005
|
||||||
|
*/
|
||||||
|
package de.uka.ilkd.key.ocl.gf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author daniels
|
||||||
|
* This class represents a link to a subcategory submenu.
|
||||||
|
* When it is encountered as the executed command, the corresponding
|
||||||
|
* menu gets opened.
|
||||||
|
*/
|
||||||
|
public class LinkCommand extends GFCommand {
|
||||||
|
|
||||||
|
public LinkCommand(final String subcat, final PrintnameManager manager) {
|
||||||
|
this.command = subcat;
|
||||||
|
this.newSubcat = false;
|
||||||
|
this.commandType = Printname.SUBCAT;
|
||||||
|
this.argument = -1;
|
||||||
|
this.funName = null;
|
||||||
|
this.printname = null;
|
||||||
|
|
||||||
|
String dtext;
|
||||||
|
String ttext;
|
||||||
|
String fullname = manager.getFullname(subcat);
|
||||||
|
if (fullname == null) {
|
||||||
|
dtext = getSubcat();
|
||||||
|
ttext = "open submenu " + getSubcat();
|
||||||
|
} else {
|
||||||
|
ttext = Printname.htmlPrepend(Printname.extractTooltipText(fullname), "<i>open submenu</i> <br> ");
|
||||||
|
dtext = Printname.extractDisplayText(fullname);
|
||||||
|
}
|
||||||
|
this.tooltipText = ttext;
|
||||||
|
this.displayText = dtext;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**the text that is to be displayed as the tooltip */
|
||||||
|
protected final String tooltipText;
|
||||||
|
/**the text that is to be displayed as the tooltip */
|
||||||
|
public String getTooltipText() {
|
||||||
|
return tooltipText;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** the text that is to be displayed in the refinement lists */
|
||||||
|
protected final String displayText;
|
||||||
|
/** the text that is to be displayed in the refinement lists */
|
||||||
|
public String getDisplayText() {
|
||||||
|
return displayText;
|
||||||
|
}
|
||||||
|
/** the subcategory of this command */
|
||||||
|
public String getSubcat() {
|
||||||
|
return this.command;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
40
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/MarkedArea.java
Normal file
40
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/MarkedArea.java
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package de.uka.ilkd.key.ocl.gf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores quasi a piece of the linearization area, that has a word, a beginning
|
||||||
|
* and an end in the linearization area and a position in the AST. It is used
|
||||||
|
* for clicking in the text
|
||||||
|
*
|
||||||
|
* @author janna
|
||||||
|
*/
|
||||||
|
class MarkedArea {
|
||||||
|
/** The starting position of the stored words */
|
||||||
|
final public int begin;
|
||||||
|
/** The ending position of the stored words.
|
||||||
|
* Not final because of some punctuation issue daniels
|
||||||
|
* does not understand
|
||||||
|
*/
|
||||||
|
public int end;
|
||||||
|
/** The position in the AST */
|
||||||
|
final public LinPosition position;
|
||||||
|
/** The actual text of this area */
|
||||||
|
final public String words;
|
||||||
|
/**
|
||||||
|
* Creates a new MarkedArea and initializes the fields with the parameters
|
||||||
|
* @param b The starting position of the stored words
|
||||||
|
* @param e The ending position of the stored words
|
||||||
|
* @param p The position in the AST
|
||||||
|
* @param w The actual text of this area
|
||||||
|
*/
|
||||||
|
MarkedArea(int b, int e, LinPosition p, String w) {
|
||||||
|
begin = b;
|
||||||
|
end = e;
|
||||||
|
position = p;
|
||||||
|
words = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return begin + " - " + end + " : " + position + " = '" + words + "'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
458
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/Printname.java
Normal file
458
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/Printname.java
Normal file
@@ -0,0 +1,458 @@
|
|||||||
|
package de.uka.ilkd.key.ocl.gf;
|
||||||
|
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author daniels
|
||||||
|
*
|
||||||
|
* A Printname allows easy access for all the information that is crammed
|
||||||
|
* into a printname in the GF grammars.
|
||||||
|
* This information consists of (in this order!)
|
||||||
|
* The tooltip text which is started with $
|
||||||
|
* The subcategory which is started with %
|
||||||
|
* The longer explanation for the subcategory which directly follows the
|
||||||
|
* subcategory and is put into parantheses
|
||||||
|
* The parameter descriptions, which start with #name and is followed
|
||||||
|
* by their actual description.
|
||||||
|
* HTML can be used inside the descriptions and the tooltip text
|
||||||
|
*/
|
||||||
|
class Printname {
|
||||||
|
protected static Logger subcatLogger = Logger.getLogger(Printname.class.getName());
|
||||||
|
|
||||||
|
public static final Printname delete = new Printname("d", "delete current sub-tree");
|
||||||
|
public static final Printname addclip = new Printname("ac", "add to clipboard\\$<html>adds the current subtree to the clipboard.<br>It is offered in the refinement menu if the expected type fits to the one of the current sub-tree.</html>");
|
||||||
|
public static final Printname printhistory = new Printname("ph", "print history\\$prints all previous command in the linearization area");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The character that is the borderline between the text that
|
||||||
|
* is to be displayed in the JList and the ToolTip text
|
||||||
|
*/
|
||||||
|
public final static String TT_START = "\\$";
|
||||||
|
/**
|
||||||
|
* the string that is followed by the sub-category shorthand
|
||||||
|
* in the refinement menu
|
||||||
|
*/
|
||||||
|
public final static String SUBCAT = "\\%";
|
||||||
|
/**
|
||||||
|
* The string that is followed by a new parameter to the GF function
|
||||||
|
*/
|
||||||
|
public final static String PARAM = "\\#";
|
||||||
|
|
||||||
|
|
||||||
|
/** the name of the fun that is used in this command */
|
||||||
|
protected final String fun;
|
||||||
|
|
||||||
|
/** the printname of this function */
|
||||||
|
protected final String printname;
|
||||||
|
|
||||||
|
/** to cache the printname, once it is constructed */
|
||||||
|
protected String displayedPrintname = null;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the name of the module the fun belongs to
|
||||||
|
* null means that the function is saved without module information,
|
||||||
|
* "" means that a GF command is represented
|
||||||
|
*/
|
||||||
|
protected final String module;
|
||||||
|
/**
|
||||||
|
* the name of the module the fun belongs to
|
||||||
|
* null means that the function is saved without module information,
|
||||||
|
* "" means that a GF command is represented
|
||||||
|
*/
|
||||||
|
public String getModule() {
|
||||||
|
return module;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** the qualified function name, not needed yet */
|
||||||
|
/*
|
||||||
|
public String getFunQualified() {
|
||||||
|
if (module != null && !module.equals("")) {
|
||||||
|
return module + "." + fun;
|
||||||
|
} else {
|
||||||
|
return fun;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** the subcategory of this command */
|
||||||
|
protected final String subcat;
|
||||||
|
/** the subcategory of this command */
|
||||||
|
public String getSubcat() {
|
||||||
|
return subcat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The hashmap for the names of the sub categories,
|
||||||
|
* with the shortname starting with '%' as the key.
|
||||||
|
* It is important that all Printnames of one session share the same
|
||||||
|
* instance of Hashtable here.
|
||||||
|
* This field is not static because there can be several instances of
|
||||||
|
* the editor that shouldn't interfere.
|
||||||
|
*/
|
||||||
|
protected final Hashtable subcatNameHashtable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* contains the names of the paramters of this function (String).
|
||||||
|
* Parallel with paramTexts
|
||||||
|
*/
|
||||||
|
protected final Vector paramNames = new Vector();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fetches the name of the nth parameter
|
||||||
|
* @param n the number of the wanted paramter
|
||||||
|
* @return the corresponding name, null if not found
|
||||||
|
*/
|
||||||
|
public String getParamName(int n) {
|
||||||
|
String name = null;
|
||||||
|
try {
|
||||||
|
name = (String)this.paramNames.get(n);
|
||||||
|
} catch (ArrayIndexOutOfBoundsException e) {
|
||||||
|
subcatLogger.warn(e.getLocalizedMessage());
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* contains the descriptions of the paramters of this function (String).
|
||||||
|
* Parallel with paramNames
|
||||||
|
*/
|
||||||
|
protected final Vector paramTexts = new Vector();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a Printname for a normal GF function
|
||||||
|
* @param myFun the function name
|
||||||
|
* @param myPrintname the printname given for this function
|
||||||
|
* @param myFullnames the Hashtable for the full names for the category
|
||||||
|
* names for the shortnames like %PREDEF
|
||||||
|
*/
|
||||||
|
public Printname(String myFun, String myPrintname, Hashtable myFullnames) {
|
||||||
|
myFun = myFun.trim();
|
||||||
|
myPrintname = myPrintname.trim();
|
||||||
|
this.printname = myPrintname;
|
||||||
|
this.subcatNameHashtable = myFullnames;
|
||||||
|
|
||||||
|
//parse the fun name
|
||||||
|
{
|
||||||
|
int index = myFun.indexOf('.');
|
||||||
|
if (index > -1) {
|
||||||
|
//a valid fun name must not be empty
|
||||||
|
this.fun = myFun.substring(index + 1);
|
||||||
|
this.module = myFun.substring(0, index);
|
||||||
|
} else {
|
||||||
|
this.fun = myFun;
|
||||||
|
this.module = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//parse the parameters and cut that part
|
||||||
|
{
|
||||||
|
int index = Utils.indexOfNotEscaped(myPrintname, PARAM);
|
||||||
|
if (index > -1) {
|
||||||
|
String paramPart = myPrintname.substring(index);
|
||||||
|
String splitString;
|
||||||
|
//split takes a regexp as an argument. So we have to escape the '\' again.
|
||||||
|
if (PARAM.startsWith("\\")) {
|
||||||
|
splitString = "\\" + PARAM;
|
||||||
|
} else {
|
||||||
|
splitString = PARAM;
|
||||||
|
}
|
||||||
|
String[] params = paramPart.split(splitString);
|
||||||
|
//don't use the first split part, since it's empty
|
||||||
|
for (int i = 1; i < params.length; i++) {
|
||||||
|
String current = params[i];
|
||||||
|
int nameEnd = current.indexOf(' ');
|
||||||
|
int nameEnd2 = Utils.indexOfNotEscaped(current, PARAM);
|
||||||
|
if (nameEnd == -1) {
|
||||||
|
nameEnd = current.length();
|
||||||
|
}
|
||||||
|
String name = current.substring(0, nameEnd);
|
||||||
|
String description;
|
||||||
|
if (nameEnd < current.length() - 1) {
|
||||||
|
description = current.substring(nameEnd + 1).trim();
|
||||||
|
} else {
|
||||||
|
description = "";
|
||||||
|
}
|
||||||
|
this.paramNames.addElement(name);
|
||||||
|
this.paramTexts.addElement(description);
|
||||||
|
}
|
||||||
|
myPrintname = myPrintname.substring(0, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//extract the subcategory part and cut that part
|
||||||
|
{
|
||||||
|
int index = Utils.indexOfNotEscaped(myPrintname, SUBCAT);
|
||||||
|
if (index > -1) {
|
||||||
|
String subcatPart = myPrintname.substring(index);
|
||||||
|
myPrintname = myPrintname.substring(0, index);
|
||||||
|
int indFull = subcatPart.indexOf('{');
|
||||||
|
if (indFull > -1) {
|
||||||
|
int indFullEnd = subcatPart.indexOf('}', indFull + 1);
|
||||||
|
if (indFullEnd == -1) {
|
||||||
|
indFullEnd = subcatPart.length();
|
||||||
|
}
|
||||||
|
String fullName = subcatPart.substring(indFull + 1, indFullEnd);
|
||||||
|
this.subcat = subcatPart.substring(0, indFull).trim();
|
||||||
|
this.subcatNameHashtable.put(this.subcat, fullName);
|
||||||
|
if (subcatLogger.isDebugEnabled()) {
|
||||||
|
subcatLogger.debug("new fullname '" + fullName + "' for category (shortname) '" + this.subcat + "'");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
subcat = subcatPart.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this.subcat = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a constructor for GF command that don't represent functions,
|
||||||
|
* like d, ph, ac
|
||||||
|
* @param command the GF command
|
||||||
|
* @param explanation an explanatory text what this command does
|
||||||
|
*/
|
||||||
|
protected Printname(String command, String explanation) {
|
||||||
|
this.fun = command;
|
||||||
|
this.subcatNameHashtable = null;
|
||||||
|
this.subcat = null;
|
||||||
|
this.module = "";
|
||||||
|
this.printname = explanation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Special constructor for bound variables.
|
||||||
|
* These printnames don't get saved since they don't always exist and
|
||||||
|
* also consist of quite few information.
|
||||||
|
* @param bound The name of the bound variable
|
||||||
|
*/
|
||||||
|
public Printname(String bound) {
|
||||||
|
this.fun = bound;
|
||||||
|
this.subcatNameHashtable = null;
|
||||||
|
this.subcat = null;
|
||||||
|
this.module = null;
|
||||||
|
this.printname = bound + "$insert the bound variable" + bound;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** the text that is to be displayed in the refinement lists */
|
||||||
|
public String getDisplayText() {
|
||||||
|
String result;
|
||||||
|
result = extractDisplayText(this.printname);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the text that is to be displayed as the tooltip.
|
||||||
|
* Will always be enclosed in <html> </html> tags.
|
||||||
|
*/
|
||||||
|
public String getTooltipText() {
|
||||||
|
if (this.displayedPrintname != null) {
|
||||||
|
return this.displayedPrintname;
|
||||||
|
} else {
|
||||||
|
String result;
|
||||||
|
result = extractTooltipText(this.printname);
|
||||||
|
if (this.paramNames.size() > 0) {
|
||||||
|
String params = htmlifyParams();
|
||||||
|
//will result in <html> wrapping
|
||||||
|
result = htmlAppend(result, params);
|
||||||
|
} else {
|
||||||
|
//wrap in <html> by force
|
||||||
|
result = htmlAppend(result, "");
|
||||||
|
}
|
||||||
|
this.displayedPrintname = result;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* extracts the part of the body of the printname that is the tooltip
|
||||||
|
* @param myPrintname the body of the printname
|
||||||
|
* @return the tooltip
|
||||||
|
*/
|
||||||
|
public static String extractTooltipText(String myPrintname) {
|
||||||
|
//if the description part of the fun has no \$ to denote a tooltip,
|
||||||
|
//but the subcat description has one, than we must take extra
|
||||||
|
//caution
|
||||||
|
final int indTT = Utils.indexOfNotEscaped(myPrintname, TT_START);
|
||||||
|
final int indSC = Utils.indexOfNotEscaped(myPrintname, SUBCAT);
|
||||||
|
int ind;
|
||||||
|
if ((indSC > -1) && (indSC < indTT)) {
|
||||||
|
ind = -1;
|
||||||
|
} else {
|
||||||
|
ind = indTT;
|
||||||
|
}
|
||||||
|
String result;
|
||||||
|
if (ind > -1) {
|
||||||
|
result = myPrintname.substring(ind + TT_START.length());
|
||||||
|
} else {
|
||||||
|
result = myPrintname;
|
||||||
|
}
|
||||||
|
ind = Utils.indexOfNotEscaped(result, SUBCAT);
|
||||||
|
if (ind > -1) {
|
||||||
|
result = result.substring(0, ind);
|
||||||
|
}
|
||||||
|
ind = Utils.indexOfNotEscaped(result, PARAM);
|
||||||
|
if (ind > -1) {
|
||||||
|
result = result.substring(0, ind);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* extracts the part of the body of the printname that is the
|
||||||
|
* text entry for the JList
|
||||||
|
* @param myPrintname the body of the printname
|
||||||
|
* @return the one-line description of this Printname's fun
|
||||||
|
*/
|
||||||
|
public static String extractDisplayText(String myPrintname) {
|
||||||
|
String result;
|
||||||
|
int ind = Utils.indexOfNotEscaped(myPrintname, TT_START);
|
||||||
|
if (ind > -1) {
|
||||||
|
result = myPrintname.substring(0, ind);
|
||||||
|
} else {
|
||||||
|
result = myPrintname;
|
||||||
|
}
|
||||||
|
ind = Utils.indexOfNotEscaped(result, SUBCAT);
|
||||||
|
if (ind > -1) {
|
||||||
|
result = result.substring(0, ind);
|
||||||
|
}
|
||||||
|
ind = Utils.indexOfNotEscaped(result, PARAM);
|
||||||
|
if (ind > -1) {
|
||||||
|
result = result.substring(0, ind);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends the given string insertion to original and
|
||||||
|
* returns the result. If original is already HTML, the appended
|
||||||
|
* text will get right before the </html> tag.
|
||||||
|
* If original is no HTML, it will be enclosed in <html>
|
||||||
|
* @param original The String that is to come before insertion
|
||||||
|
* @param insertion the String to be appended
|
||||||
|
* @return the aforementioned result.
|
||||||
|
*/
|
||||||
|
public static String htmlAppend(String original, String insertion) {
|
||||||
|
StringBuffer result = new StringBuffer(original);
|
||||||
|
int htmlindex = result.indexOf("</html>");
|
||||||
|
|
||||||
|
if (htmlindex > -1) {
|
||||||
|
result.insert(htmlindex, insertion);
|
||||||
|
} else {
|
||||||
|
result.insert(0,"<html>").append(insertion).append("</html>");
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepends the given string insertion to original and
|
||||||
|
* returns the result. If original is already HTML, the appended
|
||||||
|
* text will get right after the <html> tag.
|
||||||
|
* If original is no HTML, it will be enclosed in <html>
|
||||||
|
* @param original The String that is to come after insertion
|
||||||
|
* @param insertion the String to be appended
|
||||||
|
* @return the aforementioned result.
|
||||||
|
*/
|
||||||
|
public static String htmlPrepend(String original, String insertion) {
|
||||||
|
StringBuffer result = new StringBuffer(original);
|
||||||
|
int htmlindex = result.indexOf("<html>");
|
||||||
|
|
||||||
|
if (htmlindex > -1) {
|
||||||
|
result.insert(htmlindex, insertion);
|
||||||
|
} else {
|
||||||
|
result.insert(0,insertion).insert(0,"<html>").append("</html>");
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wraps a single parameter with explanatory text
|
||||||
|
* into <dt> and <dd> tags
|
||||||
|
* @param which the number of the parameter
|
||||||
|
* @return the resulting String, "" if the wanted parameter
|
||||||
|
* is not stored (illegal index)
|
||||||
|
*/
|
||||||
|
protected String htmlifyParam(int which) {
|
||||||
|
try {
|
||||||
|
String result = "<dt>" + this.paramNames.get(which) + "</dt>"
|
||||||
|
+ "<dd>" + this.paramTexts.get(which) + "</dd>";
|
||||||
|
return result;
|
||||||
|
} catch (ArrayIndexOutOfBoundsException e) {
|
||||||
|
subcatLogger.warn(e.getLocalizedMessage());
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wraps a single parameter together with its explanatory text into
|
||||||
|
* a HTML definition list (<dl> tags).
|
||||||
|
* Also the result is wrapped in <html> tags.
|
||||||
|
* @param which the number of the parameter
|
||||||
|
* @return the resulting definition list, null if the param is not found.
|
||||||
|
*/
|
||||||
|
public String htmlifySingleParam(int which) {
|
||||||
|
String text = htmlifyParam(which);
|
||||||
|
if (text.equals("")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String result = "<html><dl>" + text + "</dl></html>";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wraps all parameters together with their explanatory text into
|
||||||
|
* a HTML definition list (<dl> tags).
|
||||||
|
* No <html> tags are wrapped around here, that is sth. the caller
|
||||||
|
* has to do!
|
||||||
|
* @return the resulting definition list, "" if which is larger than
|
||||||
|
* the amount of stored params
|
||||||
|
*/
|
||||||
|
public String htmlifyParams() {
|
||||||
|
if (this.paramNames.size() == 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
StringBuffer result = new StringBuffer("<h4>Parameters:</h4><dl>");
|
||||||
|
for (int i = 0; i < this.paramNames.size(); i++) {
|
||||||
|
result.append(htmlifyParam(i));
|
||||||
|
}
|
||||||
|
result.append("</dl>");
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a testing method that is not called from KeY.
|
||||||
|
* Probably things like this should be automated via JUnit ...
|
||||||
|
* @param args not used
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
String SandS = "boolean 'and' for sentences$true iff both of the two given sentences is equivalent to true%BOOL#alpha the first of the two and-conjoined sentences#beta the second of the and-conjoined sentences";
|
||||||
|
String FandS = "andS";
|
||||||
|
Hashtable ht = new Hashtable();
|
||||||
|
Printname pn = new Printname(FandS, SandS, ht);
|
||||||
|
System.out.println(pn);
|
||||||
|
for (int i = 0; i < pn.paramNames.size(); i++) {
|
||||||
|
System.out.println(pn.htmlifySingleParam(i));
|
||||||
|
}
|
||||||
|
System.out.println(pn.getTooltipText());
|
||||||
|
SandS = "boolean 'and' for sentences$true iff both of the two given sentences is equivalent to true%BOOL";
|
||||||
|
FandS = "andS";
|
||||||
|
pn = new Printname(FandS, SandS, ht);
|
||||||
|
System.out.println("*" + pn.getTooltipText());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return getDisplayText() + " \n " + getTooltipText() + " (" + this.paramNames.size() + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
83
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/PrintnameLoader.java
Normal file
83
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/PrintnameLoader.java
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
package de.uka.ilkd.key.ocl.gf;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author daniels
|
||||||
|
*
|
||||||
|
* TODO To change the template for this generated type comment go to
|
||||||
|
* Window - Preferences - Java - Code Style - Code Templates
|
||||||
|
*/
|
||||||
|
public class PrintnameLoader extends AbstractProber {
|
||||||
|
protected final PrintnameManager printnameManager;
|
||||||
|
protected static Logger nogger = Logger.getLogger(Printname.class.getName());
|
||||||
|
/**
|
||||||
|
* @param fromGf The GF process
|
||||||
|
* @param toGf The GF process
|
||||||
|
* @param pm The PrintnameManager on which the read Printnames
|
||||||
|
* will be registered with their fun name.
|
||||||
|
*/
|
||||||
|
public PrintnameLoader(BufferedReader fromGf, BufferedWriter toGf, PrintnameManager pm) {
|
||||||
|
super(fromGf, toGf);
|
||||||
|
this.printnameManager = pm;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the tree child of the XML from beginning to end.
|
||||||
|
* Sets autocompleted to false, if the focus position is open.
|
||||||
|
*/
|
||||||
|
protected void readMessage() {
|
||||||
|
try {
|
||||||
|
String result = this.fromProc.readLine();
|
||||||
|
if (nogger.isDebugEnabled()) {
|
||||||
|
nogger.debug("1 " + result);
|
||||||
|
}
|
||||||
|
//first read line is <message>, but this one gets filtered out in the next line
|
||||||
|
while (result.indexOf("/message")==-1){
|
||||||
|
result = result.trim();
|
||||||
|
if (result.startsWith("printname fun ")) {
|
||||||
|
//unescape backslashes. Probably there are more
|
||||||
|
result = GFEditor2.unescapeTextFromGF(result);
|
||||||
|
this.printnameManager.addNewPrintnameLine(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = this.fromProc.readLine();
|
||||||
|
if (nogger.isDebugEnabled()) {
|
||||||
|
nogger.debug("1 " + result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nogger.isDebugEnabled()) {
|
||||||
|
nogger.debug("finished loading printnames");
|
||||||
|
}
|
||||||
|
} catch(IOException e){
|
||||||
|
System.err.println(e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* asks GF to print a list of all available printnames and
|
||||||
|
* calls the registered PrintnameManager to register those.
|
||||||
|
* @param lang The module for which the grammars should be printed.
|
||||||
|
* If lang is "" or null, the last read grammar module is used.
|
||||||
|
*/
|
||||||
|
public void readPrintnames(String lang) {
|
||||||
|
//send("gf pg -lang=FromUMLTypesOCL -printer=printnames");
|
||||||
|
//prints the printnames of the last loaded grammar,
|
||||||
|
//which can be another one than FromUMLTypesOCL
|
||||||
|
String sendString = "gf pg -printer=printnames";
|
||||||
|
if (lang != null && !("".equals(lang))) {
|
||||||
|
sendString = sendString + " -lang=" + lang;
|
||||||
|
}
|
||||||
|
nogger.info("collecting printnames :" + sendString);
|
||||||
|
send(sendString);
|
||||||
|
readGfedit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
139
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/PrintnameManager.java
Normal file
139
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/PrintnameManager.java
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
package de.uka.ilkd.key.ocl.gf;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author daniels
|
||||||
|
*
|
||||||
|
* An object of this class manages a bunch of printlines which is comprised of
|
||||||
|
* storage and retrieval. Also giving the subcategory shortnames their long
|
||||||
|
* counterpart is done here.
|
||||||
|
*/
|
||||||
|
class PrintnameManager {
|
||||||
|
protected static Logger logger = Logger.getLogger(Printname.class.getName());
|
||||||
|
|
||||||
|
protected final static String frontMatter = "printname fun ";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The hashmap for the names of the sub categories,
|
||||||
|
* with the shortname starting with '%' as the key.
|
||||||
|
* It is important that all Printnames of one session share the same
|
||||||
|
* instance of Hashtable here.
|
||||||
|
* This field is not static because there can be several instances of
|
||||||
|
* the editor that shouldn't interfere.
|
||||||
|
*/
|
||||||
|
protected final Hashtable subcatNames = new Hashtable();
|
||||||
|
|
||||||
|
/** contains all the Printnames with the fun names as keys */
|
||||||
|
protected final Hashtable printnames = new Hashtable();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* processes a line from the "gf pg -printer=printnames" command
|
||||||
|
* @param line the read line from GF
|
||||||
|
* Should look like
|
||||||
|
* printname fun neq = "<>," ++ ("parametrized" ++ ("disequality$to" ++ ("compare" ++ ("two" ++ ("instances" ++ ("on" ++ ("a" ++ ("specific" ++ "type%COMP"))))))))
|
||||||
|
* and needs to get like
|
||||||
|
* printname fun neq = "<>, parametrized disequality$to compare two instances on a specific type%COMP"
|
||||||
|
*/
|
||||||
|
public void addNewPrintnameLine(String line) {
|
||||||
|
line = removePluses(line);
|
||||||
|
|
||||||
|
//remove "printname fun " (the frontMatter)
|
||||||
|
int index = line.indexOf(frontMatter);
|
||||||
|
line = line.substring(index + frontMatter.length()).trim();
|
||||||
|
|
||||||
|
//extract fun name
|
||||||
|
int endFun = line.indexOf(' ');
|
||||||
|
String fun = line.substring(0, endFun);
|
||||||
|
//extract printname
|
||||||
|
String printname = line.substring(line.indexOf('"') + 1, line.lastIndexOf('"'));
|
||||||
|
|
||||||
|
addNewPrintname(fun, printname);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The printname printer of pg spits out no String, but a wrapping of
|
||||||
|
* small Strings conjoined with ++ which includes lots of parantheses.
|
||||||
|
* @param line The GF line from pg -printer=printnames
|
||||||
|
* @return a String representing the actual printname without the clutter
|
||||||
|
*/
|
||||||
|
protected static String removePluses(String line) {
|
||||||
|
line = line.replaceAll("\"\\)*\\s*\\+\\+\\s*\\(*\""," ");
|
||||||
|
int index = line.lastIndexOf('"');
|
||||||
|
line = line.substring(0, index + 1);
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs the actual printname and puts it into printnames
|
||||||
|
* @param myFun the GF abstract fun name
|
||||||
|
* @param myPrintname the printname given by GF
|
||||||
|
*/
|
||||||
|
protected void addNewPrintname(String myFun, String myPrintname) {
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("addNewPrintname, myFun = '" + myFun + "' , myPrintname = '" + myPrintname + "'");
|
||||||
|
}
|
||||||
|
Printname printname = new Printname(myFun, myPrintname, this.subcatNames);
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("printname = '" + printname + "'");
|
||||||
|
}
|
||||||
|
this.printnames.put(myFun, printname);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* looks for the Printname corresponding to the given fun.
|
||||||
|
* If the fun is qualified with a module and no Printname
|
||||||
|
* is found with module, another lookup without the module part
|
||||||
|
* is made.
|
||||||
|
* @param myFun the GF abstract fun name (with or without qualification)
|
||||||
|
* @return the corresponding Printname iff that one exists, null otherwise
|
||||||
|
*/
|
||||||
|
public Printname getPrintname(String myFun) {
|
||||||
|
Printname result = null;
|
||||||
|
if (this.printnames.containsKey(myFun)) {
|
||||||
|
result = (Printname)this.printnames.get(myFun);
|
||||||
|
} else {
|
||||||
|
int index = myFun.indexOf('.');
|
||||||
|
if (index > -1) {
|
||||||
|
//a valid fun name must not be empty
|
||||||
|
String fun = myFun.substring(index + 1);
|
||||||
|
if (printnames.containsKey(fun)) {
|
||||||
|
result = (Printname)this.printnames.get(fun);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (result == null) {
|
||||||
|
//?n indicates that myFun is a metavariable of GF,
|
||||||
|
// which does not occur in the refinement menu.
|
||||||
|
// if that is not wanted, don't call this method!
|
||||||
|
if (!myFun.startsWith("?")) {
|
||||||
|
logger.warn("no printname for '" + myFun + "', pretend that it is a bound variable");
|
||||||
|
return new Printname(myFun);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* looks up the full name for the subcategory name shortname.
|
||||||
|
* This is the %SOMETHING from the printname.
|
||||||
|
* @param shortname The subcat name which should get expanded
|
||||||
|
* @return the corresponding full name, maybe null!
|
||||||
|
*/
|
||||||
|
public String getFullname(String shortname) {
|
||||||
|
String result = (String)this.subcatNames.get(shortname);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
String a = "printname fun stringLiteral = \"arbitrary\" ++ (\"String$click\" ++ (\"read\" ++ (\"and\" ++ (\"enter\" ++ (\"the\" ++ (\"String\" ++ (\"in\" ++ (\"the\" ++ (\"dialog\" ++ (\"TODO%STRING(String\" ++ \"operations)\"))))))))))";
|
||||||
|
System.out.println(a);
|
||||||
|
System.out.println(removePluses(a));
|
||||||
|
a = "printname fun count = \"count\" ++ (\"the\" ++ (\"occurances\" ++ (\"of\" ++ (\"an\" ++ (\"object\" ++ (\"in\" ++ (\"the\" ++ \"collection.\")))))))++ (\"%COLL\" ++ (\"#collElemType\" ++ (\"The\" ++ (\"official\" ++ (\"element\" ++ (\"type\" ++ (\"of\" ++ (\"<i>coll</i>.<br>That\" ++ (\"is,\" ++ (\"the\" ++ (\"parameter\" ++ (\"type\" ++ (\"of\" ++ \"<i>coll</i>\")))))))))))++ (\"#set\" ++ (\"The\" ++ (\"Set\" ++ (\"in\" ++ (\"which\" ++ (\"occurances\" ++ (\"of\" ++ (\"<i>elem</i>\" ++ (\"are\" ++ (\"to\" ++ (\"be\" ++ \"counted.\")))))))))) ++ (\"#elem\" ++ (\"The\" ++ (\"instance\" ++ (\"of\" ++ (\"which\" ++ (\"the\" ++ (\"occurances\" ++ (\"in\" ++ (\"<i>coll</i>\" ++ (\"are\" ++ \"counted.\")))))))))))))";
|
||||||
|
System.out.println(a);
|
||||||
|
System.out.println(removePluses(a));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
193
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/ReadDialog.java
Normal file
193
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/ReadDialog.java
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
/*
|
||||||
|
* Created on 13.05.2005
|
||||||
|
*
|
||||||
|
* TODO To change the template for this generated file go to
|
||||||
|
* Window - Preferences - Java - Code Style - Code Templates
|
||||||
|
*/
|
||||||
|
package de.uka.ilkd.key.ocl.gf;
|
||||||
|
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.GridLayout;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import javax.swing.ButtonGroup;
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JDialog;
|
||||||
|
import javax.swing.JFileChooser;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JRadioButton;
|
||||||
|
import javax.swing.JTextField;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes care of reading in Strings that are to be parsed and terms.
|
||||||
|
* @author daniels
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class ReadDialog implements ActionListener{
|
||||||
|
/** XML parsing debug messages */
|
||||||
|
protected static Logger xmlLogger = Logger.getLogger(GFEditor2.class.getName() + "_XML");
|
||||||
|
/** The window to which this class belongs */
|
||||||
|
protected final GFEditor2 owner;
|
||||||
|
/** is the main thing of this class */
|
||||||
|
protected final JDialog readDialog;
|
||||||
|
/** main area of the Read dialog (content pane)*/
|
||||||
|
private final JPanel inputPanel = new JPanel();
|
||||||
|
/** OK, Cancel, Browse in the Read dialog */
|
||||||
|
private final JPanel inputPanel2 = new JPanel();
|
||||||
|
/** in the Read dialog the OK button */
|
||||||
|
private final JButton ok = new JButton("OK");
|
||||||
|
/** in the Read dialog the Cancel button */
|
||||||
|
private final JButton cancel = new JButton("Cancel");
|
||||||
|
/** in the Read dialog the Browse button */
|
||||||
|
private final JButton browse = new JButton("Browse...");
|
||||||
|
/** groups inputField and inputLabel */
|
||||||
|
private final JPanel inputPanel3 = new JPanel();
|
||||||
|
/** for 'Read' to get the input */
|
||||||
|
private final JTextField inputField = new JTextField();
|
||||||
|
/** "Read: " */
|
||||||
|
private final JLabel inputLabel = new JLabel("Read: ");
|
||||||
|
/** the radio group in the Read dialog to select Term or String */
|
||||||
|
private final ButtonGroup readGroup = new ButtonGroup();
|
||||||
|
/** to select to input a Term in the Read dialog */
|
||||||
|
private final JRadioButton termReadButton = new JRadioButton("Term");
|
||||||
|
/** to select to input a String in the Read dialog */
|
||||||
|
private final JRadioButton stringReadButton = new JRadioButton("String");
|
||||||
|
/** used for new Topic, Import and Browse (readDialog) */
|
||||||
|
protected final JFileChooser fc = new JFileChooser("./");
|
||||||
|
/**
|
||||||
|
* if a user sends a custom command to GF, he might want to do this
|
||||||
|
* again with the same command.
|
||||||
|
* Therefore it is saved.
|
||||||
|
*/
|
||||||
|
private String parseInput = "";
|
||||||
|
/**
|
||||||
|
* if the user enters a term, he perhaps wants to input the same text again.
|
||||||
|
* Therefore it is saved.
|
||||||
|
*/
|
||||||
|
private String termInput = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates a modal dialog
|
||||||
|
* @param owner The parent for which this dialog shall be modal.
|
||||||
|
*/
|
||||||
|
protected ReadDialog(GFEditor2 owner) {
|
||||||
|
this.owner = owner;
|
||||||
|
readDialog= new JDialog(owner, "Input", true);
|
||||||
|
readDialog.setLocationRelativeTo(owner);
|
||||||
|
readDialog.getContentPane().add(inputPanel);
|
||||||
|
readDialog.setSize(480,135);
|
||||||
|
|
||||||
|
termReadButton.setActionCommand("term");
|
||||||
|
stringReadButton.setSelected(true);
|
||||||
|
stringReadButton.setActionCommand("lin");
|
||||||
|
// Group the radio buttons.
|
||||||
|
readGroup.add(stringReadButton);
|
||||||
|
readGroup.add(termReadButton);
|
||||||
|
JPanel readButtonPanel = new JPanel();
|
||||||
|
readButtonPanel.setLayout(new GridLayout(3,1));
|
||||||
|
readButtonPanel.setPreferredSize(new Dimension(70, 70));
|
||||||
|
readButtonPanel.add(new JLabel("Format:"));
|
||||||
|
readButtonPanel.add(stringReadButton);
|
||||||
|
readButtonPanel.add(termReadButton);
|
||||||
|
inputPanel.setLayout(new BorderLayout(10,10));
|
||||||
|
inputPanel3.setLayout(new GridLayout(2,1,5,5));
|
||||||
|
inputPanel3.add(inputLabel);
|
||||||
|
inputPanel3.add(inputField);
|
||||||
|
ok.addActionListener(this);
|
||||||
|
browse.addActionListener(this);
|
||||||
|
cancel.addActionListener(this);
|
||||||
|
inputField.setPreferredSize(new Dimension(300,23));
|
||||||
|
inputPanel.add(inputPanel3, BorderLayout.CENTER);
|
||||||
|
inputPanel.add(new JLabel(" "), BorderLayout.WEST);
|
||||||
|
inputPanel.add(readButtonPanel, BorderLayout.EAST);
|
||||||
|
inputPanel.add(inputPanel2, BorderLayout.SOUTH);
|
||||||
|
inputPanel2.add(ok);
|
||||||
|
inputPanel2.add(cancel);
|
||||||
|
inputPanel2.add(browse);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows this modal dialog.
|
||||||
|
* The previous input text will be there again.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected void show() {
|
||||||
|
if (stringReadButton.isSelected()) {
|
||||||
|
inputField.setText(this.parseInput);
|
||||||
|
} else {
|
||||||
|
inputField.setText(this.termInput);
|
||||||
|
}
|
||||||
|
this.readDialog.setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the font of all GUI elements to font
|
||||||
|
* @param font
|
||||||
|
*/
|
||||||
|
protected void setFont(Font font) {
|
||||||
|
ok.setFont(font);
|
||||||
|
cancel.setFont(font);
|
||||||
|
inputLabel.setFont(font);
|
||||||
|
browse.setFont(font);
|
||||||
|
termReadButton.setFont(font);
|
||||||
|
stringReadButton.setFont(font);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the ActionListener method that does the user interaction
|
||||||
|
*/
|
||||||
|
public void actionPerformed(ActionEvent ae) {
|
||||||
|
Object obj = ae.getSource();
|
||||||
|
|
||||||
|
if ( obj == cancel ) {
|
||||||
|
readDialog.setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( obj == browse ) {
|
||||||
|
if (fc.getChoosableFileFilters().length<2)
|
||||||
|
fc.addChoosableFileFilter(new GrammarFilter());
|
||||||
|
int returnVal = fc.showOpenDialog(owner);
|
||||||
|
if (returnVal == JFileChooser.APPROVE_OPTION) {
|
||||||
|
File file = fc.getSelectedFile();
|
||||||
|
inputField.setText(file.getPath().replace('\\','/'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( obj == ok ) {
|
||||||
|
owner.treeChanged = true;
|
||||||
|
if (termReadButton.isSelected()) {
|
||||||
|
termInput = inputField.getText();
|
||||||
|
if (termInput.indexOf(File.separatorChar)==-1){
|
||||||
|
owner.send("g "+termInput);
|
||||||
|
if (xmlLogger.isDebugEnabled()) xmlLogger.debug("sending term string");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
owner.send("tfile "+termInput);
|
||||||
|
if (xmlLogger.isDebugEnabled()) {
|
||||||
|
xmlLogger.debug("sending file term: "+termInput);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { //String selected
|
||||||
|
parseInput = inputField.getText();
|
||||||
|
if (parseInput.indexOf(File.separatorChar)==-1){
|
||||||
|
owner.send("p "+parseInput);
|
||||||
|
if (xmlLogger.isDebugEnabled()) xmlLogger.debug("sending parse string: "+parseInput);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
owner.send("pfile "+parseInput);
|
||||||
|
if (xmlLogger.isDebugEnabled()) xmlLogger.debug("sending file parse string: "+parseInput);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
readDialog.setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
146
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/RealCommand.java
Normal file
146
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/RealCommand.java
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
/*
|
||||||
|
* Created on 21.04.2005
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package de.uka.ilkd.key.ocl.gf;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author daniels
|
||||||
|
* This class represents a command, that is sent to GF
|
||||||
|
*/
|
||||||
|
class RealCommand extends GFCommand {
|
||||||
|
|
||||||
|
private final static HashMap fullnames = new HashMap();
|
||||||
|
|
||||||
|
protected final static Logger logger = Logger.getLogger(Printname.class.getName());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a Command that stands for a GF command, no link command
|
||||||
|
* sets all the attributes of this semi-immutable class.
|
||||||
|
* @param myCommand the actual GF command
|
||||||
|
* @param processedSubcats
|
||||||
|
* @param manager maps funs to previously read Printnames.
|
||||||
|
* Thus needs to be the same object.
|
||||||
|
* @param myShowText The text GF prints in the show part of the XML
|
||||||
|
* which should be the command followed by the printname
|
||||||
|
* @param mlAbstract is true, iff the menu language is set to Abstract
|
||||||
|
* Then no preloaded printnames are used.
|
||||||
|
*/
|
||||||
|
public RealCommand(final String myCommand, HashSet processedSubcats, final PrintnameManager manager, final String myShowText, boolean mlAbstract) {
|
||||||
|
if (fullnames.isEmpty()) {
|
||||||
|
fullnames.put("w", "wrap");
|
||||||
|
fullnames.put("ch", "change head");
|
||||||
|
fullnames.put("rc", "refine from history:");
|
||||||
|
}
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("new RealCommand: " + myCommand);
|
||||||
|
}
|
||||||
|
this.command = myCommand.trim();
|
||||||
|
this.showText = myShowText;
|
||||||
|
//extract command type
|
||||||
|
int ind = this.command.indexOf(' ');
|
||||||
|
if (ind > -1) {
|
||||||
|
this.commandType = this.command.substring(0, ind);
|
||||||
|
} else {
|
||||||
|
this.commandType = this.command;
|
||||||
|
}
|
||||||
|
|
||||||
|
//extract the argument position for wrapping commands and cut that part
|
||||||
|
if (this.commandType.equals("w")) {
|
||||||
|
int beforeNumber = this.command.lastIndexOf(' ');
|
||||||
|
int protoarg;
|
||||||
|
try {
|
||||||
|
String argumentAsString = this.command.substring(beforeNumber + 1);
|
||||||
|
protoarg = Integer.parseInt(argumentAsString);
|
||||||
|
} catch (Exception e) {
|
||||||
|
protoarg = -1;
|
||||||
|
}
|
||||||
|
this.argument = protoarg;
|
||||||
|
} else {
|
||||||
|
this.argument = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//extract the fun of the GF command
|
||||||
|
if (this.commandType.equals("w")) {
|
||||||
|
int beforePos = this.command.indexOf(' ');
|
||||||
|
int afterPos = this.command.lastIndexOf(' ');
|
||||||
|
if (beforePos > -1 && afterPos > beforePos) {
|
||||||
|
this.funName = this.command.substring(beforePos + 1, afterPos);
|
||||||
|
} else {
|
||||||
|
this.funName = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int beforePos = this.command.indexOf(' ');
|
||||||
|
if (beforePos > -1) {
|
||||||
|
this.funName = this.command.substring(beforePos + 1);
|
||||||
|
} else {
|
||||||
|
this.funName = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//get corresponding Printname
|
||||||
|
if (this.commandType.equals("d")) {
|
||||||
|
this.printname = Printname.delete;
|
||||||
|
} else if (this.commandType.equals("ac")) {
|
||||||
|
this.printname = Printname.addclip;
|
||||||
|
} else if (this.commandType.equals("ph")) {
|
||||||
|
this.printname = Printname.printhistory;
|
||||||
|
} else if (this.commandType.equals("rc")) {
|
||||||
|
String subtree = this.showText.substring(3);
|
||||||
|
this.printname = new Printname(this.getCommand(), subtree + "$paste the previously copied subtree here<br>" + subtree);
|
||||||
|
} else if (mlAbstract) {
|
||||||
|
//create a new Printname
|
||||||
|
this.printname = new Printname(funName, myShowText, null);
|
||||||
|
} else {
|
||||||
|
this.printname = manager.getPrintname(funName);
|
||||||
|
}
|
||||||
|
if (this.getSubcat() != null) {
|
||||||
|
if (processedSubcats.contains(this.getSubcat())) {
|
||||||
|
newSubcat = false;
|
||||||
|
} else {
|
||||||
|
newSubcat = true;
|
||||||
|
processedSubcats.add(this.getSubcat());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
newSubcat = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** the text that is to be displayed in the refinement lists */
|
||||||
|
public String getDisplayText() {
|
||||||
|
String result = "";
|
||||||
|
if (fullnames.containsKey(this.commandType)) {
|
||||||
|
result = fullnames.get(this.commandType) + " '";
|
||||||
|
}
|
||||||
|
result = result + this.printname.getDisplayText();
|
||||||
|
if (fullnames.containsKey(this.commandType)) {
|
||||||
|
result = result + "'";
|
||||||
|
}
|
||||||
|
if (this.commandType.equals("w")) {
|
||||||
|
String insertion = " as argument " + (this.argument + 1);
|
||||||
|
result = result + insertion;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**the text that is to be displayed as the tooltip */
|
||||||
|
public String getTooltipText() {
|
||||||
|
String result;
|
||||||
|
result = this.printname.getTooltipText();
|
||||||
|
if (this.commandType.equals("w")) {
|
||||||
|
String insertion = "<br>The selected sub-tree will be the " + (this.argument + 1) + ". argument of this refinement.";
|
||||||
|
result = Printname.htmlAppend(result, insertion);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSubcat() {
|
||||||
|
return this.printname.getSubcat();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final String showText;
|
||||||
|
}
|
||||||
58
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/RefinedAstNodeData.java
Normal file
58
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/RefinedAstNodeData.java
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Created on 27.04.2005
|
||||||
|
*/
|
||||||
|
package de.uka.ilkd.key.ocl.gf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author daniels
|
||||||
|
* An object of this class represents a line in the GF abstract syntax tree
|
||||||
|
* in the graphical form. Well, not really, but how this line appears there
|
||||||
|
* and what its tooltip is is stored here.
|
||||||
|
* RefinedAstNodeData has its tooltip from the function it represents, not
|
||||||
|
* from its parent node.
|
||||||
|
*/
|
||||||
|
class RefinedAstNodeData implements AstNodeData {
|
||||||
|
|
||||||
|
protected final Printname printname;
|
||||||
|
protected final GfAstNode node;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* all we have to know about an already refined node is its Printname
|
||||||
|
* and the GF line representing it
|
||||||
|
* @param pname the suiting Printname, may be null if the line could
|
||||||
|
* not be parsed
|
||||||
|
* @param node the GfAstNode for the current line
|
||||||
|
*/
|
||||||
|
public RefinedAstNodeData(Printname pname, GfAstNode node) {
|
||||||
|
this.printname = pname;
|
||||||
|
this.node = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the printname associated with this object
|
||||||
|
*/
|
||||||
|
public Printname getPrintname() {
|
||||||
|
return this.printname;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return displays the tooltip of the registered Printname,
|
||||||
|
* which may be null
|
||||||
|
*/
|
||||||
|
public String getParamTooltip() {
|
||||||
|
if (getPrintname() != null) {
|
||||||
|
return getPrintname().getTooltipText();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isMeta() {
|
||||||
|
return this.node.isMeta();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return this.node.getLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
66
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/ToolTipCellRenderer.java
Normal file
66
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/ToolTipCellRenderer.java
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Created on 13.04.2005
|
||||||
|
*
|
||||||
|
* TODO To change the template for this generated file go to
|
||||||
|
* Window - Preferences - Java - Code Style - Code Templates
|
||||||
|
*/
|
||||||
|
package de.uka.ilkd.key.ocl.gf;
|
||||||
|
|
||||||
|
import java.awt.Component;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JList;
|
||||||
|
import javax.swing.ListCellRenderer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A cell renderer, that returns JLables, that put everything after the first
|
||||||
|
* '$' character into their tooltip
|
||||||
|
* @author daniels
|
||||||
|
*/
|
||||||
|
public class ToolTipCellRenderer extends JLabel implements ListCellRenderer {
|
||||||
|
|
||||||
|
protected static Logger logger = Logger.getLogger(ToolTipCellRenderer.class.getName());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a JLabel with a tooltip in which everything after the
|
||||||
|
* first '$' character is.
|
||||||
|
* @param list Well, the list this cell belongs to
|
||||||
|
* @param value value to display
|
||||||
|
* @param index cell index
|
||||||
|
* @param isSelected is the cell selected
|
||||||
|
* @param cellHasFocus the list and the cell have the focus
|
||||||
|
* @return a suiting JLabel
|
||||||
|
*/
|
||||||
|
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||||
|
if (isSelected) {
|
||||||
|
setBackground(list.getSelectionBackground());
|
||||||
|
setForeground(list.getSelectionForeground());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setBackground(list.getBackground());
|
||||||
|
setForeground(list.getForeground());
|
||||||
|
}
|
||||||
|
setEnabled(list.isEnabled());
|
||||||
|
setFont(list.getFont());
|
||||||
|
setOpaque(true);
|
||||||
|
|
||||||
|
|
||||||
|
if (value == null) {
|
||||||
|
setText("Null-Value!!! Something went terribly wrong here!");
|
||||||
|
} else if (value instanceof GFCommand){
|
||||||
|
GFCommand gfc = (GFCommand)value;
|
||||||
|
String disText = gfc.getDisplayText();
|
||||||
|
if (gfc instanceof LinkCommand) {
|
||||||
|
//italic font could be an alternative
|
||||||
|
disText = "-> " + disText;
|
||||||
|
}
|
||||||
|
setText(disText);
|
||||||
|
setToolTipText(gfc.getTooltipText());
|
||||||
|
} else {
|
||||||
|
setText(value.toString());
|
||||||
|
setToolTipText("Strange thing of class '" + value.getClass() + "'");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Created on 27.04.2005
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package de.uka.ilkd.key.ocl.gf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author daniels
|
||||||
|
*
|
||||||
|
* represents an open, unrefined node in the AST.
|
||||||
|
* It knows, how it is called and described (tooltip).
|
||||||
|
*/
|
||||||
|
public class UnrefinedAstNodeData implements AstNodeData {
|
||||||
|
protected final GfAstNode node;
|
||||||
|
protected final String paramTooltip;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For a child we have to know its name, its type and the tooltip
|
||||||
|
* @param pTooltip
|
||||||
|
* @param node The GfAstNode for the current AST node, for which
|
||||||
|
* this AstNodeData is the data for.
|
||||||
|
*/
|
||||||
|
public UnrefinedAstNodeData(String pTooltip, GfAstNode node) {
|
||||||
|
this.node = node;
|
||||||
|
this.paramTooltip = pTooltip;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return no refinement, no printname, thus null
|
||||||
|
*/
|
||||||
|
public Printname getPrintname() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the parameter tooltip that this node has as a child
|
||||||
|
* of its parent (who gave it to it depending on its position)
|
||||||
|
*/
|
||||||
|
public String getParamTooltip() {
|
||||||
|
return this.paramTooltip;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isMeta() {
|
||||||
|
return this.node.isMeta();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return this.node.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
156
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/Utils.java
Normal file
156
src/JavaGUI2/de/uka/ilkd/key/ocl/gf/Utils.java
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
// This file is part of KeY - Integrated Deductive Software Design
|
||||||
|
// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany
|
||||||
|
// Universitaet Koblenz-Landau, Germany
|
||||||
|
// Chalmers University of Technology, Sweden
|
||||||
|
//
|
||||||
|
// The KeY system is protected by the GNU General Public License.
|
||||||
|
// See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
package de.uka.ilkd.key.ocl.gf;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import javax.swing.ProgressMonitor;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
public class Utils {
|
||||||
|
protected static Logger timeLogger = Logger.getLogger("de.uka.ilkd.key.ocl.gf.utils.timer");
|
||||||
|
protected static Logger deleteLogger = Logger.getLogger("de.uka.ilkd.key.ocl.gf.utils.delete");
|
||||||
|
|
||||||
|
private Utils() {
|
||||||
|
//non-instantiability enforced
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String gf = "gf";
|
||||||
|
public static final String gfm = "gfm";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the extension of a file.
|
||||||
|
*/
|
||||||
|
public static String getExtension(File f) {
|
||||||
|
String ext = null;
|
||||||
|
String s = f.getName();
|
||||||
|
int i = s.lastIndexOf('.');
|
||||||
|
|
||||||
|
if (i > 0 && i < s.length() - 1) {
|
||||||
|
ext = s.substring(i+1).toLowerCase();
|
||||||
|
}
|
||||||
|
return ext;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Sets the progress on the given ProgressMonitor and logs the current time.
|
||||||
|
* @param pm the monitor which is to be updated. If null, only logging is done
|
||||||
|
* @param progress The progress in absolute ticks
|
||||||
|
* @param note The note that is to be displayed above the progress monitor
|
||||||
|
*/
|
||||||
|
public static void tickProgress(ProgressMonitor pm, int progress, String note) {
|
||||||
|
if (note != null) {
|
||||||
|
if (timeLogger.isDebugEnabled()) {
|
||||||
|
timeLogger.debug(System.currentTimeMillis() + " : " + note);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pm == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pm.setProgress(progress);
|
||||||
|
if (note != null) {
|
||||||
|
pm.setNote(note);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* schedules all Eng, OCL and Ger grammar files for deletion.
|
||||||
|
* @param grammarsDir The directory where those files are
|
||||||
|
*/
|
||||||
|
public static void cleanupFromUMLTypes(String grammarsDir) {
|
||||||
|
String[] endings = {"Eng.gf", "Eng.gfc", "Ger.gf", "Ger.gfc", "OCL.gf", "OCL.gfc", ".gf", ".gfc"};
|
||||||
|
for (int i = 0; i < endings.length; i++) {
|
||||||
|
String filename = grammarsDir + File.separator + GFEditor2.modelModulName + endings[i];
|
||||||
|
File file = new File(filename);
|
||||||
|
file.deleteOnExit();
|
||||||
|
if (deleteLogger.isDebugEnabled()) {
|
||||||
|
deleteLogger.debug("scheduled for deletion: " + filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
File file = new File(grammarsDir);
|
||||||
|
file.deleteOnExit();
|
||||||
|
file = file.getParentFile();
|
||||||
|
file.deleteOnExit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* shamelessly copied from de.uka.ilkd.key.gui.Main
|
||||||
|
* With that, the editor is compilable without changes.
|
||||||
|
*/
|
||||||
|
private static final String LOGGER_CONFIGURATION =
|
||||||
|
System.getProperty("user.home")+
|
||||||
|
File.separator+".key"+File.separator+"logger.props";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* shamelessly copied from de.uka.ilkd.key.gui.Main
|
||||||
|
* With that, the editor is compilable without changes.
|
||||||
|
* Only gets called in stand-alone mode, not when run with KeY.
|
||||||
|
*/
|
||||||
|
public static void configureLogger() {
|
||||||
|
if ((new File(LOGGER_CONFIGURATION)).exists())
|
||||||
|
org.apache.log4j.PropertyConfigurator.configureAndWatch(
|
||||||
|
LOGGER_CONFIGURATION, 1500);
|
||||||
|
else {
|
||||||
|
org.apache.log4j.BasicConfigurator.configure();
|
||||||
|
Logger.getRootLogger().setLevel(org.apache.log4j.Level.ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches for the first occurace not escaped with '\' of toBeFound in s.
|
||||||
|
* Works like String::indexOf otherwise
|
||||||
|
* @param s the String to search in
|
||||||
|
* @param toBeFound the String to search for
|
||||||
|
* @return the index of toBeFound, -1 if not found (or only escaped)
|
||||||
|
*/
|
||||||
|
public static int indexOfNotEscaped(String s, String toBeFound) {
|
||||||
|
return indexOfNotEscaped(s, toBeFound, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches for the first occurace not escaped with '\' of toBeFound in s.
|
||||||
|
* Works like String::indexOf otherwise
|
||||||
|
* @param s the String to search in
|
||||||
|
* @param toBeFound the String to search for
|
||||||
|
* @param startIndex the index in s, from which the search starts
|
||||||
|
* @return the index of toBeFound, -1 if not found (or only escaped)
|
||||||
|
*/
|
||||||
|
public static int indexOfNotEscaped(String s, String toBeFound, int startIndex) {
|
||||||
|
for (int from = startIndex; from < s.length();) {
|
||||||
|
int i = s.indexOf(toBeFound, from);
|
||||||
|
if (i <= 0) {
|
||||||
|
//-1 is not found at all, 0 can't have a '\' before
|
||||||
|
return i;
|
||||||
|
} else if (s.charAt(i-1) != '\\') {
|
||||||
|
return i;
|
||||||
|
} else {
|
||||||
|
from = i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a simple replaceAll replacement, that uses NO regexps
|
||||||
|
* and thus needs no freaking amount of backslashes
|
||||||
|
* @param original The String in which the replacements should take place
|
||||||
|
* @param toReplace the String literal that is to be replaced
|
||||||
|
* @param replacement the replacement string
|
||||||
|
* @return original, but with replacements
|
||||||
|
*/
|
||||||
|
public static String replaceAll(String original, String toReplace, String replacement) {
|
||||||
|
StringBuffer sb = new StringBuffer(original);
|
||||||
|
for (int i = sb.indexOf(toReplace); i >= 0; i = sb.indexOf(toReplace)) {
|
||||||
|
sb.replace(i, i + toReplace.length(), replacement);
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
src/JavaGUI2/jargs-1.0.jar
Normal file
BIN
src/JavaGUI2/jargs-1.0.jar
Normal file
Binary file not shown.
BIN
src/JavaGUI2/log4j-1.2.8.jar
Normal file
BIN
src/JavaGUI2/log4j-1.2.8.jar
Normal file
Binary file not shown.
14
src/Makefile
14
src/Makefile
@@ -7,6 +7,7 @@ GHCFLAGS+= -fglasgow-exts -package util
|
|||||||
GHCOPTFLAGS=-O2
|
GHCOPTFLAGS=-O2
|
||||||
GHCFUDFLAG=
|
GHCFUDFLAG=
|
||||||
JAVAFLAGS=-target 1.4 -source 1.4
|
JAVAFLAGS=-target 1.4 -source 1.4
|
||||||
|
GFEDITOR=JavaGUI2
|
||||||
|
|
||||||
DIST_DIR=GF-$(PACKAGE_VERSION)
|
DIST_DIR=GF-$(PACKAGE_VERSION)
|
||||||
NOT_IN_DIST= \
|
NOT_IN_DIST= \
|
||||||
@@ -93,10 +94,12 @@ shell:
|
|||||||
clean:
|
clean:
|
||||||
find . '(' -name '*~' -o -name '*.hi' -o -name '*.ghi' -o -name '*.o' ')' -exec rm -f '{}' ';'
|
find . '(' -name '*~' -o -name '*.hi' -o -name '*.ghi' -o -name '*.o' ')' -exec rm -f '{}' ';'
|
||||||
-rm -f JavaGUI/*.class
|
-rm -f JavaGUI/*.class
|
||||||
|
-rm -f $(GFEDITOR)/de/uka/ilkd/key/ocl/gf/*.class
|
||||||
-rm -f gf.wixobj
|
-rm -f gf.wixobj
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
-rm -f JavaGUI/gf-java.jar jgf
|
-rm -f JavaGUI/gf-java.jar jgf
|
||||||
|
-rm -f $(GFEDITOR)/gfeditor.jar jgf
|
||||||
-rm -f tools/$(GF_DOC_EXE)
|
-rm -f tools/$(GF_DOC_EXE)
|
||||||
-rm -f config.status config.mk config.log
|
-rm -f config.status config.mk config.log
|
||||||
-rm -f *.tgz *.zip
|
-rm -f *.tgz *.zip
|
||||||
@@ -111,9 +114,12 @@ today:
|
|||||||
|
|
||||||
javac:
|
javac:
|
||||||
$(JAVAC) $(JAVAFLAGS) JavaGUI/*.java
|
$(JAVAC) $(JAVAFLAGS) JavaGUI/*.java
|
||||||
|
$(JAVAC) $(JAVAFLAGS) -classpath $(GFEDITOR):$(GFEDITOR)/log4j-1.2.8.jar:$(GFEDITOR)/jargs-1.0.jar $(GFEDITOR)/de/uka/ilkd/key/ocl/gf/*.java
|
||||||
|
|
||||||
|
|
||||||
jar: javac
|
jar: javac
|
||||||
cd JavaGUI; $(JAR) -cmf manifest.txt gf-java.jar *.class
|
cd JavaGUI; $(JAR) -cmf manifest.txt gf-java.jar *.class ; cd ..
|
||||||
|
cd $(GFEDITOR) ; rm -rf jarcontents ; mkdir jarcontents ; cp -r de/ ManifestMain.txt jarcontents ; cat jargs-1.0.jar | (cd jarcontents; jar -x jargs) ; cat log4j-1.2.8.jar | (cd jarcontents; jar -x org) ; cd jarcontents ; $(JAR) -cmf ManifestMain.txt ../gfeditor.jar de/uka/ilkd/key/ocl/gf/*.class org jargs ; cd .. ; rm -rf jarcontents ; cd ..
|
||||||
|
|
||||||
showflags:
|
showflags:
|
||||||
@echo $(GHCFLAGS)
|
@echo $(GHCFLAGS)
|
||||||
@@ -187,6 +193,7 @@ binary-dist:
|
|||||||
$(MAKE) all
|
$(MAKE) all
|
||||||
$(INSTALL) ../bin/$(GF_EXE) tools/$(GF_DOC_EXE) $(BIN_DIST_DIR)
|
$(INSTALL) ../bin/$(GF_EXE) tools/$(GF_DOC_EXE) $(BIN_DIST_DIR)
|
||||||
$(INSTALL) -m 0644 JavaGUI/gf-java.jar $(BIN_DIST_DIR)
|
$(INSTALL) -m 0644 JavaGUI/gf-java.jar $(BIN_DIST_DIR)
|
||||||
|
$(INSTALL) -m 0644 $(GFEDITOR)/gfeditor.jar $(BIN_DIST_DIR)
|
||||||
$(INSTALL) configure config.guess config.sub install-sh $(BIN_DIST_DIR)
|
$(INSTALL) configure config.guess config.sub install-sh $(BIN_DIST_DIR)
|
||||||
$(INSTALL) -m 0644 config.mk.in jgf.in $(BIN_DIST_DIR)
|
$(INSTALL) -m 0644 config.mk.in jgf.in $(BIN_DIST_DIR)
|
||||||
$(INSTALL) -m 0644 ../README ../LICENSE $(BIN_DIST_DIR)
|
$(INSTALL) -m 0644 ../README ../LICENSE $(BIN_DIST_DIR)
|
||||||
@@ -229,8 +236,13 @@ install-editor:
|
|||||||
$(INSTALL) -d $(datadir)/GF-$(PACKAGE_VERSION)
|
$(INSTALL) -d $(datadir)/GF-$(PACKAGE_VERSION)
|
||||||
$(INSTALL) jgf $(bindir)
|
$(INSTALL) jgf $(bindir)
|
||||||
$(INSTALL) -m 0644 JavaGUI/gf-java.jar $(datadir)/GF-$(PACKAGE_VERSION)
|
$(INSTALL) -m 0644 JavaGUI/gf-java.jar $(datadir)/GF-$(PACKAGE_VERSION)
|
||||||
|
$(INSTALL) gfeditor $(bindir)
|
||||||
|
$(INSTALL) -m 0644 $(GFEDITOR)/gfeditor.jar $(datadir)/GF-$(PACKAGE_VERSION)
|
||||||
|
|
||||||
install-java: javac
|
install-java: javac
|
||||||
-rm -f ../bin/JavaGUI
|
-rm -f ../bin/JavaGUI
|
||||||
ln -s ../src/JavaGUI ../bin
|
ln -s ../src/JavaGUI ../bin
|
||||||
@echo "PLEASE edit GFHOME in bin/jgf"
|
@echo "PLEASE edit GFHOME in bin/jgf"
|
||||||
|
-rm -f ../bin/$(GFEDITOR)
|
||||||
|
ln -s ../src/$(GFEDITOR) ../bin
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ install:
|
|||||||
$(INSTALL) gf$(EXEEXT) gfdoc$(EXEEXT) jgf $(bindir)
|
$(INSTALL) gf$(EXEEXT) gfdoc$(EXEEXT) jgf $(bindir)
|
||||||
$(INSTALL) -d $(GF_DATA_DIR)
|
$(INSTALL) -d $(GF_DATA_DIR)
|
||||||
$(INSTALL) -m 0644 gf-java.jar $(GF_DATA_DIR)
|
$(INSTALL) -m 0644 gf-java.jar $(GF_DATA_DIR)
|
||||||
|
$(INSTALL) -m 0644 gfeditor.jar $(GF_DATA_DIR)
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
-rm -f $(bindir)/gf$(EXEEXT) $(bindir)/gfdoc$(EXEEXT) $(bindir)/jgf
|
-rm -f $(bindir)/gf$(EXEEXT) $(bindir)/gfdoc$(EXEEXT) $(bindir)/jgf
|
||||||
-rm -f $(GF_DATA_DIR)/gf-java.jar
|
-rm -f $(GF_DATA_DIR)/gf-java.jar
|
||||||
|
-rm -f $(GF_DATA_DIR)/gfeditor.jar
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ AC_INIT([GF],[2.2],[aarne@cs.chalmers.se],[GF])
|
|||||||
|
|
||||||
AC_PREREQ(2.53)
|
AC_PREREQ(2.53)
|
||||||
|
|
||||||
AC_REVISION($Revision: 1.23 $)
|
AC_REVISION($Revision: 1.24 $)
|
||||||
|
|
||||||
AC_CONFIG_FILES([config.mk jgf])
|
AC_CONFIG_FILES([config.mk jgf gfeditor])
|
||||||
|
|
||||||
AC_CANONICAL_HOST
|
AC_CANONICAL_HOST
|
||||||
|
|
||||||
|
|||||||
39
src/gfeditor.in
Normal file
39
src/gfeditor.in
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
prefix=@prefix@
|
||||||
|
exec_prefix=@exec_prefix@
|
||||||
|
GF_BIN_DIR=@bindir@
|
||||||
|
GF_DATA_DIR=@datadir@/GF-@PACKAGE_VERSION@
|
||||||
|
|
||||||
|
JAVA="@JAVA@"
|
||||||
|
|
||||||
|
GF=$GF_BIN_DIR/gf
|
||||||
|
JARFILE=$GF_DATA_DIR/gfeditor.jar
|
||||||
|
|
||||||
|
if [ ! -x "${JAVA}" ]; then
|
||||||
|
JAVA=`which java`
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -x "${JAVA}" ]; then
|
||||||
|
echo "No Java VM found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "${JARFILE}" ]; then
|
||||||
|
echo "JAR file ${JARFILE} not found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -x "${GF}" ]; then
|
||||||
|
GF=`which gf`
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -x "${GF}" ]; then
|
||||||
|
echo "gf not found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
COMMAND= ${JAVA} -jar ${JARFILE} -g $GF $*
|
||||||
|
|
||||||
|
echo ${COMMAND}
|
||||||
|
exec ${COMMAND}
|
||||||
Reference in New Issue
Block a user