From 9debed66d1a96c255f478d52e4da89eaac47db04 Mon Sep 17 00:00:00 2001 From: khartlage Date: Sun, 8 Dec 2002 22:48:54 +0000 Subject: [PATCH] first version of 'Code Assist" template engine --- .../internal/corext/template/ContextType.java | 163 ++++++ .../corext/template/ContextTypeRegistry.java | 71 +++ .../corext/template/DocumentTemplateContext.java | 80 +++ .../internal/corext/template/ITemplateEditor.java | 23 + .../corext/template/SimpleTemplateVariable.java | 54 ++ .../phpdt/internal/corext/template/Template.java | 159 ++++++ .../internal/corext/template/TemplateBuffer.java | 63 +++ .../internal/corext/template/TemplateContext.java | 41 ++ .../internal/corext/template/TemplateMessages.java | 43 ++ .../corext/template/TemplateMessages.properties | 94 ++++ .../internal/corext/template/TemplatePosition.java | 96 ++++ .../internal/corext/template/TemplateSet.java | 310 +++++++++++ .../corext/template/TemplateTranslator.java | 216 ++++++++ .../internal/corext/template/TemplateVariable.java | 64 +++ .../phpdt/internal/corext/template/Templates.java | 94 ++++ .../internal/corext/template/default-templates.xml | 186 +++++++ .../template/java/CompilationUnitContext.java | 140 +++++ .../template/java/CompilationUnitContextType.java | 157 ++++++ .../corext/template/java/GlobalVariables.java | 80 +++ .../corext/template/java/JavaContextType.java | 119 +++++ .../corext/template/java/JavaDocContextType.java | 48 ++ .../corext/template/java/JavaTemplateMessages.java | 43 ++ .../template/java/JavaTemplateMessages.properties | 53 ++ .../corext/textmanipulation/Messages.properties | 17 + .../corext/textmanipulation/MoveTextEdit.java | 147 ++++++ .../corext/textmanipulation/MultiTextEdit.java | 136 +++++ .../corext/textmanipulation/NopTextEdit.java | 60 +++ .../corext/textmanipulation/SimpleTextEdit.java | 105 ++++ .../corext/textmanipulation/SwapTextEdit.java | 25 + .../corext/textmanipulation/TextBuffer.java | 418 +++++++++++++++ .../corext/textmanipulation/TextBufferEditor.java | 217 ++++++++ .../corext/textmanipulation/TextBufferFactory.java | 186 +++++++ .../internal/corext/textmanipulation/TextEdit.java | 100 ++++ .../corext/textmanipulation/TextEditNode.java | 493 ++++++++++++++++++ .../textmanipulation/TextEditNodeComparator.java | 48 ++ .../textmanipulation/TextManipulationMessages.java | 41 ++ .../corext/textmanipulation/TextRange.java | 195 +++++++ .../corext/textmanipulation/TextRegion.java | 37 ++ .../corext/textmanipulation/UndoMemento.java | 31 ++ .../phpdt/internal/corext/util/IOCloser.java | 41 ++ .../phpdt/internal/corext/util/Strings.java | 260 ++++++++++ .../phpdt/internal/ui/JavaStatusConstants.java | 28 + .../phpdt/internal/ui/JavaUIException.java | 21 + .../phpdt/internal/ui/JavaUIMessages.java | 36 ++ .../phpdt/internal/ui/JavaUIMessages.properties | 542 ++++++++++++++++++++ .../phpdt/internal/ui/JavaUIStatus.java | 28 + .../ui/text/java/IJavaCompletionProposal.java | 28 + .../JavaCompletionProcessor_NotInUseVersion.java | 378 ++++++++++++++ .../java/JavaCompletionProposalComparator.java | 35 ++ .../ui/text/template/TemplateContentProvider.java | 38 ++ .../internal/ui/text/template/TemplateEngine.java | 93 ++++ .../ui/text/template/TemplateLabelProvider.java | 67 +++ .../ui/text/template/TemplateProposal.java | 241 +++++++++ .../text/template/TemplateVariableProcessor.java | 129 +++++ .../ui/text/template/TemplateVariableProposal.java | 100 ++++ .../phpeditor/php/PHPCompletionProcessor.java | 215 +++++++-- 56 files changed, 6901 insertions(+), 32 deletions(-) create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/ContextType.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/ContextTypeRegistry.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/DocumentTemplateContext.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/ITemplateEditor.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/SimpleTemplateVariable.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/Template.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateBuffer.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateContext.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateMessages.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateMessages.properties create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplatePosition.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateSet.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateTranslator.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateVariable.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/Templates.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/default-templates.xml create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/CompilationUnitContext.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/CompilationUnitContextType.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/GlobalVariables.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/JavaContextType.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/JavaDocContextType.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/JavaTemplateMessages.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/JavaTemplateMessages.properties create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/Messages.properties create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/MoveTextEdit.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/MultiTextEdit.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/NopTextEdit.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/SimpleTextEdit.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/SwapTextEdit.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextBuffer.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextBufferEditor.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextBufferFactory.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextEdit.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextEditNode.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextEditNodeComparator.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextManipulationMessages.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextRange.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextRegion.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/UndoMemento.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/util/IOCloser.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/util/Strings.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaStatusConstants.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaUIException.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaUIMessages.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaUIMessages.properties create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaUIStatus.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/IJavaCompletionProposal.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaCompletionProcessor_NotInUseVersion.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaCompletionProposalComparator.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateContentProvider.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateEngine.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateLabelProvider.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateProposal.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateVariableProcessor.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateVariableProposal.java diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/ContextType.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/ContextType.java new file mode 100644 index 0000000..c6c96e3 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/ContextType.java @@ -0,0 +1,163 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.template; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Vector; + +import net.sourceforge.phpdt.internal.corext.textmanipulation.MultiTextEdit; +import net.sourceforge.phpdt.internal.corext.textmanipulation.NopTextEdit; +import net.sourceforge.phpdt.internal.corext.textmanipulation.SimpleTextEdit; +import net.sourceforge.phpdt.internal.corext.textmanipulation.TextBuffer; +import net.sourceforge.phpdt.internal.corext.textmanipulation.TextBufferEditor; +import net.sourceforge.phpdt.internal.corext.textmanipulation.TextEdit; +import org.eclipse.core.runtime.CoreException; + +/** + * A context type is a context factory. + */ +public abstract class ContextType implements ITemplateEditor { + + /** name of the context type */ + private final String fName; + + /** variables used by this content type */ + private final Map fVariables = new HashMap(); + + /** + * Creates a context type with a name. + * + * @param name the name of the context. It has to be unique wrt to other context names. + */ + public ContextType(String name) { + fName = name; + } + + /** + * Returns the name of the context type. + */ + public String getName() { + return fName; + } + + /** + * Adds a template variable to the context type. + */ + public void addVariable(TemplateVariable variable) { + fVariables.put(variable.getName(), variable); + } + + /** + * Removes a template variable from the context type. + */ + public void removeVariable(TemplateVariable variable) { + fVariables.remove(variable.getName()); + } + + /** + * Removes all template variables from the context type. + */ + public void removeAllVariables() { + fVariables.clear(); + } + + /** + * Returns an iterator for the variables known to the context type. + */ + public Iterator variableIterator() { + return fVariables.values().iterator(); + } + + /** + * Creates a template context. + */ + public abstract TemplateContext createContext(); + + /* + * @see ITemplateEditor#edit(TemplateBuffer) + */ + public void edit(TemplateBuffer templateBuffer, TemplateContext context) throws CoreException { + TextBuffer textBuffer = TextBuffer.create(templateBuffer.getString()); + TemplatePosition[] variables = templateBuffer.getVariables(); + + MultiTextEdit positions = variablesToPositions(variables); + MultiTextEdit multiEdit = new MultiTextEdit(); + + // iterate over all variables and try to resolve them + for (int i = 0; i != variables.length; i++) { + TemplatePosition variable = variables[i]; + + if (variable.isResolved()) + continue; + + String name = variable.getName(); + int[] offsets = variable.getOffsets(); + int length = variable.getLength(); + + TemplateVariable evaluator = (TemplateVariable) fVariables.get(name); + String value = (evaluator == null) ? null : evaluator.evaluate(context); + + if (value == null) + continue; + + variable.setLength(value.length()); + variable.setResolved(evaluator.isResolved(context)); + + for (int k = 0; k != offsets.length; k++) + multiEdit.add(SimpleTextEdit.createReplace(offsets[k], length, value)); + } + + TextBufferEditor editor = new TextBufferEditor(textBuffer); + editor.add(positions); + editor.add(multiEdit); + editor.performEdits(null); + + positionsToVariables(positions, variables); + + templateBuffer.setContent(textBuffer.getContent(), variables); + } + + private static MultiTextEdit variablesToPositions(TemplatePosition[] variables) { + MultiTextEdit positions = new MultiTextEdit(); + for (int i = 0; i != variables.length; i++) { + int[] offsets = variables[i].getOffsets(); + for (int j = 0; j != offsets.length; j++) + positions.add(new NopTextEdit(offsets[j], 0)); + } + + return positions; + } + + private static void positionsToVariables(MultiTextEdit positions, TemplatePosition[] variables) { + Iterator iterator = positions.iterator(); + + for (int i = 0; i != variables.length; i++) { + TemplatePosition variable = variables[i]; + + int[] offsets = new int[variable.getOffsets().length]; + for (int j = 0; j != offsets.length; j++) + offsets[j] = ((TextEdit) iterator.next()).getTextRange().getOffset(); + + variable.setOffsets(offsets); + } + } + + /** + * Returns the templates associated with this context type. + */ + public Template[] getTemplates() { + Template[] templates = Templates.getInstance().getTemplates(); + + Vector vector = new Vector(); + for (int i = 0; i != templates.length; i++) + if (templates[i].getContextTypeName().equals(fName)) + vector.add(templates[i]); + + return (Template[]) vector.toArray(new Template[vector.size()]); + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/ContextTypeRegistry.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/ContextTypeRegistry.java new file mode 100644 index 0000000..8247bdc --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/ContextTypeRegistry.java @@ -0,0 +1,71 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.template; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import net.sourceforge.phpdt.internal.corext.template.java.JavaContextType; +import net.sourceforge.phpdt.internal.corext.template.java.JavaDocContextType; + + + +/** + * A singleton to keep track of all known context types. + */ +public class ContextTypeRegistry { + + /** the singleton */ + private static ContextTypeRegistry fInstance; + + /** all known context types */ + private final Map fContextTypes= new HashMap(); + + /** + * Returns the single instance of this class. + */ + public static ContextTypeRegistry getInstance() { + if (fInstance == null) + fInstance= new ContextTypeRegistry(); + + return fInstance; + } + + /** + * Adds a context type to the registry. + */ + public void add(ContextType contextType) { + fContextTypes.put(contextType.getName(), contextType); + } + + /** + * Removes a context type from the registry. + */ + public void remove(ContextType contextType) { + fContextTypes.remove(contextType.getName()); + } + + /** + * Returns the context type if the name is valid, null otherwise. + */ + public ContextType getContextType(String name) { + return (ContextType) fContextTypes.get(name); + } + + /** + * Returns an iterator over the registered context type names. + */ + public Iterator iterator() { + return fContextTypes.keySet().iterator(); + } + + // XXX bootstrap with java and javadoc context types + private ContextTypeRegistry() { + add(new JavaContextType()); + add(new JavaDocContextType()); + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/DocumentTemplateContext.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/DocumentTemplateContext.java new file mode 100644 index 0000000..e89d632 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/DocumentTemplateContext.java @@ -0,0 +1,80 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.template; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; + +//import org.eclipse.jdt.internal.corext.Assert; + +/** + * A typical text based document template context. + */ +public abstract class DocumentTemplateContext extends TemplateContext { + + /** The text of the document. */ + private final IDocument fDocument; + /** The completion position. */ + private final int fCompletionPosition; + + /** + * Creates a document template context. + */ + protected DocumentTemplateContext(ContextType type, IDocument document, int completionPosition) { + super(type); + +// Assert.isNotNull(document); +// Assert.isTrue(completionPosition >= 0 && completionPosition <= document.getLength()); + + fDocument= document; + fCompletionPosition= completionPosition; + } + + public IDocument getDocument() { + return fDocument; + } + + /** + * Returns the string of the context. + */ +// public String getString() { +// return fDocument.get(); +// } + + /** + * Returns the completion position within the string of the context. + */ + public int getCompletionPosition() { + return fCompletionPosition; + } + + /** + * Returns the keyword which triggered template insertion. + */ + public String getKey() { + int offset= getStart(); + int length= getEnd() - offset; + try { + return fDocument.get(offset, length); + } catch (BadLocationException e) { + return ""; //$NON-NLS-1$ + } + } + + /** + * Returns the beginning offset of the keyword. + */ + public int getStart() { + return fCompletionPosition; + } + + /** + * Returns the end offset of the keyword. + */ + public int getEnd() { + return fCompletionPosition; + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/ITemplateEditor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/ITemplateEditor.java new file mode 100644 index 0000000..2698b77 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/ITemplateEditor.java @@ -0,0 +1,23 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.template; + +import org.eclipse.core.runtime.CoreException; + +/** + * A template editor implements an action to edit a template buffer in its context. + */ +public interface ITemplateEditor { + + /** + * Modifies a template buffer. + * + * @param buffer the template buffer + * @param context the template context + * @throws CoreException if the buffer cannot be successfully modified + */ + void edit(TemplateBuffer buffer, TemplateContext context) throws CoreException; + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/SimpleTemplateVariable.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/SimpleTemplateVariable.java new file mode 100644 index 0000000..62b4a7a --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/SimpleTemplateVariable.java @@ -0,0 +1,54 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.template; + +/** + * A simple template variable, which always evaluates to a defined string. + */ +public class SimpleTemplateVariable extends TemplateVariable { + + /** The string to which this variable evaluates. */ + private String fEvaluationString; + /** A flag indicating if this variable can be resolved. */ + private boolean fResolved; + + /* + * @see TemplateVariable#TemplateVariable(String, String) + */ + protected SimpleTemplateVariable(String name, String description) { + super(name, description); + } + + /** + * Sets the string to which this variable evaluates. + * + * @param evaluationString the evaluation string, may be null. + */ + public final void setEvaluationString(String evaluationString) { + fEvaluationString= evaluationString; + } + + /* + * @see TemplateVariable#evaluate(TemplateContext) + */ + public String evaluate(TemplateContext context) { + return fEvaluationString; + } + + /** + * Sets the resolved flag. + */ + public final void setResolved(boolean resolved) { + fResolved= resolved; + } + + /* + * @see TemplateVariable#isResolved(TemplateContext) + */ + public boolean isResolved(TemplateContext context) { + return fResolved; + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/Template.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/Template.java new file mode 100644 index 0000000..2ae617c --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/Template.java @@ -0,0 +1,159 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.template; + +/** + * A template consiting of a name and a pattern. + */ +public class Template { + + /** The name of this template */ + private String fName; + /** A description of this template */ + private String fDescription; + /** The name of the context type of this template */ + private String fContextTypeName; + /** The template pattern. */ + private String fPattern; + /** A flag indicating if the template is active or not. */ + private boolean fEnabled= true; + + /** + * Creates an empty template. + */ + public Template() { + this("", "", "", ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + + /** + * Creates a copy of a template. + */ + public Template(Template template) { + this(template.getName(), template.getDescription(), template.getContextTypeName(), template.getPattern()); + } + + /** + * Creates a template. + * + * @param name the name of the template. + * @param description the description of the template. + * @param contextTypeName the name of the context type in which the template can be applied. + * @param pattern the template pattern. + */ + public Template(String name, String description, String contextTypeName, String pattern) { + fName= name; + fDescription= description; + fContextTypeName= contextTypeName; + fPattern= pattern; + } + + /* + * @see Object#equals(Object) + */ + public boolean equals(Object object) { + if (!(object instanceof Template)) + return false; + + Template template= (Template) object; + + if (template == this) + return true; + + return + template.fName.equals(fName) && + template.fPattern.equals(fPattern) && + template.fContextTypeName.equals(fContextTypeName); + } + + /* + * @see Object#hashCode() + */ + public int hashCode() { + return fName.hashCode() ^ fPattern.hashCode() ^ fContextTypeName.hashCode(); + } + + /** + * Sets the description of the template. + */ + public void setDescription(String description) { + fDescription= description; + } + + /** + * Returns the description of the template. + */ + public String getDescription() { + return fDescription; + } + + /** + * Sets the name of the context type in which the template can be applied. + */ + public void setContext(String contextTypeName) { + fContextTypeName= contextTypeName; + } + + /** + * Returns the name of the context type in which the template can be applied. + */ + public String getContextTypeName() { + return fContextTypeName; + } + + /** + * Sets the name of the template. + */ + public void setName(String name) { + fName= name; + } + + /** + * Returns the name of the template. + */ + public String getName() { + return fName; + } + + /** + * Sets the pattern of the template. + */ + public void setPattern(String pattern) { + fPattern= pattern; + } + + /** + * Returns the template pattern. + */ + public String getPattern() { + return fPattern; + } + + /** + * Sets the enable state of the template. + */ + public void setEnabled(boolean enable) { + fEnabled= enable; + } + + /** + * Returns true if template is enabled, false otherwise. + */ + public boolean isEnabled() { + return fEnabled; + } + + /** + * Returns true if template matches the prefix and context, + * false otherwise. + */ + public boolean matches(String prefix, String contextTypeName) { + return + fEnabled && + fContextTypeName.equals(contextTypeName) && + (prefix.length() != 0) && + fName.toLowerCase().startsWith(prefix.toLowerCase()); + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateBuffer.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateBuffer.java new file mode 100644 index 0000000..9783027 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateBuffer.java @@ -0,0 +1,63 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.template; + +import org.eclipse.core.runtime.CoreException; + +//import org.eclipse.jdt.internal.corext.Assert; + +/** + * A template buffer is a container for a string and variables. + */ +public final class TemplateBuffer { + + /** The string of the template buffer */ + private String fString; + /** The variable positions of the template buffer */ + private TemplatePosition[] fVariables; + + /** + * Creates a template buffer. + * + * @param string the string + * @param variables the variable positions + * @throws CoreException for illegal variable positions + */ + public TemplateBuffer(String string, TemplatePosition[] variables) throws CoreException { + setContent(string, variables); + } + + /** + * Sets the content of the template buffer. + * + * @param string the string + * @param variables the variable positions + * @throws CoreException for illegal variable positions + */ + public final void setContent(String string, TemplatePosition[] variables) throws CoreException { + // Assert.isNotNull(string); + // Assert.isNotNull(variables); + + // XXX assert non-overlapping variable properties + + fString= string; + fVariables= variables; + } + + /** + * Returns the string of the template buffer. + */ + public final String getString() { + return fString; + } + + /** + * Returns the variable positions of the template buffer. + */ + public final TemplatePosition[] getVariables() { + return fVariables; + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateContext.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateContext.java new file mode 100644 index 0000000..b4ca23d --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateContext.java @@ -0,0 +1,41 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.template; + +import org.eclipse.core.runtime.CoreException; + +/** + * A template context. A template context is associated with a context type. + */ +public abstract class TemplateContext { + + /** context type of this context */ + private final ContextType fContextType; + + /** + * Creates a template context of a particular context type. + */ + protected TemplateContext(ContextType contextType) { + fContextType= contextType; + } + + /** + * Returns the context type of this context. + */ + public ContextType getContextType() { + return fContextType; + } + + /** + * Evaluates the template and returns a template buffer. + */ + public abstract TemplateBuffer evaluate(Template template) throws CoreException; + + /** + * Tests if the specified template can be evaluated in this context. + */ + public abstract boolean canEvaluate(Template template); + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateMessages.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateMessages.java new file mode 100644 index 0000000..9ed4fca --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateMessages.java @@ -0,0 +1,43 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.template; + +import java.text.MessageFormat; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class TemplateMessages { + + private static final String RESOURCE_BUNDLE= TemplateMessages.class.getName(); + private static ResourceBundle fgResourceBundle= ResourceBundle.getBundle(RESOURCE_BUNDLE); + + private TemplateMessages() { + } + + public static String getString(String key) { + try { + return fgResourceBundle.getString(key); + } catch (MissingResourceException e) { + return '!' + key + '!'; + } + } + + /** + * Gets a string from the resource bundle and formats it with the argument + * + * @param key the string used to get the bundle value, must not be null + */ + public static String getFormattedString(String key, Object arg) { + return MessageFormat.format(getString(key), new Object[] { arg }); + } + + + /** + * Gets a string from the resource bundle and formats it with arguments + */ + public static String getFormattedString(String key, Object[] args) { + return MessageFormat.format(getString(key), args); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateMessages.properties b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateMessages.properties new file mode 100644 index 0000000..3c085d0 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateMessages.properties @@ -0,0 +1,94 @@ +######################################### +# (c) Copyright IBM Corp. 2000, 2001. +# All Rights Reserved. +######################################### + +# preference page +TemplatePreferencePage.error.import=Failed to import templates. +TemplatePreferencePage.error.export=Failed to export templates. +TemplatePreferencePage.error.read.title=Reading Templates +TemplatePreferencePage.error.write.title=Reading Templates +TemplatePreferencePage.message=&Create, edit or remove templates: +TemplatePreferencePage.title=Templates + +TemplatePreferencePage.new=&New... +TemplatePreferencePage.edit=&Edit... +TemplatePreferencePage.import=&Import... +TemplatePreferencePage.export=E&xport... +TemplatePreferencePage.export.all=Ex&port All... +TemplatePreferencePage.remove=&Remove +TemplatePreferencePage.enable.all=Ena&ble All +TemplatePreferencePage.disable.all=Di&sable All +TemplatePreferencePage.editor=Template + +TemplatePreferencePage.column.name=Name +TemplatePreferencePage.column.context=Context +TemplatePreferencePage.column.description=Description + +TemplatePreferencePage.use.code.formatter=Use Code &Formatter + +TemplatePreferencePage.import.title=Importing Templates +TemplatePreferencePage.import.extension=*.xml + +TemplatePreferencePage.export.title=Exporting {0} Templates +TemplatePreferencePage.export.filename=templates.xml +TemplatePreferencePage.export.extension=*.xml + +TemplatePreferencePage.export.exists.title=Exporting Templates +TemplatePreferencePage.export.exists.message={0} already exists.\nDo you want to replace it? + +TemplatePreferencePage.question.create.new.title=Edit Template +TemplatePreferencePage.question.create.new.message=The name of the template was changed.\nDo you want to create a new template? + +TemplatePreferencePage.preview=Preview: + +# edit template dialog +EditTemplateDialog.error.noname=Template name must not be empty. +EditTemplateDialog.error.adjacent.variables=Template pattern has adjacent variables. +EditTemplateDialog.title.new=New Template +EditTemplateDialog.title.edit=Edit Template + +EditTemplateDialog.name=&Name: +EditTemplateDialog.description=&Description: +EditTemplateDialog.context=&Context: +EditTemplateDialog.pattern=&Pattern: +EditTemplateDialog.insert.variable=Insert &Variable... + +EditTemplateDialog.undo=&Undo@Ctrl+Z +EditTemplateDialog.cut=Cu&t@Ctrl+X +EditTemplateDialog.copy=&Copy@Ctrl+C +EditTemplateDialog.paste=&Paste@Ctrl+V +EditTemplateDialog.select.all=Select &All@Ctrl+A +EditTemplateDialog.content.assist=Insert &Variable...@Ctrl+Space + +# template variable dialog +TemplateVariableDialog.title=Select a template variable. +TemplateVariableDialog.column.name=Name +TemplateVariableDialog.column.description=Description +TemplateVariableDialog.insert=&Insert + +TemplateVariableProposal.error.title=Error applying template variable proposal +TemplateVariableProcessor.error.title=Error creating template variable proposals + +# template set +TemplateSet.error.read=Error occurred while reading templates. +TemplateSet.error.write=Error occurred while writing templates. + +# templates +Templates.error.title=Error accessing templates. +Templates.error.read=Error occurred while reading templates. +Templates.error.write=Error occurred while writing templates. + +# template engine +TemplateEngine.error.title=Could not create template proposals. + +# template proposal +TemplateProposal.delimiter=\ - + +# template evaluator +TemplateEvaluator.error.title=Template Evaluation Error + +# template translator +TemplateTranslator.error.incomplete.variable=Template has incomplete variables. +TemplateTranslator.error.invalid.identifier=Template has invalid variable identifiers. +TemplateSet.error.missing.attribute=Missing required attribute diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplatePosition.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplatePosition.java new file mode 100644 index 0000000..9acc561 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplatePosition.java @@ -0,0 +1,96 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.template; + +/** + * + */ +public class TemplatePosition { + + /** The name of the template position */ + private final String fName; + /** The default value of the template position */ + private final String fDefaultValue; + + /** The length of the template positions. */ + private int fLength; + /** The offsets of the template positions. */ + private int[] fOffsets; + /** A flag indicating if the template position has been resolved. */ + private boolean fResolved; + + /** + * Creates a template position. + * + * @param name the name of the template position. + * @param defaultValue the default value of the position. + * @param offsets the array of offsets of the position. + * @param the length of the position. + */ + public TemplatePosition(String name, String defaultValue, int[] offsets, int length) { + fName= name; + fDefaultValue= defaultValue; + fOffsets= offsets; + fLength= length; + fResolved= false; + } + + /** + * Returns the name of the position. + */ + public String getName() { + return fName; + } + + /** + * Returns the default value of the position. + */ + public String getDefaultValue() { + return fDefaultValue; + } + + /** + * Sets the length of the position. + */ + public void setLength(int length) { + fLength= length; + } + + /** + * Returns the length of the position. + */ + public int getLength() { + return fLength; + } + + /** + * Sets the offsets of the position. + */ + public void setOffsets(int[] offsets) { + fOffsets= offsets; + } + + /** + * Returns the offsets of the position. + */ + public int[] getOffsets() { + return fOffsets; + } + + /** + * Sets the resolved flag of the position. + */ + public void setResolved(boolean resolved) { + fResolved= resolved; + } + + /** + * Returns true if the position is resolved, false otherwise. + */ + public boolean isResolved() { + return fResolved; + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateSet.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateSet.java new file mode 100644 index 0000000..d7de172 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateSet.java @@ -0,0 +1,310 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.template; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import org.apache.xml.serialize.OutputFormat; +import org.apache.xml.serialize.Serializer; +import org.apache.xml.serialize.SerializerFactory; +import org.eclipse.core.runtime.CoreException; +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +//import org.eclipse.jdt.internal.ui.JavaUIStatus; +//import org.eclipse.jdt.internal.ui.JavaUIException; + +import net.sourceforge.phpeclipse.PHPeclipsePlugin; + +/** + * TemplateSet manages a collection of templates and makes them + * persistent. + */ +public class TemplateSet { + + private static class TemplateComparator implements Comparator { + public int compare(Object arg0, Object arg1) { + if (arg0 == arg1) + return 0; + + if (arg0 == null) + return -1; + + Template template0= (Template) arg0; + Template template1= (Template) arg1; + + return template0.getName().compareTo(template1.getName()); + } + } + + private static final String TEMPLATE_TAG= "template"; //$NON-NLS-1$ + private static final String NAME_ATTRIBUTE= "name"; //$NON-NLS-1$ + private static final String DESCRIPTION_ATTRIBUTE= "description"; //$NON-NLS-1$ + private static final String CONTEXT_ATTRIBUTE= "context"; //$NON-NLS-1$ + private static final String ENABLED_ATTRIBUTE= "enabled"; //$NON-NLS-1$ + + private List fTemplates= new ArrayList(); + private Comparator fTemplateComparator= new TemplateComparator(); + private Template[] fSortedTemplates= new Template[0]; + + /** + * Convenience method for reading templates from a file. + * + * @see #addFromStream(InputStream) + */ + public void addFromFile(File file) throws CoreException { + InputStream stream= null; + + try { + stream= new FileInputStream(file); + addFromStream(stream); + + } catch (IOException e) { + throwReadException(e); + + } finally { + try { + if (stream != null) + stream.close(); + } catch (IOException e) {} + } + } + + /** + * Reads templates from a XML stream and adds them to the template set. + */ + public void addFromStream(InputStream stream) throws CoreException { + try { + DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance(); + DocumentBuilder parser= factory.newDocumentBuilder(); + Document document= parser.parse(new InputSource(stream)); + NodeList elements= document.getElementsByTagName(TEMPLATE_TAG); + + int count= elements.getLength(); + for (int i= 0; i != count; i++) { + Node node= elements.item(i); + NamedNodeMap attributes= node.getAttributes(); + + if (attributes == null) + continue; + + String name= getAttributeValue(attributes, NAME_ATTRIBUTE); + String description= getAttributeValue(attributes, DESCRIPTION_ATTRIBUTE); + String context= getAttributeValue(attributes, CONTEXT_ATTRIBUTE); + Node enabledNode= attributes.getNamedItem(ENABLED_ATTRIBUTE); + + if (name == null || description == null || context == null) + throw new SAXException(TemplateMessages.getString("TemplateSet.error.missing.attribute")); //$NON-NLS-1$ + + boolean enabled= (enabledNode == null) || (enabledNode.getNodeValue().equals("true")); //$NON-NLS-1$ + + StringBuffer buffer= new StringBuffer(); + NodeList children= node.getChildNodes(); + for (int j= 0; j != children.getLength(); j++) { + String value= children.item(j).getNodeValue(); + if (value != null) + buffer.append(value); + } + String pattern= buffer.toString().trim(); + + Template template= new Template(name, description, context, pattern); + template.setEnabled(enabled); + add(template); + } + + sort(); + + } catch (ParserConfigurationException e) { + throwReadException(e); + } catch (IOException e) { + throwReadException(e); + } catch (SAXException e) { + throwReadException(e); + } + } + + private String getAttributeValue(NamedNodeMap attributes, String name) { + Node node= attributes.getNamedItem(name); + + return node == null + ? null + : node.getNodeValue(); + } + + /** + * Convenience method for saving to a file. + * + * @see #saveToStream(OutputStream) + */ + public void saveToFile(File file) throws CoreException { + OutputStream stream= null; + + try { + stream= new FileOutputStream(file); + saveToStream(stream); + + } catch (IOException e) { + throwWriteException(e); + + } finally { + try { + if (stream != null) + stream.close(); + } catch (IOException e) {} + } + } + + /** + * Saves the template set as XML. + */ + public void saveToStream(OutputStream stream) throws CoreException { + try { + DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance(); + DocumentBuilder builder= factory.newDocumentBuilder(); + Document document= builder.newDocument(); + + Node root= document.createElement("templates"); // $NON-NLS-1$ //$NON-NLS-1$ + document.appendChild(root); + + for (int i= 0; i != fTemplates.size(); i++) { + Template template= (Template) fTemplates.get(i); + + Node node= document.createElement("template"); // $NON-NLS-1$ //$NON-NLS-1$ + root.appendChild(node); + + NamedNodeMap attributes= node.getAttributes(); + + Attr name= document.createAttribute(NAME_ATTRIBUTE); + name.setValue(template.getName()); + attributes.setNamedItem(name); + + Attr description= document.createAttribute(DESCRIPTION_ATTRIBUTE); + description.setValue(template.getDescription()); + attributes.setNamedItem(description); + + Attr context= document.createAttribute(CONTEXT_ATTRIBUTE); + context.setValue(template.getContextTypeName()); + attributes.setNamedItem(context); + + Attr enabled= document.createAttribute(ENABLED_ATTRIBUTE); + enabled.setValue(template.isEnabled() ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$ + attributes.setNamedItem(enabled); + + Text pattern= document.createTextNode(template.getPattern()); + node.appendChild(pattern); + } + + OutputFormat format = new OutputFormat(); + format.setPreserveSpace(true); + Serializer serializer = SerializerFactory.getSerializerFactory("xml").makeSerializer(stream, format); //$NON-NLS-1$ + serializer.asDOMSerializer().serialize(document); + + } catch (ParserConfigurationException e) { + throwWriteException(e); + } catch (IOException e) { + throwWriteException(e); + } + } + + private static void throwReadException(Throwable t) throws CoreException { + PHPeclipsePlugin.log(t); +// IStatus status= new JavaUIStatus(JavaStatusConstants.TEMPLATE_IO_EXCEPTION, +// TemplateMessages.getString("TemplateSet.error.read"), t); //$NON-NLS-1$ +// throw new JavaUIException(status); + } + + private static void throwWriteException(Throwable t) throws CoreException { + PHPeclipsePlugin.log(t); +// IStatus status= new JavaUIStatus(JavaStatusConstants.TEMPLATE_IO_EXCEPTION, +// TemplateMessages.getString("TemplateSet.error.write"), t); //$NON-NLS-1$ +// throw new JavaUIException(status); + } + + /** + * Adds a template to the set. + */ + public void add(Template template) { + if (exists(template)) + return; // ignore duplicate + + fTemplates.add(template); + sort(); + } + + private boolean exists(Template template) { + for (Iterator iterator = fTemplates.iterator(); iterator.hasNext();) { + Template anotherTemplate = (Template) iterator.next(); + + if (template.equals(anotherTemplate)) + return true; + } + + return false; + } + + /** + * Removes a template to the set. + */ + public void remove(Template template) { + fTemplates.remove(template); + sort(); + } + + /** + * Empties the set. + */ + public void clear() { + fTemplates.clear(); + sort(); + } + + /** + * Returns all templates. + */ + public Template[] getTemplates() { + return (Template[]) fTemplates.toArray(new Template[fTemplates.size()]); + } + + /** + * Returns all templates with a given name. + */ + public Template[] getTemplates(String name) { + ArrayList res= new ArrayList(); + for (Iterator iterator= fTemplates.iterator(); iterator.hasNext();) { + Template curr= (Template) iterator.next(); + if (curr.getName().equals(name)) { + res.add(curr); + } + } + return (Template[]) res.toArray(new Template[res.size()]); + } + + private void sort() { + fSortedTemplates= (Template[]) fTemplates.toArray(new Template[fTemplates.size()]); + Arrays.sort(fSortedTemplates, fTemplateComparator); + } + +} + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateTranslator.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateTranslator.java new file mode 100644 index 0000000..f2190f0 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateTranslator.java @@ -0,0 +1,216 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.template; + +import java.io.Reader; +import java.io.StringReader; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.Vector; + +import org.eclipse.core.runtime.CoreException; + +/** + * The template translator translates a string into a template buffer. + * The EBNF grammer of a valid string is as follows: + * + *

+ * template := (text | escape)*.
+ * text := character - dollar.
+ * escape := dollar ('{' identifier '}' | dollar).
+ * dollar := '$'.
+ *

+ */ +public class TemplateTranslator { + + // states + private static final int TEXT= 0; + private static final int ESCAPE= 1; + private static final int IDENTIFIER= 2; + + // tokens + private static final char ESCAPE_CHARACTER= '$'; + private static final char IDENTIFIER_BEGIN= '{'; + private static final char IDENTIFIER_END= '}'; + + /** a buffer for the translation result string */ + private final StringBuffer fBuffer= new StringBuffer(); + /** position offsets of variables */ + private final Vector fOffsets= new Vector(); + /** position lengths of variables */ + private final Vector fLengths= new Vector(); + + /** the current parsing state */ + private int fState; + /** the last translation error */ + private String fErrorMessage; + + /** + * Returns an error message if an error occured for the last translation, null + * otherwise. + */ + public String getErrorMessage() { + return fErrorMessage; + } + + /** + * Translates a template string to TemplateBuffer. null + * is returned if there was an error. getErrorMessage() retrieves the + * associated error message. + * + * @param string the string to translate. + * @return returns the template buffer corresponding to the string, null + * if there was an error. + * @see #getErrorMessage() + */ + public TemplateBuffer translate(String string) throws CoreException { + + fBuffer.setLength(0); + fOffsets.clear(); + fLengths.clear(); + fState= TEXT; + fErrorMessage= null; + + if (!parse(string)) + return null; + + switch (fState) { + case TEXT: + break; + + // illegal, but be tolerant + case ESCAPE: + fErrorMessage= TemplateMessages.getString("TemplateTranslator.error.incomplete.variable"); //$NON-NLS-1$ + fBuffer.append(ESCAPE_CHARACTER); + return null; + + // illegal, but be tolerant + case IDENTIFIER: + fErrorMessage= TemplateMessages.getString("TemplateTranslator.error.incomplete.variable"); //$NON-NLS-1$ + fBuffer.append(ESCAPE_CHARACTER); + return null; + } + + int[] offsets= new int[fOffsets.size()]; + int[] lengths= new int[fLengths.size()]; + + for (int i= 0; i < fOffsets.size(); i++) { + offsets[i]= ((Integer) fOffsets.get(i)).intValue(); + lengths[i]= ((Integer) fLengths.get(i)).intValue(); + } + + String translatedString= fBuffer.toString(); + TemplatePosition[] variables= findVariables(translatedString, offsets, lengths); + + return new TemplateBuffer(translatedString, variables); + } + + private static TemplatePosition[] findVariables(String string, int[] offsets, int[] lengths) { + + Map map= new HashMap(); + + for (int i= 0; i != offsets.length; i++) { + int offset= offsets[i]; + int length= lengths[i]; + + String content= string.substring(offset, offset + length); + Vector vector= (Vector) map.get(content); + if (vector == null) { + vector= new Vector(); + map.put(content, vector); + } + vector.add(new Integer(offset)); + } + + TemplatePosition[] variables= new TemplatePosition[map.size()]; + int k= 0; + + Set keys= map.keySet(); + for (Iterator i= keys.iterator(); i.hasNext(); ) { + String name= (String) i.next(); + Vector vector= (Vector) map.get(name); + + int[] offsets_= new int[vector.size()]; + for (int j= 0; j != offsets_.length; j++) + offsets_[j]= ((Integer) vector.get(j)).intValue(); + + variables[k]= new TemplatePosition(name, name, offsets_, name.length()); + k++; + } + + return variables; + } + + /** internal parser */ + private boolean parse(String string) { + + for (int i= 0; i != string.length(); i++) { + char ch= string.charAt(i); + + switch (fState) { + case TEXT: + switch (ch) { + case ESCAPE_CHARACTER: + fState= ESCAPE; + break; + + default: + fBuffer.append(ch); + break; + } + break; + + case ESCAPE: + switch (ch) { + case ESCAPE_CHARACTER: + fBuffer.append(ch); + fState= TEXT; + break; + + case IDENTIFIER_BEGIN: + fOffsets.add(new Integer(fBuffer.length())); + fState= IDENTIFIER; + break; + + default: + // illegal single escape character, but be tolerant + fErrorMessage= TemplateMessages.getString("TemplateTranslator.error.incomplete.variable"); //$NON-NLS-1$ + fBuffer.append(ESCAPE_CHARACTER); + fBuffer.append(ch); + fState= TEXT; + return false; + } + break; + + case IDENTIFIER: + switch (ch) { + case IDENTIFIER_END: + int offset = ((Integer) fOffsets.get(fOffsets.size() - 1)).intValue(); + fLengths.add(new Integer(fBuffer.length() - offset)); + fState= TEXT; + break; + + default: + if (!Character.isUnicodeIdentifierStart((char) ch) && + !Character.isUnicodeIdentifierPart((char) ch)) + { + // illegal identifier character + fErrorMessage= TemplateMessages.getString("TemplateTranslator.error.invalid.identifier"); //$NON-NLS-1$ + return false; + } + + fBuffer.append(ch); + break; + } + break; + } + } + + return true; + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateVariable.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateVariable.java new file mode 100644 index 0000000..7d3c055 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateVariable.java @@ -0,0 +1,64 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.template; + +/** + * A template variable. + */ +public abstract class TemplateVariable { + + /** name of the variable */ + private final String fName; + + /** description of the variable */ + private final String fDescription; + + /** + * Creates an instance of TemplateVariable. + * + * @param name the name of the variable + * @param description the description for the variable + */ + protected TemplateVariable(String name, String description) { + fName= name; + fDescription= description; + } + + /** + * Returns the name of the variable. + */ + public String getName() { + return fName; + } + + /** + * Returns the description for the variable. + */ + public String getDescription() { + return fDescription; + } + + /** + * Tests if this variable can be evaluated. + */ +// public abstract boolean canEvaluate(TemplateContext context); + + /** + * Evaluates this variable + * + * @return the evaluated string, or null if not evaluatable. + */ + public abstract String evaluate(TemplateContext context); + + /** + * Returns whether this variable is resolved. + * By default, the variable is not resolved. + * Clients can overwrite this method to force resolution of the variable. + */ + public boolean isResolved(TemplateContext context) { + return false; + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/Templates.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/Templates.java new file mode 100644 index 0000000..71c4c9d --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/Templates.java @@ -0,0 +1,94 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.template; + +import java.io.File; +import java.io.InputStream; + +import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.jface.dialogs.ErrorDialog; + +/** + * Templates gives access to the available templates. + */ +public class Templates extends TemplateSet { + + private static final String DEFAULT_FILE= "default-templates.xml"; //$NON-NLS-1$ + private static final String TEMPLATE_FILE= "templates.xml"; //$NON-NLS-1$ + + /** Singleton. */ + private static Templates fgTemplates; + + /** + * Returns an instance of templates. + */ + public static Templates getInstance() { + if (fgTemplates == null) + fgTemplates= create(); + + return fgTemplates; + } + + private static Templates create() { + Templates templates= new Templates(); + + try { + File templateFile= getTemplateFile(); + if (templateFile.exists()) { + templates.addFromFile(templateFile); + } else { + templates.addFromStream(getDefaultsAsStream()); + templates.saveToFile(templateFile); + } + + } catch (CoreException e) { + PHPeclipsePlugin.log(e); + ErrorDialog.openError(null, + TemplateMessages.getString("Templates.error.title"), //$NON-NLS-1$ + e.getMessage(), e.getStatus()); + + templates.clear(); + } + + return templates; + } + + /** + * Resets the template set. + */ + public void reset() throws CoreException { + clear(); + addFromFile(getTemplateFile()); + } + + /** + * Resets the template set with the default templates. + */ + public void restoreDefaults() throws CoreException { + clear(); + addFromStream(getDefaultsAsStream()); + } + + /** + * Saves the template set. + */ + public void save() throws CoreException { + saveToFile(getTemplateFile()); + } + + private static InputStream getDefaultsAsStream() { + return Templates.class.getResourceAsStream(DEFAULT_FILE); + } + + private static File getTemplateFile() { + IPath path= PHPeclipsePlugin.getDefault().getStateLocation(); + path= path.append(TEMPLATE_FILE); + + return path.toFile(); + } +} + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/default-templates.xml b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/default-templates.xml new file mode 100644 index 0000000..cd33d19 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/default-templates.xml @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/CompilationUnitContext.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/CompilationUnitContext.java new file mode 100644 index 0000000..dcc8f00 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/CompilationUnitContext.java @@ -0,0 +1,140 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.template.java; + +import net.sourceforge.phpdt.internal.corext.template.ContextType; +import net.sourceforge.phpdt.internal.corext.template.DocumentTemplateContext; +import net.sourceforge.phpdt.internal.corext.template.Template; +import net.sourceforge.phpdt.internal.corext.template.TemplateBuffer; +import net.sourceforge.phpdt.internal.corext.template.TemplateTranslator; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; + +/** + * A compilation unit context. + */ +public class CompilationUnitContext extends DocumentTemplateContext { + + /** The platform default line delimiter. */ + private static final String PLATFORM_LINE_DELIMITER= System.getProperty("line.separator"); //$NON-NLS-1$ + + /** The compilation unit, may be null. */ +// private final ICompilationUnit fCompilationUnit; + + /** + * Creates a compilation unit context. + * + * @param type the context type. + * @param document the document. + * @param completionPosition the completion position within the document. + * @param compilationUnit the compilation unit (may be null). + */ + protected CompilationUnitContext(ContextType type, IDocument document, int completionPosition) + //,ICompilationUnit compilationUnit) + { + super(type, document, completionPosition); + // fCompilationUnit= compilationUnit; + } + + /* + * @see TemplateContext#canEvaluate(Template templates) + */ + public boolean canEvaluate(Template template) { + // return fForceEvaluation || + return template.matches(getKey(), getContextType().getName()); + } + + /* + * @see TemplateContext#evaluate(Template template) + */ + public TemplateBuffer evaluate(Template template) throws CoreException { + if (!canEvaluate(template)) + return null; + + TemplateTranslator translator= new TemplateTranslator(); + TemplateBuffer buffer= translator.translate(template.getPattern()); + + getContextType().edit(buffer, this); + + String lineDelimiter= null; + try { + lineDelimiter= getDocument().getLineDelimiter(0); + } catch (BadLocationException e) { + } + + if (lineDelimiter == null) + lineDelimiter= PLATFORM_LINE_DELIMITER; + +// ITemplateEditor formatter= new JavaFormatter(lineDelimiter); +// formatter.edit(buffer, this); + + return buffer; + } + + /* + * @see DocumentTemplateContext#getCompletionPosition(); + */ + public int getStart() { + IDocument document= getDocument(); + try { + int start= getCompletionPosition(); + + while ((start != 0) && Character.isUnicodeIdentifierPart(document.getChar(start - 1))) + start--; + + if ((start != 0) && Character.isUnicodeIdentifierStart(document.getChar(start - 1))) + start--; + + return start; + + } catch (BadLocationException e) { + return getCompletionPosition(); + } + } + + /** + * Returns the character before start position of completion. + */ + public char getCharacterBeforeStart() { + int start= getStart(); + + try { + return start == 0 + ? ' ' + : getDocument().getChar(start - 1); + + } catch (BadLocationException e) { + return ' '; + } + } + /** + * Returns the compilation unit if one is associated with this context, null otherwise. + */ +// public final ICompilationUnit getCompilationUnit() { +// return fCompilationUnit; +// } + + /** + * Returns the enclosing element of a particular element type, null + * if no enclosing element of that type exists. + */ +// public IJavaElement findEnclosingElement(int elementType) { +// if (fCompilationUnit == null) +// return null; +// +// try { +// IJavaElement element= fCompilationUnit.getElementAt(getStart()); +// while (element != null && element.getElementType() != elementType) +// element= element.getParent(); +// +// return element; +// +// } catch (JavaModelException e) { +// return null; +// } +// } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/CompilationUnitContextType.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/CompilationUnitContextType.java new file mode 100644 index 0000000..f0760e3 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/CompilationUnitContextType.java @@ -0,0 +1,157 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.template.java; + +import org.eclipse.jface.text.IDocument; +/* +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.Signature; +*/ +import net.sourceforge.phpdt.internal.corext.template.ContextType; +import net.sourceforge.phpdt.internal.corext.template.TemplateContext; +import net.sourceforge.phpdt.internal.corext.template.TemplateVariable; + +/** + * Compilation unit context type. + */ +public abstract class CompilationUnitContextType extends ContextType { + + /** the document */ + protected IDocument fDocument; + + /** the completion position within the document string */ + protected int fPosition; + + /** the associated compilation unit, may be null */ + //protected ICompilationUnit fCompilationUnit; +/* + protected static class ReturnType extends TemplateVariable { + public ReturnType() { + super(JavaTemplateMessages.getString("CompilationUnitContextType.variable.name.return.type"), JavaTemplateMessages.getString("CompilationUnitContextType.variable.description.return.type")); //$NON-NLS-1$ //$NON-NLS-2$ + } + + public String evaluate(TemplateContext context) { + IJavaElement element= ((CompilationUnitContext) context).findEnclosingElement(IJavaElement.METHOD); + if (element == null) + return null; + + try { + return Signature.toString(((IMethod) element).getReturnType()); + } catch (JavaModelException e) { + return null; + } + } + + public boolean isResolved(TemplateContext context) { + return evaluate(context) != null; + } + } + + protected static class File extends TemplateVariable { + public File() { + super(JavaTemplateMessages.getString("CompilationUnitContextType.variable.name.file"), JavaTemplateMessages.getString("CompilationUnitContextType.variable.description.file")); //$NON-NLS-1$ //$NON-NLS-2$ + } + public String evaluate(TemplateContext context) { + ICompilationUnit unit= ((CompilationUnitContext) context).getCompilationUnit(); + + return (unit == null) ? null : unit.getElementName(); + return null; + } + public boolean isResolved(TemplateContext context) { + return evaluate(context) != null; + } + } + + protected static class EnclosingJavaElement extends TemplateVariable { + protected final int fElementType; + + public EnclosingJavaElement(String name, String description, int elementType) { + super(name, description); + fElementType= elementType; + } + public String evaluate(TemplateContext context) { + IJavaElement element= ((CompilationUnitContext) context).findEnclosingElement(fElementType); + return (element == null) ? null : element.getElementName(); + } + public boolean isResolved(TemplateContext context) { + return evaluate(context) != null; + } + } + + protected static class Method extends EnclosingJavaElement { + public Method() { + super(JavaTemplateMessages.getString("CompilationUnitContextType.variable.name.enclosing.method"), JavaTemplateMessages.getString("CompilationUnitContextType.variable.description.enclosing.method"), IJavaElement.METHOD); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + protected static class Type extends EnclosingJavaElement { + public Type() { + super(JavaTemplateMessages.getString("CompilationUnitContextType.variable.name.enclosing.type"), JavaTemplateMessages.getString("CompilationUnitContextType.variable.description.enclosing.type"), IJavaElement.TYPE); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + protected static class Package extends EnclosingJavaElement { + public Package() { + super(JavaTemplateMessages.getString("CompilationUnitContextType.variable.name.enclosing.package"), JavaTemplateMessages.getString("CompilationUnitContextType.variable.description.enclosing.package"), IJavaElement.PACKAGE_FRAGMENT); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + protected static class Project extends EnclosingJavaElement { + public Project() { + super(JavaTemplateMessages.getString("CompilationUnitContextType.variable.name.enclosing.project"), JavaTemplateMessages.getString("CompilationUnitContextType.variable.description.enclosing.project"), IJavaElement.JAVA_PROJECT); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + + protected static class Arguments extends TemplateVariable { + public Arguments() { + super(JavaTemplateMessages.getString("CompilationUnitContextType.variable.name.enclosing.method.arguments"), JavaTemplateMessages.getString("CompilationUnitContextType.variable.description.enclosing.method.arguments")); //$NON-NLS-1$ //$NON-NLS-2$ + } + public String evaluate(TemplateContext context) { + IJavaElement element= ((CompilationUnitContext) context).findEnclosingElement(IJavaElement.METHOD); + if (element == null) + return null; + + IMethod method= (IMethod) element; + + try { + String[] arguments= method.getParameterNames(); + StringBuffer buffer= new StringBuffer(); + + for (int i= 0; i < arguments.length; i++) { + if (i > 0) + buffer.append(", "); //$NON-NLS-1$ + buffer.append(arguments[i]); + } + + return buffer.toString(); + + } catch (JavaModelException e) { + return null; + } + } + } +*/ + + /* + * @see ContextType#ContextType(String) + */ + public CompilationUnitContextType(String name) { + super(name); + } + + /** + * Sets context parameters. Needs to be called before createContext(). + */ + public void setContextParameters(IDocument document, int position) {//, ICompilationUnit compilationUnit) { + fDocument= document; + fPosition= position; +// fCompilationUnit= compilationUnit; + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/GlobalVariables.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/GlobalVariables.java new file mode 100644 index 0000000..2b37134 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/GlobalVariables.java @@ -0,0 +1,80 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.template.java; + +import java.text.DateFormat; +import java.util.Date; + +import net.sourceforge.phpdt.internal.corext.template.SimpleTemplateVariable; +import net.sourceforge.phpdt.internal.corext.template.TemplateContext; + +import net.sourceforge.phpdt.internal.corext.template.TemplateVariable; + +/** + * Global variables which are available in any context. + */ +public class GlobalVariables { + + /** + * The cursor variable determines the cursor placement after template edition. + */ + static class Cursor extends SimpleTemplateVariable { + public Cursor() { + super(JavaTemplateMessages.getString("GlobalVariables.variable.name.cursor"), JavaTemplateMessages.getString("GlobalVariables.variable.description.cursor")); //$NON-NLS-1$ //$NON-NLS-2$ + setEvaluationString(""); //$NON-NLS-1$ + setResolved(true); + } + } + + /** + * The dollar variable inserts an escaped dollar symbol. + */ + static class Dollar extends SimpleTemplateVariable { + public Dollar() { + super(JavaTemplateMessages.getString("GlobalVariables.variable.name.dollar"), JavaTemplateMessages.getString("GlobalVariables.variable.description.dollar")); //$NON-NLS-1$ //$NON-NLS-2$ + setEvaluationString("$"); //$NON-NLS-1$ + setResolved(true); + } + } + + /** + * The date variable evaluates to the current date. + */ + static class Date extends SimpleTemplateVariable { + public Date() { + super(JavaTemplateMessages.getString("GlobalVariables.variable.name.date"), JavaTemplateMessages.getString("GlobalVariables.variable.description.date")); //$NON-NLS-1$ //$NON-NLS-2$ + setResolved(true); + } + public String evaluate(TemplateContext context) { + return DateFormat.getDateInstance().format(new java.util.Date()); + } + } + + /** + * The time variable evaluates to the current time. + */ + static class Time extends SimpleTemplateVariable { + public Time() { + super(JavaTemplateMessages.getString("GlobalVariables.variable.name.time"), JavaTemplateMessages.getString("GlobalVariables.variable.description.time")); //$NON-NLS-1$ //$NON-NLS-2$ + setResolved(true); + } + public String evaluate(TemplateContext context) { + return DateFormat.getTimeInstance().format(new java.util.Date()); + } + } + + /** + * The user variable evaluates to the current user. + */ + static class User extends SimpleTemplateVariable { + public User() { + super(JavaTemplateMessages.getString("GlobalVariables.variable.name.user"), JavaTemplateMessages.getString("GlobalVariables.variable.description.user")); //$NON-NLS-1$ //$NON-NLS-2$ + setResolved(true); + } + public String evaluate(TemplateContext context) { + return System.getProperty("user.name"); //$NON-NLS-1$ + } + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/JavaContextType.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/JavaContextType.java new file mode 100644 index 0000000..7c048fa --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/JavaContextType.java @@ -0,0 +1,119 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.template.java; + +import java.util.Collection; +/* +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.Signature; +*/ +import net.sourceforge.phpdt.internal.corext.template.ContextType; +import net.sourceforge.phpdt.internal.corext.template.TemplateContext; +import net.sourceforge.phpdt.internal.corext.template.TemplateVariable; + +/** + * A context type for java code. + */ +public class JavaContextType extends CompilationUnitContextType { +/* + protected static class Array extends TemplateVariable { + public Array() { + super(JavaTemplateMessages.getString("JavaContextType.variable.name.array"), JavaTemplateMessages.getString("JavaContextType.variable.description.array")); //$NON-NLS-1$ //$NON-NLS-2$ + } + public String evaluate(TemplateContext context) { + return ((JavaContext) context).guessArray(); + } + } + + protected static class ArrayType extends TemplateVariable { + public ArrayType() { + super(JavaTemplateMessages.getString("JavaContextType.variable.name.array.type"), JavaTemplateMessages.getString("JavaContextType.variable.description.array.type")); //$NON-NLS-1$ //$NON-NLS-2$ + } + public String evaluate(TemplateContext context) { + return ((JavaContext) context).guessArrayType(); + } + } + + protected static class ArrayElement extends TemplateVariable { + public ArrayElement() { + super(JavaTemplateMessages.getString("JavaContextType.variable.name.array.element"), JavaTemplateMessages.getString("JavaContextType.variable.description.array.element")); //$NON-NLS-1$ //$NON-NLS-2$ + } + public String evaluate(TemplateContext context) { + return ((JavaContext) context).guessArrayElement(); + } + } + + protected static class Index extends TemplateVariable { + public Index() { + super(JavaTemplateMessages.getString("JavaContextType.variable.name.index"), JavaTemplateMessages.getString("JavaContextType.variable.description.index")); //$NON-NLS-1$ //$NON-NLS-2$ + } + public String evaluate(TemplateContext context) { + return ((JavaContext) context).getIndex(); + } + } + + protected static class Collection extends TemplateVariable { + public Collection() { + super(JavaTemplateMessages.getString("JavaContextType.variable.name.collection"), JavaTemplateMessages.getString("JavaContextType.variable.description.collection")); //$NON-NLS-1$ //$NON-NLS-2$ + } + public String evaluate(TemplateContext context) { + return ((JavaContext) context).guessCollection(); + } + } + + protected static class Iterator extends TemplateVariable { + public Iterator() { + super(JavaTemplateMessages.getString("JavaContextType.variable.name.iterator"), JavaTemplateMessages.getString("JavaContextType.variable.description.iterator")); //$NON-NLS-1$ //$NON-NLS-2$ + } + public String evaluate(TemplateContext context) { + return ((JavaContext) context).getIterator(); + } + } + +*/ + + + /** + * Creates a java context type. + */ + public JavaContextType() { + super("php"); //$NON-NLS-1$ + + // global + addVariable(new GlobalVariables.Cursor()); + addVariable(new GlobalVariables.Dollar()); + addVariable(new GlobalVariables.Date()); + addVariable(new GlobalVariables.Time()); + addVariable(new GlobalVariables.User()); + + // compilation unit + /* addVariable(new File()); + addVariable(new ReturnType()); + addVariable(new Method()); + addVariable(new Type()); + addVariable(new Package()); + addVariable(new Project()); + addVariable(new Arguments()); + + // java + addVariable(new Array()); + addVariable(new ArrayType()); + addVariable(new ArrayElement()); + addVariable(new Index()); + addVariable(new Iterator()); + addVariable(new Collection());*/ + } + + /* + * @see ContextType#createContext() + */ + public TemplateContext createContext() { + return new CompilationUnitContext(this, fDocument, fPosition); //, fCompilationUnit); + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/JavaDocContextType.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/JavaDocContextType.java new file mode 100644 index 0000000..79c3457 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/JavaDocContextType.java @@ -0,0 +1,48 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.template.java; + +//import org.eclipse.jdt.core.ICompilationUnit; + +import net.sourceforge.phpdt.internal.corext.template.ContextType; +import net.sourceforge.phpdt.internal.corext.template.TemplateContext; +import net.sourceforge.phpdt.internal.corext.template.TemplateVariable; + +/** + * A context type for javadoc. + */ +public class JavaDocContextType extends CompilationUnitContextType { + + /** + * Creates a java context type. + */ + public JavaDocContextType() { + super("html"); //$NON-NLS-1$ + + // global + addVariable(new GlobalVariables.Cursor()); + addVariable(new GlobalVariables.Dollar()); + addVariable(new GlobalVariables.Date()); + addVariable(new GlobalVariables.Time()); + addVariable(new GlobalVariables.User()); + + // compilation unit + /* addVariable(new File()); + addVariable(new Method()); + addVariable(new ReturnType()); + addVariable(new Arguments()); + addVariable(new Type()); + addVariable(new Package()); + addVariable(new Project());*/ + } + + /* + * @see ContextType#createContext() + */ + public TemplateContext createContext() { + return new CompilationUnitContext(this, fDocument, fPosition); //, fCompilationUnit); + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/JavaTemplateMessages.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/JavaTemplateMessages.java new file mode 100644 index 0000000..c2b0fc8 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/JavaTemplateMessages.java @@ -0,0 +1,43 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.template.java; + +import java.text.MessageFormat; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class JavaTemplateMessages { + + private static final String RESOURCE_BUNDLE= JavaTemplateMessages.class.getName(); + private static ResourceBundle fgResourceBundle= ResourceBundle.getBundle(RESOURCE_BUNDLE); + + private JavaTemplateMessages() { + } + + public static String getString(String key) { + try { + return fgResourceBundle.getString(key); + } catch (MissingResourceException e) { + return '!' + key + '!'; + } + } + + /** + * Gets a string from the resource bundle and formats it with the argument + * + * @param key the string used to get the bundle value, must not be null + */ + public static String getFormattedString(String key, Object arg) { + return MessageFormat.format(getString(key), new Object[] { arg }); + } + + + /** + * Gets a string from the resource bundle and formats it with arguments + */ + public static String getFormattedString(String key, Object[] args) { + return MessageFormat.format(getString(key), args); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/JavaTemplateMessages.properties b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/JavaTemplateMessages.properties new file mode 100644 index 0000000..05d0d06 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/JavaTemplateMessages.properties @@ -0,0 +1,53 @@ +######################################### +# (c) Copyright IBM Corp. 2000, 2001. +# All Rights Reserved. +######################################### + +GlobalVariables.variable.description.cursor=The cursor position after editing template variables +GlobalVariables.variable.description.dollar=The dollar symbol +GlobalVariables.variable.description.date=Current date +GlobalVariables.variable.description.time=Current time +GlobalVariables.variable.description.user=User name + +GlobalVariables.variable.name.cursor=cursor +GlobalVariables.variable.name.dollar=dollar +GlobalVariables.variable.name.date=date +GlobalVariables.variable.name.time=time +GlobalVariables.variable.name.user=user + +# GlobalVariables.variable.description.line=Current line number + +CompilationUnitContextType.variable.description.file=Filename of compilation unit +CompilationUnitContextType.variable.description.enclosing.method=Enclosing method name +CompilationUnitContextType.variable.description.enclosing.type=Enclosing type name +CompilationUnitContextType.variable.description.enclosing.package=Enclosing package name +CompilationUnitContextType.variable.description.enclosing.project=Enclosing project name +CompilationUnitContextType.variable.description.enclosing.method.arguments=Argument names of enclosing method +CompilationUnitContextType.variable.description.return.type=Enclosing method return type + +CompilationUnitContextType.variable.name.file=file +CompilationUnitContextType.variable.name.enclosing.method=enclosing_method +CompilationUnitContextType.variable.name.enclosing.type=enclosing_type +CompilationUnitContextType.variable.name.enclosing.package=enclosing_package +CompilationUnitContextType.variable.name.enclosing.project=enclosing_project +CompilationUnitContextType.variable.name.enclosing.method.arguments=enclosing_method_arguments +CompilationUnitContextType.variable.name.return.type=return_type + +JavaContextType.variable.description.array=A proposal for an array +JavaContextType.variable.description.array.type=A proposal for the element type of an array +JavaContextType.variable.description.array.element=A proposal for the element name of an array +JavaContextType.variable.description.index=A proposal for an index (int) +JavaContextType.variable.description.collection=A proposal for a collection (java.util.Collection) +JavaContextType.variable.description.iterator=A proposal for an iterator (java.util.Iterator) +JavaContextType.variable.description.arguments=Method arguments (evaluates to empty string) + +JavaContextType.variable.name.array=array +JavaContextType.variable.name.array.type=array_type +JavaContextType.variable.name.array.element=array_element +JavaContextType.variable.name.index=index +JavaContextType.variable.name.collection=collection +JavaContextType.variable.name.iterator=iterator +JavaContextType.variable.name.arguments=Method arguments (evaluates to empty string) + +JavaContext.error.title=Template Error +JavaContext.error.message=java context type missing \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/Messages.properties b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/Messages.properties new file mode 100644 index 0000000..729774b --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/Messages.properties @@ -0,0 +1,17 @@ +################################################################################ +# Copyright (c) 2002 International Business Machines Corp. and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Common Public License v0.5 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/cpl-v05.html +# +# Contributors: +# IBM Corporation - initial API and implementation +################################################################################ + +TextRange.offset=Offset: +TextRange.length=\ Length: + +TextBuffer.wrongRange=Replace failed due to wrong range [{0},{1}] + +TextBufferFactory.bufferNotManaged=Buffer not managed diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/MoveTextEdit.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/MoveTextEdit.java new file mode 100644 index 0000000..77a8db5 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/MoveTextEdit.java @@ -0,0 +1,147 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.textmanipulation; + +import org.eclipse.core.runtime.CoreException; + + +//import org.eclipse.jdt.internal.corext.Assert; + +/** + * A text edit that moves text inside a text buffer. + */ +public final class MoveTextEdit extends TextEdit { + + /* package */ static class TargetMark extends NopTextEdit { + private MoveTextEdit fMoveTextEdit; + public TargetMark(TextRange range, MoveTextEdit edit) { + super(range); + fMoveTextEdit= edit; + } + /* package */ MoveTextEdit getMoveTextEdit() { + return fMoveTextEdit; + } + public TextEdit perform(TextBuffer buffer) throws CoreException { + fMoveTextEdit.internalPerform(buffer); + return super.perform(buffer); + } + public TextEdit copy() { + // Assert.isTrue(false, "This should never happen"); //$NON-NLS-1$ + return super.copy(); + } + } + + private TextRange fTarget; + private TextRange fSource; + private int fPerformCounter; + + /** + * Creates a new MoveTextEdit. The text edit doesn't support + * overlapping moves. So for a MoveTextEdit destination <= offset && + * offset + length - 1 <= destination must be true. + * + * @param offset the offset of the text to be moved + * @param length the text length to be moved + * @param destination the destination offset + */ + public MoveTextEdit(int offset, int length, int destination) { + // Assert.isTrue(destination <= offset || offset + length <= destination); + fSource= new TextRange(offset, length); + fTarget= new TextRange(destination); + } + + /** + * Creates a new MoveTextEdit with the given source and target range. + * + * @param source the source + * @param target the target + */ + private MoveTextEdit(TextRange source,TextRange target) { + fSource= source; + fTarget= target; + } + + /** + * Returns the move text edit's source range. This method returns the same range + * as TextEdit#getTextRange() + * + * @return the edit's source range + */ + public TextRange getSourceRange() { + return fSource; + } + + /** + * Returns the move text edit's target range. + * + * @return the edit's target range + */ + public TextRange getTargetRange() { + return fTarget; + } + + /* non Java-doc + * @see TextEdit#getTextRange() + */ + public TextRange getTextRange() { + return fSource; + } + + /* non Java-doc + * @see TextEdit#connect(TextBufferEditor) + */ + public void connect(TextBufferEditor editor) throws CoreException { + editor.add(new TargetMark(fTarget, this)); + } + + /* non Java-doc + * @see TextEdit#perform(TextBuffer) + */ + public TextEdit perform(TextBuffer buffer) throws CoreException { + internalPerform(buffer); + return new MoveTextEdit(fTarget, fSource); + } + + /* non Java-doc + * @see TextEdit#copy() + */ + public TextEdit copy() { + TextRange source= getSourceRange(); + TextRange target= getTargetRange(); + return new MoveTextEdit(source.fOffset, source.fLength, target.fOffset); + } + + //---- Helper method --------------------------------------------------------------------------------- + + private void internalPerform(TextBuffer buffer) throws CoreException { +// Assert.isTrue(fPerformCounter < 2); + if (++fPerformCounter == 2) { + TextRange source= getSourceRange(); + TextRange target= getTargetRange(); + String current= buffer.getContent(source.fOffset, source.fLength); + buffer.replace(source, ""); //$NON-NLS-1$ + buffer.replace(target, current); + } + } + + /* package */ boolean isUpMove() { + return fSource.fOffset < fTarget.fOffset; + } + + /* package */ boolean isDownMove() { + return fSource.fOffset > fTarget.fOffset; + } + + /* package */ TextRange getChildRange() { + int offset= fSource.fOffset; + int length= fSource.fLength; + int destination= fTarget.fOffset; + if (destination <= offset) + return new TextRange(destination, offset + length - destination); + else + return new TextRange(offset, destination - offset); + } +} + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/MultiTextEdit.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/MultiTextEdit.java new file mode 100644 index 0000000..ae29be5 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/MultiTextEdit.java @@ -0,0 +1,136 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.textmanipulation; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.core.internal.utils.Assert; +import org.eclipse.core.runtime.CoreException; + + +public class MultiTextEdit { + + private List fChildren; + + /** + * Creates a new composite text edit. + */ + public MultiTextEdit() { + fChildren= new ArrayList(3); + } + + protected MultiTextEdit(List children) throws CoreException { + fChildren= new ArrayList(children.size()); + for (Iterator iter= children.iterator(); iter.hasNext();) { + fChildren.add(((TextEdit)iter.next()).copy()); + } + } + + protected List getChildren() { + return fChildren; + } + + /** + * Adds all TextEdits managed by the given multt text edit. + * + * @param edit the multi text edit to be added. + */ + public void add(MultiTextEdit edit) { + Assert.isNotNull(edit); + fChildren.add(edit); + } + + /** + * Adds a text edit. + * + * @param edit the text edit to be added + */ + public void add(TextEdit edit) { + Assert.isNotNull(edit); + fChildren.add(edit); + } + + /** + * Returns the children managed by this text edit collection. + * + * @return the children of this composite text edit + */ + public Iterator iterator() { + return fChildren.iterator(); + } + + /** + * Connects this text edit to the given TextBufferEditor. + * Note that this method should only be called by a + * TextBufferEditor. + *

+ * This default implementation does nothing. Subclasses may override + * if needed. + * + * @param editor the text buffer editor this text edit has been added to + */ + public void connect(TextBufferEditor editor) throws CoreException { + for (Iterator iter= fChildren.iterator(); iter.hasNext();) { + Object element= iter.next(); + if (element instanceof TextEdit) + editor.add((TextEdit)element); + else + editor.add((MultiTextEdit)element); + } + } + + /** + * Creates and returns a copy of this text edit collection. The copy method should + * be implemented in a way so that the copy can be added to a different + * TextBuffer without causing any harm to the object from which the copy + * has been created. + * + * @return a copy of this object. + */ + public MultiTextEdit copy() throws CoreException { + return new MultiTextEdit(fChildren); + } + + /** + * Returns the TextRange that this text edit is going to + * manipulate. If this method is called before the MultiTextEdit + * has been added to a TextBufferEditor it may return + * null to indicate this situation. + * + * @return the TextRanges this TextEdit is going + * to manipulate + */ + public TextRange getTextRange() { + int size= fChildren.size(); + if (size == 0) + return new TextRange(0,0); + TextRange range= ((TextEdit)fChildren.get(0)).getTextRange(); + int start= range.getOffset(); + int end= range.getInclusiveEnd(); + for (int i= 1; i < size; i++) { + range= ((TextEdit)fChildren.get(i)).getTextRange(); + start= Math.min(start, range.getOffset()); + end= Math.max(end, range.getInclusiveEnd()); + } + return new TextRange(start, end - start + 1); + } + + /** + * Returns the element modified by this text edit. The method + * may return null if the modification isn't related to a + * element or if the content of the modified text buffer doesn't + * follow any syntax. + *

+ * This default implementation returns null + * + * @return the element modified by this text edit + */ + public Object getModifiedElement() { + return null; + } +} + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/NopTextEdit.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/NopTextEdit.java new file mode 100644 index 0000000..083fe0b --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/NopTextEdit.java @@ -0,0 +1,60 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.textmanipulation; + +import org.eclipse.core.runtime.CoreException; + +/** + * A text edit that does nothing. A NopTextEdit can be used to track + * positions when executing TextEdits associated with a + * TextBufferEditor. + */ +public class NopTextEdit extends TextEdit { + + private TextRange fTextRange; + + /** + * Creates a new NopTextEdit for the given + * offset and length. + * + * @param offset the starting offset this text edit is "working on" + * @param length the length this text edit is "working on" + */ + public NopTextEdit(int offset, int length) { + this(new TextRange(offset, length)); + } + + /** + * Creates a new NopTextEdit for the given + * range. + * + * @param range the TextRange this text edit is "working on" + */ + public NopTextEdit(TextRange range) { + fTextRange= range; + } + + /* non Java-doc + * @see TextEdit#getTextRange + */ + public TextRange getTextRange() { + return fTextRange; + } + + /* non Java-doc + * @see TextEdit#perform + */ + public TextEdit perform(TextBuffer buffer) throws CoreException { + return new NopTextEdit(fTextRange); + } + + /* non Java-doc + * @see TextEdit#perform + */ + public TextEdit copy() { + return new NopTextEdit(fTextRange.copy()); + } +} + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/SimpleTextEdit.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/SimpleTextEdit.java new file mode 100644 index 0000000..1000537 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/SimpleTextEdit.java @@ -0,0 +1,105 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.textmanipulation; + +import org.eclipse.core.runtime.CoreException; + +//import org.eclipse.jdt.internal.corext.Assert; + +public abstract class SimpleTextEdit extends TextEdit { + + private TextRange fRange; + private String fText; + + public static SimpleTextEdit createReplace(int offset, int length, String text) { + return new SimpleTextEditImpl(offset, length, text); + } + + public static SimpleTextEdit createInsert(int offset, String text) { + return new SimpleTextEditImpl(offset, 0, text); + } + + public static SimpleTextEdit createDelete(int offset, int length) { + return new SimpleTextEditImpl(offset, length, ""); //$NON-NLS-1$ + } + + private final static class SimpleTextEditImpl extends SimpleTextEdit { + protected SimpleTextEditImpl(TextRange range, String text) { + super(range, text); + } + protected SimpleTextEditImpl(int offset, int length, String text) { + super(offset, length, text); + } + public TextEdit copy() { + return new SimpleTextEditImpl(getTextRange().copy(), getText()); + } + } + + protected SimpleTextEdit() { + this(TextRange.UNDEFINED, ""); //$NON-NLS-1$ + } + + protected SimpleTextEdit(int offset, int length, String text) { + this(new TextRange(offset, length), text); + } + protected SimpleTextEdit(TextRange range, String text) { + // Assert.isNotNull(range); + // Assert.isNotNull(text); + fRange= range; + fText= text; + } + + /** + * Returns the text edit's text + * + * @return the text edit's text + */ + public String getText() { + return fText; + } + + /** + * Sets the text edit's text + *

+ * This method should only be called from within the + * connect method. + * + * @param text the text edit's text + */ + protected final void setText(String text) { + fText= text; +// Assert.isNotNull(fText); + } + + /** + * Sets the text edit's range. + *

+ * This method should only be called from within the + * connect method. + * + * @param range the text edit's range. + */ + protected void setTextRange(TextRange range) { + fRange= range; + // Assert.isNotNull(fRange); + } + + /* non Java-doc + * @see TextEdit#getTextRange + */ + public TextRange getTextRange() { + return fRange; + } + + /* non Java-doc + * @see TextEdit#doPerform + */ + public final TextEdit perform(TextBuffer buffer) throws CoreException { + String current= buffer.getContent(fRange.fOffset, fRange.fLength); + buffer.replace(fRange, fText); + return new SimpleTextEditImpl(fRange, current); + } +} + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/SwapTextEdit.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/SwapTextEdit.java new file mode 100644 index 0000000..eb0d247 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/SwapTextEdit.java @@ -0,0 +1,25 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.textmanipulation; + + +/** + * A SwapTextEdit exchanges to text ranges. + */ +public class SwapTextEdit extends MultiTextEdit { + /** + * Create a new SwapTextEdit + * + * @param offset1 the offset of the first text range + * @param length1 the length of the first text range + * @param offset2 the offset of the second text range + * @param length2 the length of the second text range + */ + public SwapTextEdit(int offset1, int length1, int offset2, int length2) { + add(new MoveTextEdit(offset1, length1, offset2)); + add(new MoveTextEdit(offset2, length2, offset1)); + } +} + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextBuffer.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextBuffer.java new file mode 100644 index 0000000..c7e2476 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextBuffer.java @@ -0,0 +1,418 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.textmanipulation; + +import java.util.ArrayList; +import java.util.List; + +import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import net.sourceforge.phpdt.internal.corext.util.Strings; +import net.sourceforge.phpdt.internal.ui.JavaStatusConstants; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.DefaultLineTracker; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IDocumentListener; +import org.eclipse.jface.text.ILineTracker; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.util.Assert; + +//import org.eclipse.jdt.internal.ui.JavaPlugin; +//import org.eclipse.jdt.internal.ui.JavaStatusConstants; + +/** + * An implementation of a TextBuffer that is based on ITextSelection + * and IDocument. + */ +public class TextBuffer { + + private static class DocumentRegion extends TextRegion { + IRegion fRegion; + public DocumentRegion(IRegion region) { + fRegion= region; + } + public int getOffset() { + return fRegion.getOffset(); + } + public int getLength() { + return fRegion.getLength(); + } + } + + public class Block { + public String content; + public int offsetDelta; + } + + private IDocument fDocument; + + private static final TextBufferFactory fgFactory= new TextBufferFactory(); + + TextBuffer(IDocument document) { + fDocument= document; + Assert.isNotNull(fDocument); + } + + /** + * Returns the number of characters in this text buffer. + * + * @return the number of characters in this text buffer + */ + public int getLength() { + return fDocument.getLength(); + } + + /** + * Returns the number of lines in this text buffer. + * + * @return the number of lines in this text buffer + */ + public int getNumberOfLines() { + return fDocument.getNumberOfLines(); + } + + /** + * Returns the character at the given offset in this text buffer. + * + * @param offset a text buffer offset + * @return the character at the offset + * @exception IndexOutOfBoundsException if the offset + * argument is negative or not less than the length of this text buffer. + */ + public char getChar(int offset) { + try { + return fDocument.getChar(offset); + } catch (BadLocationException e) { + throw new ArrayIndexOutOfBoundsException(e.getMessage()); + } + } + + /** + * Returns the whole content of the text buffer. + * + * @return the whole content of the text buffer + */ + public String getContent() { + return fDocument.get(); + } + + /** + * Returns length characters starting from the specified position. + * + * @return the characters specified by the given text region. Returns + * null if text range is illegal + */ + public String getContent(int start, int length) { + try { + return fDocument.get(start, length); + } catch (BadLocationException e) { + return null; + } + } + + public Block getBlockContent(int start, int length, int tabWidth) { + Block result= new Block(); + StringBuffer buffer= new StringBuffer(); + int lineOffset= getLineInformationOfOffset(start).getOffset(); + if (start > lineOffset) { + String line= getContent(lineOffset, start - lineOffset); + String indent= Strings.getIndentString(line, tabWidth); + result.offsetDelta= -indent.length(); + buffer.append(indent); + } + final int end= start + length; + TextRegion region= getLineInformationOfOffset(end); + lineOffset= region.getOffset(); + // Cursor is at beginning of next line + if (lineOffset == end) { + int lineNumber= getLineOfOffset(lineOffset); + if (lineNumber > 0) { + length= length - getLineDelimiter(lineNumber - 1).length(); + } + } + if (buffer.length() == 0) { + result.content= getContent(start, length); + } else { + buffer.append(getContent(start, length)); + result.content= buffer.toString(); + } + return result; + } + + /** + * Returns the preferred line delimiter to be used for this text buffer. + * + * @return the preferred line delimiter + */ + public String getLineDelimiter() { + String lineDelimiter= getLineDelimiter(0); + if (lineDelimiter == null) + lineDelimiter= System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ + return lineDelimiter; + } + + /** + * Returns the line delimiter used for the given line number. Returns + * null if the line number is out of range. + * + * @return the line delimiter used by the given line number or null + */ + public String getLineDelimiter(int line) { + try { + return fDocument.getLineDelimiter(line); + } catch (BadLocationException e) { + return null; + } + } + + /** + * Returns the line for the given line number. If there isn't any line for + * the given line number, null is returned. + * + * @return the line for the given line number or null + */ + public String getLineContent(int line) { + try { + IRegion region= fDocument.getLineInformation(line); + return fDocument.get(region.getOffset(), region.getLength()); + } catch (BadLocationException e) { + return null; + } + } + + /** + * Returns the line indent for the given line. If there isn't any line for the + * given line number, -1 is returned. + * + * @return the line indent for the given line number of -1 + */ + public int getLineIndent(int lineNumber, int tabWidth) { + return Strings.computeIndent(getLineContent(lineNumber), tabWidth); + } + + /** + * Returns a region of the specified line. The region contains the offset and the + * length of the line excluding the line's delimiter. Returns null + * if the line doesn't exist. + * + * @param line the line of interest + * @return a line description or null if the given line doesn't + * exist + */ + public TextRegion getLineInformation(int line) { + try { + return new DocumentRegion(fDocument.getLineInformation(line)); + } catch (BadLocationException e) { + return null; + } + } + + /** + * Returns a line region of the specified offset. The region contains the offset and + * the length of the line excluding the line's delimiter. Returns null + * if the line doesn't exist. + * + * @param offset an offset into a line + * @return a line description or null if the given line doesn't + * exist + */ + public TextRegion getLineInformationOfOffset(int offset) { + try { + return new DocumentRegion(fDocument.getLineInformationOfOffset(offset)); + } catch (BadLocationException e) { + return null; + } + } + + /** + * Returns the line number that contains the given position. If there isn't any + * line that contains the position, null is returned. The returned + * string is a copy and doesn't contain the line delimiter. + * + * @return the line that contains the given offset or null if line + * doesn't exist + */ + public int getLineOfOffset(int offset) { + try { + return fDocument.getLineOfOffset(offset); + } catch (BadLocationException e) { + return -1; + } + } + + /** + * Returns the line that contains the given position. If there isn't any + * line that contains the position, null is returned. The returned + * string is a copy and doesn't contain the line delimiter. + * + * @return the line that contains the given offset or null if line + * doesn't exist + */ + public String getLineContentOfOffset(int offset) { + try { + IRegion region= fDocument.getLineInformationOfOffset(offset); + return fDocument.get(region.getOffset(), region.getLength()); + } catch (BadLocationException e) { + return null; + } + } + + /** + * Converts the text determined by the region [offset, length] into an array of lines. + * The lines are copies of the original lines and don't contain any line delimiter + * characters. + * + * @return the text converted into an array of strings. Returns null if the + * region lies outside the source. + */ + public String[] convertIntoLines(int offset, int length, boolean lastNewLineCreateEmptyLine) { + try { + String text= fDocument.get(offset, length); + ILineTracker tracker= new DefaultLineTracker(); + tracker.set(text); + int size= tracker.getNumberOfLines(); + int lastLine= size - 1; + List result= new ArrayList(size); + for (int i= 0; i < size; i++) { + IRegion region= tracker.getLineInformation(i); + String line= getContent(offset + region.getOffset(), region.getLength()); + if (i < lastLine || !"".equals(line) || lastNewLineCreateEmptyLine) //$NON-NLS-1$ + result.add(line); + } + return (String[]) result.toArray(new String[result.size()]); + } catch (BadLocationException e) { + return null; + } + } + + /** + * Subsitutes the given text for the specified text position + * + * @param offset the starting offset of the text to be replaced + * @param length the length of the text to be replaced + * @param text the substitution text + * @exception CoreException if the text position [offset, length] is invalid. + */ + public void replace(int offset, int length, String text) throws CoreException { + try { + fDocument.replace(offset, length, text); + } catch (BadLocationException e) { + IStatus s = new Status(IStatus.ERROR, PHPeclipsePlugin.getPluginId(), JavaStatusConstants.INTERNAL_ERROR, + TextManipulationMessages.getFormattedString( + "TextBuffer.wrongRange", //$NON-NLS-1$ + new Object[] {new Integer(offset), new Integer(length) } ), e); + throw new CoreException(s); + } + } + + public void replace(TextRange range, String text) throws CoreException { + replace(range.fOffset, range.fLength, text); + } + + //---- Special methods used by the TextBufferEditor + + /** + * Releases this text buffer. + */ + /* package */ void release() { + } + + /* package */ void registerUpdater(IDocumentListener listener) { + fDocument.addDocumentListener(listener); + } + + /* package */ void unregisterUpdater(IDocumentListener listener) { + fDocument.removeDocumentListener(listener); + } + + //---- Factory methods ---------------------------------------------------------------- + + /** + * Acquires a text buffer for the given file. If a text buffer for the given + * file already exists, then that one is returned. + * + * @param file the file for which a text buffer is requested + * @return a managed text buffer for the given file + * @exception CoreException if it was not possible to acquire the + * text buffer + */ + public static TextBuffer acquire(IFile file) throws CoreException { + return fgFactory.acquire(file); + } + + /** + * Releases the given text buffer. + * + * @param buffer the text buffer to be released + */ + public static void release(TextBuffer buffer) { + fgFactory.release(buffer); + } + + /** + * Commits the changes made to the given text buffer to the underlying + * storage system. + * + * @param buffer the text buffer containing the changes to be committed. + * @param force if true the text buffer is committed in any case. + * If false the text buffer is ONLY committed if the client + * is the last one that holds a reference to the text buffer. Clients of this + * method must make sure that they don't call this method from within an + * IWorkspaceRunnable. + * @param pm the progress monitor used to report progress if committing is + * necessary + */ + public static void commitChanges(TextBuffer buffer, boolean force, IProgressMonitor pm) throws CoreException { + fgFactory.commitChanges(buffer, force, pm); + } + + /** + * Creates a new TextBuffer for the given file. The returned + * buffer will not be managed. Any subsequent call to create + * with the same file will return a different text buffer. + *

+ * If the file is currently open in a text editor, the editors content is copied into + * the returned TextBuffer. Otherwise the content is read from + * disk. + * + * @param file the file for which a text buffer is to be created + * @return a new unmanaged text buffer + * @exception CoreException if it was not possible to create the text buffer + */ + public static TextBuffer create(IFile file) throws CoreException { + return fgFactory.create(file); + } + + /** + * Creates a new TextBuffer for the string. The returned + * buffer will not be managed. Any subsequent call to create + * with the identical string will return a different text buffer. + * + * @param content the text buffer's content + * @return a new unmanaged text buffer + */ + public static TextBuffer create(String content) { + return fgFactory.create(content); + } + + // Unclear which methods are needed if we get the new save model. If optimal no + // save is needed at all. + + public static void save(TextBuffer buffer, IProgressMonitor pm) throws CoreException { + fgFactory.save(buffer, pm); + } + + public static void aboutToChange(TextBuffer buffer) throws CoreException { + fgFactory.aboutToChange(buffer); + } + + public static void changed(TextBuffer buffer) throws CoreException { + fgFactory.changed(buffer); + } +} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextBufferEditor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextBufferEditor.java new file mode 100644 index 0000000..05333c3 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextBufferEditor.java @@ -0,0 +1,217 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.textmanipulation; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import net.sourceforge.phpdt.internal.corext.textmanipulation.TextEditNode.RootNode; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; + +//import org.eclipse.jdt.core.IJavaModelStatusConstants; +//import org.eclipse.jdt.core.JavaModelException; +// +//import org.eclipse.jdt.internal.corext.Assert; + + +/** + * A TextBufferEditor manages a set of TextEdits and applies + * them as a whole to a TextBuffer. Added TextEdits must + * not overlap. The only exception from this rule are insertion point. There can be more than + * one insert point at the same text position. Clients should use the method + * canPerformEdits to validate if all added text edits follow these rules. + *

+ * Clients can attach more than one TextBufferEditor to a single + * TextBuffer. If so canPerformEdits validates all text edits from + * all text buffer editors working on the same text buffer. + */ +public class TextBufferEditor { + + private TextBuffer fBuffer; + private List fEdits; + private RootNode fRootNode; + private int fNumberOfNodes; + private int fConnectCount; + private int fMode; + + /* package */ static final int UNDEFINED= 0; + /* package */ static final int REDO= 1; + /* package */ static final int UNDO= 2; + + /** + * Creates a new TextBufferEditor for the given + * TextBuffer. + * + * @param the text buffer this editor is working on. + */ + public TextBufferEditor(TextBuffer buffer) { + fBuffer= buffer; + // Assert.isNotNull(fBuffer); + fEdits= new ArrayList(); + } + + /** + * Returns the text buffer this editor is working on. + * + * @return the text buffer this editor is working on + */ + public TextBuffer getTextBuffer() { + return fBuffer; + } + + /** + * Adds a TextEdit to this text editor. Adding a TextEdit + * to a TextBufferEditor transfers ownership of the edit to the editor. So + * after a edit has been added to a editor the creator of that edit must not continue + * modifing it. + * + * @param edit the text edit to be added + * @exception CoreException if the text edit can not be added + * to this text buffer editor + */ + public void add(TextEdit edit) throws CoreException { + // Assert.isTrue(fMode == UNDEFINED || fMode == REDO); + internalAdd(edit); + fMode= REDO; + } + + /** + * Adds a MultiTextEdit to this text editor. Adding a MultiTextEdit + * to a TextBufferEditor transfers ownership of the edit to the editor. So + * after a edit has been added to a editor the creator of that edit must not continue + * modifing it. + * + * @param edit the multi text edit to be added + * @exception CoreException if the multi text edit can not be added + * to this text buffer editor + */ + public void add(MultiTextEdit edit) throws CoreException { + // Assert.isTrue(fMode == UNDEFINED || fMode == REDO); + edit.connect(this); + fMode= REDO; + } + + /** + * Adds a UndoMemento to this text editor. Adding a UndoMemento + * to a TextBufferEditor transfers ownership of the memento to the editor. So + * after a memento has been added to a editor the creator of that memento must not continue + * modifing it. + * + * @param undo the undo memento to be added + * @exception CoreException if the undo memento can not be added + * to this text buffer editor + */ + public void add(UndoMemento undo) throws CoreException { + // Assert.isTrue(fMode == UNDEFINED); + List list= undo.fEdits; + // Add them reverse since we are adding undos. + for (int i= list.size() - 1; i >= 0; i--) { + internalAdd((TextEdit)list.get(i)); + } + fMode= undo.fMode; + } + + /** + * Checks if the TextEdit added to this text editor can be executed. + * + * @return true if the edits can be executed. Return false + * otherwise. One major reason why text edits cannot be executed + * is a wrong offset or length value of a TextEdit. + */ + public boolean canPerformEdits() { + if (fRootNode != null) + return true; + fRootNode= buildTree(); + if (fRootNode == null) + return false; + if (fRootNode.validate(fBuffer.getLength())) + return true; + + fRootNode= null; + return false; + } + + /** + * Clears the text buffer editor. + */ + public void clear() { + fRootNode= null; + fMode= UNDEFINED; + fEdits.clear(); + } + + /** + * Executes the text edits added to this text buffer editor and clears all added + * text edits. + * + * @param pm a progress monitor to report progress or null if + * no progress is desired. + * @return an object representing the undo of the executed TextEdits + * @exception CoreException if the edits cannot be executed + */ + public UndoMemento performEdits(IProgressMonitor pm) throws CoreException { + if (pm == null) + pm= new NullProgressMonitor(); + + int size= fEdits.size(); + if (size == 0) + return new UndoMemento(fMode == UNDO ? REDO : UNDO); + + if (fRootNode == null) { + fRootNode= buildTree(); + if (fRootNode == null || !fRootNode.validate(fBuffer.getLength())) { + // throw new JavaModelException(null, IJavaModelStatusConstants.NO_ELEMENTS_TO_PROCESS); + } + } + try { + pm.beginTask("", fNumberOfNodes + 10); //$NON-NLS-1$ + UndoMemento undo= null; + if (fMode == REDO) { + undo= fRootNode.performDo(fBuffer, pm); + fRootNode.performedDo(); + } else { + undo= fRootNode.performUndo(fBuffer, pm); + fRootNode.performedUndo(); + } + pm.worked(10); + return undo; + } finally { + pm.done(); + clear(); + } + } + + //---- Helper methods ------------------------------------------------------------ + + private RootNode buildTree() { + TextEditNode[] nodes= new TextEditNode[fEdits.size()]; + for (int i= fEdits.size() - 1; i >= 0; i--) { + nodes[i]= TextEditNode.create((TextEdit)fEdits.get(i)); + } + fNumberOfNodes= nodes.length; + Arrays.sort(nodes, new TextEditNodeComparator()); + RootNode root= new RootNode(fBuffer.getLength()); + for (int i= 0; i < nodes.length; i++) { + root.add(nodes[i]); + } + return root; + } + + private void internalAdd(TextEdit edit) throws CoreException { + edit.index= fEdits.size(); + edit.isSynthetic= fConnectCount > 0; + try { + fConnectCount++; + edit.connect(this); + } finally { + fConnectCount--; + } + fEdits.add(edit); + } +} + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextBufferFactory.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextBufferFactory.java new file mode 100644 index 0000000..5d6800b --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextBufferFactory.java @@ -0,0 +1,186 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.textmanipulation; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.HashMap; +import java.util.Map; + +import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import net.sourceforge.phpdt.internal.corext.util.IOCloser; +import net.sourceforge.phpdt.internal.ui.JavaStatusConstants; +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.jface.util.Assert; +import org.eclipse.ui.part.FileEditorInput; +import org.eclipse.ui.texteditor.IDocumentProvider; + +/* package */ class TextBufferFactory { + + private IDocumentProvider fDocumentProvider; + private Map fFileValueMap; + private Map fBufferValueMap; + + private static class Value { + TextBuffer buffer; + FileEditorInput input; + IDocument document; + IAnnotationModel annotationModel; + int references; + public Value(TextBuffer b, FileEditorInput i, IDocument d, IAnnotationModel m) { + buffer= b; + input= i; + document= d; + annotationModel= m; + } + } + + public TextBufferFactory() { + // XXX http://dev.eclipse.org/bugs/show_bug.cgi?id=5170 + // Need way to map a file to a document without knowing any kind of document provider. + this(PHPeclipsePlugin.getDefault().getCompilationUnitDocumentProvider()); + } + + public TextBufferFactory(IDocumentProvider provider) { + fDocumentProvider= provider; + Assert.isNotNull(fDocumentProvider); + fFileValueMap= new HashMap(5); + fBufferValueMap= new HashMap(5); + } + + public TextBuffer acquire(IFile file) throws CoreException { + FileEditorInput input= new FileEditorInput(file); + + Value value= (Value)fFileValueMap.get(input); + if (value != null) { + value.references++; + return value.buffer; + } + + fDocumentProvider.connect(input); + IDocument document= fDocumentProvider.getDocument(input); + IAnnotationModel annotationModel= fDocumentProvider.getAnnotationModel(input); + annotationModel.connect(document); + value= new Value(new TextBuffer(document), input, document, annotationModel); + fFileValueMap.put(input, value); + fBufferValueMap.put(value.buffer, value); + value.references++; + return value.buffer; + } + + public void release(TextBuffer buffer) { + final Value value= (Value)fBufferValueMap.get(buffer); + if (value == null) + return; + + value.references--; + if (value.references == 0) { + buffer.release(); + value.annotationModel.disconnect(value.document); + fDocumentProvider.disconnect(value.input); + fFileValueMap.remove(value.input); + fBufferValueMap.remove(buffer); + } + } + + public void commitChanges(TextBuffer buffer, boolean force, IProgressMonitor pm) throws CoreException { + final Value value= (Value)fBufferValueMap.get(buffer); + if (value == null) + return; + + boolean save= force || fDocumentProvider.mustSaveDocument(value.input); + if (save) { + IWorkspaceRunnable action= new IWorkspaceRunnable() { + public void run(IProgressMonitor pm) throws CoreException { + fDocumentProvider.aboutToChange(value.input); + fDocumentProvider.saveDocument(pm, value.input, value.document, true); + } + }; + try { + ResourcesPlugin.getWorkspace().run(action, pm); + } finally { + fDocumentProvider.changed(value.input); + } + } + } + + public TextBuffer create(IFile file) throws CoreException { + FileEditorInput input= new FileEditorInput(file); + IDocument document= fDocumentProvider.getDocument(input); + if (document != null) { + return new TextBuffer(new Document(document.get())); + } else { + return createFromFile(file); + } + } + + private TextBuffer createFromFile(IFile file) throws CoreException { + IDocument document; + // Fix for http://dev.eclipse.org/bugs/show_bug.cgi?id=19319 + InputStream stream= file.getContents(); + InputStreamReader in= null; + try { + document= new Document(); + in= new InputStreamReader(new BufferedInputStream(stream), ResourcesPlugin.getEncoding()); + StringBuffer buffer= new StringBuffer(); + char[] readBuffer= new char[2048]; + int n= in.read(readBuffer); + while (n > 0) { + buffer.append(readBuffer, 0, n); + n= in.read(readBuffer); + } + document.set(buffer.toString()); + return new TextBuffer(document); + } catch (IOException x) { + IStatus s= new Status(IStatus.ERROR, PHPeclipsePlugin.getPluginId(), JavaStatusConstants.INTERNAL_ERROR, x.getMessage(), x); + throw new CoreException(s); + } finally { + IOCloser.perform(in, stream); + } + } + + public TextBuffer create(String content) { + return new TextBuffer(new Document(content)); + } + + public void save(TextBuffer buffer, IProgressMonitor pm) throws CoreException { + Value value= (Value)fBufferValueMap.get(buffer); + if (value == null) + throwNotManaged(); + fDocumentProvider.saveDocument(pm, value.input, value.document, true); + } + + public void aboutToChange(TextBuffer buffer) throws CoreException { + Value value= (Value)fBufferValueMap.get(buffer); + if (value == null) + throwNotManaged(); + fDocumentProvider.aboutToChange(value.input); + } + + public void changed(TextBuffer buffer) throws CoreException { + Value value= (Value)fBufferValueMap.get(buffer); + if (value == null) + throwNotManaged(); + fDocumentProvider.changed(value.input); + } + + private void throwNotManaged() throws CoreException { + IStatus s= new Status(IStatus.ERROR, PHPeclipsePlugin.getPluginId(), + JavaStatusConstants.INTERNAL_ERROR, TextManipulationMessages.getString("TextBufferFactory.bufferNotManaged"), null); //$NON-NLS-1$ + throw new CoreException(s); + } +} + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextEdit.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextEdit.java new file mode 100644 index 0000000..933aad4 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextEdit.java @@ -0,0 +1,100 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.textmanipulation; + +import org.eclipse.core.runtime.CoreException; + +/** + * A text edit describes an elementary text manipulation operation. Text edits + * are executed by adding them to a TextBufferEditor and then + * calling perform on the TextBufferEditor. + *

+ * After a TextEdit has been added to a TextBufferEditor + * the method connect is sent to the text edit. A TextEdit + * is allowed to do some adjustments of the text range it is going to manipulate while inside + * the hook connect. + * + * @see TextBufferEditor + */ +public abstract class TextEdit { + + // index that determines the insertion order into a text buffer + /* package */ int index; + /* package */ boolean isSynthetic; + + /** + * Connects this text edit to the given TextBufferEditor. A text edit + * must not keep a reference to the passed text buffer editor. It is guaranteed that + * the buffer passed to perform is equal to the buffer managed by + * the given text buffer editor. But they don't have to be identical. + *

+ * Note that this method should only be called by a + * TextBufferEditor. + *

+ * This default implementation does nothing. Subclasses may override + * if needed. + * + * @param editor the text buffer editor this text edit has been added to + */ + public void connect(TextBufferEditor editor) throws CoreException { + // does nothing + } + + /** + * Returns the TextRange that this text edit is going to + * manipulate. If this method is called before the TextEdit + * has been added to a TextBufferEditor it may return + * null or TextRange.UNDEFINED to indicate this situation. + * + * @return the TextRanges this TextEdit is going + * to manipulate + */ + public abstract TextRange getTextRange(); + + /** + * Performs the text edit. Note that this method should only be called + * by a TextBufferEditor. + * + * @param buffer the actual buffer to manipulate + * @return a text edit that can undo this text edit + */ + public abstract TextEdit perform(TextBuffer buffer) throws CoreException; + + /** + * This method gets called after all TextEdits added to a text buffer + * editor are executed. Implementors of this method can do some clean-up or can + * release allocated resources that are now longer needed. + *

+ * This default implementation does nothing. + */ + public void performed() { + // do nothing + } + + /** + * Creates and returns a copy of this object. The copy method should + * be implemented in a way so that the copy can be added to a different + * TextBufferEditor without causing any harm to the object + * from which the copy has been created. + * + * @return a copy of this object. + */ + public abstract TextEdit copy() throws CoreException; + + /** + * Returns the element modified by this text edit. The method + * may return null if the modification isn't related to a + * element or if the content of the modified text buffer doesn't + * follow any syntax. + *

+ * This default implementation returns null + * + * @return the element modified by this text edit + */ + public Object getModifiedElement() { + return null; + } +} + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextEditNode.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextEditNode.java new file mode 100644 index 0000000..7cfaa70 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextEditNode.java @@ -0,0 +1,493 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.textmanipulation; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.text.DocumentEvent; +import org.eclipse.jface.text.IDocumentListener; + + +/** + * A helper class to arrange TextEdits into a tree to optimize their + * execution. + */ +/* package */ abstract class TextEditNode { + + /* package */ TextEditNode fParent; + /* package */ List fChildren; + /* package */ TextEdit fEdit; + + /* package */ static class DefaultNode extends TextEditNode { + public DefaultNode(TextEdit edit) { + super(edit); + } + } + + /* package */ static class RootNode extends TextEditNode { + private int fUndoIndex; + public RootNode(int length) { + super(new NopTextEdit(new TextRange(0, length))); + fEdit.isSynthetic= true; + } + public boolean covers(TextEditNode node) { + return true; + } + public UndoMemento performDo(TextBuffer buffer, IProgressMonitor pm) throws CoreException { + DoRangeUpdater updater= new DoRangeUpdater(); + UndoMemento undo= new UndoMemento(TextBufferEditor.UNDO); + try { + buffer.registerUpdater(updater); + performDo(buffer, updater, undo, pm); + } finally { + buffer.unregisterUpdater(updater); + updater.setActiveNode(null); + } + return undo; + } + public UndoMemento performUndo(TextBuffer buffer, IProgressMonitor pm) throws CoreException { + UndoRangeUpdater updater= new UndoRangeUpdater(this); + UndoMemento undo= new UndoMemento(TextBufferEditor.REDO); + try { + buffer.registerUpdater(updater); + performUndo(buffer, updater, undo, pm); + } finally { + buffer.unregisterUpdater(updater); + updater.setActiveNode(null); + } + return undo; + } + + protected void setUndoIndex(int index) { + fUndoIndex= index; + } + + protected int getUndoIndex() { + return fUndoIndex; + } + } + + /* package */ abstract static class AbstractMoveNode extends TextEditNode { + private int state; + + private int fTargetIndex; + private int fSourceIndex; + + private List fAffectedChildren; + + public AbstractMoveNode(TextEdit edit) { + super(edit); + reset(); + } + protected abstract TextRange getSourceRange(); + protected abstract TextRange getTargetRange(); + protected abstract boolean isUpMove(); + protected boolean isDownMove() { + return !isUpMove(); + } + public boolean isMove() { + return true; + } + protected void checkRange(DocumentEvent event) { + TextRange range= getChildRange(); + int eventOffset= event.getOffset(); + int eventLength= event.getLength(); + int eventEnd = eventOffset + eventLength - 1; + // "Edit changes text that lies outside its defined range" + // Assert.isTrue(range.fOffset <= eventOffset && eventEnd <= range.getInclusiveEnd()); + } + protected boolean activeNodeChanged(int delta) { + TextRange targetRange= getTargetRange(); + TextRange sourceRange= getSourceRange(); + switch (state) { + case 0: // the move delete + init(); + // Assert.isTrue(Math.abs(delta) == sourceRange.fLength); + if (isUpMove()) { + updateOffset(fAffectedChildren, delta); + targetRange.fOffset+= delta; + } + sourceRange.fLength= 0; + state= 1; + break; + case 1: + TextEditNode target= (TextEditNode)fParent.fChildren.get(fTargetIndex); + TextEditNode source= (TextEditNode)fParent.fChildren.get(fSourceIndex); + updateOffset(source.fChildren, targetRange.fOffset - sourceRange.fOffset); + target.fChildren= source.fChildren; + if (target.fChildren != null) { + for (Iterator iter= target.fChildren.iterator(); iter.hasNext();) { + ((TextEditNode)iter.next()).fParent= target; + } + } + source.fChildren= null; + if (isDownMove()) { + updateOffset(fAffectedChildren, delta); + sourceRange.fOffset+= delta; + } + targetRange.fLength= delta; + reset(); + break; + } + return true; + } + private static void updateOffset(List nodes, int delta) { + if (nodes == null) + return; + for (int i= nodes.size() - 1; i >= 0; i--) { + TextEditNode node= (TextEditNode)nodes.get(i); + TextRange range= node.getTextRange(); + range.fOffset+= delta; + updateOffset(node.fChildren, delta); + } + } + private void init() { + TextRange source= getSourceRange(); + TextRange target= getTargetRange(); + List children= fParent.fChildren; + for (int i= children.size() - 1; i >= 0; i--) { + TextEditNode child= (TextEditNode)children.get(i); + TextRange range= child.fEdit.getTextRange(); + if (range == source) + fSourceIndex= i; + else if (range == target) + fTargetIndex= i; + } + int start= Math.min(fTargetIndex, fSourceIndex); + int end= Math.max(fTargetIndex, fSourceIndex); + fAffectedChildren= new ArrayList(3); + for (int i= start + 1; i < end; i++) { + fAffectedChildren.add(children.get(i)); + } + } + private void reset() { + state= 0; + fSourceIndex= -1; + fTargetIndex= -1; + } + } + + /* package */ static class MoveNode extends AbstractMoveNode { + public MoveNode(TextEdit edit) { + super(edit); + } + protected TextRange getChildRange() { + return ((MoveTextEdit)fEdit).getChildRange(); + } + protected TextRange getSourceRange() { + return ((MoveTextEdit)fEdit).getSourceRange(); + } + protected TextRange getTargetRange() { + return ((MoveTextEdit)fEdit).getTargetRange(); + } + protected boolean isUpMove() { + return ((MoveTextEdit)fEdit).isUpMove(); + } + public boolean isMovePartner(TextEditNode other) { + if (!(other instanceof TargetMarkNode)) + return false; + return fEdit == ((MoveTextEdit.TargetMark)other.fEdit).getMoveTextEdit(); + } + public boolean covers(TextEditNode node) { + if (node instanceof TargetMarkNode) { + MoveTextEdit.TargetMark edit= (MoveTextEdit.TargetMark)node.fEdit; + if (edit.getMoveTextEdit() == fEdit) + return false; + } + return getParentRange().covers(node.getChildRange()); + } + } + + /* package */ static class TargetMarkNode extends AbstractMoveNode { + public TargetMarkNode(TextEdit edit) { + super(edit); + } + protected TextRange getChildRange() { + return ((MoveTextEdit.TargetMark)fEdit).getMoveTextEdit().getChildRange(); + } + protected TextRange getSourceRange() { + return ((MoveTextEdit.TargetMark)fEdit).getMoveTextEdit().getSourceRange(); + } + protected TextRange getTargetRange() { + return ((MoveTextEdit.TargetMark)fEdit).getMoveTextEdit().getTargetRange(); + } + protected boolean isUpMove() { + return ((MoveTextEdit.TargetMark)fEdit).getMoveTextEdit().isUpMove(); + } + public boolean isMovePartner(TextEditNode other) { + return ((MoveTextEdit.TargetMark)fEdit).getMoveTextEdit() == other.fEdit; + } + } + + //---- Range updating --------------------------------------------------------------------------- + + private static abstract class RangeUpdater implements IDocumentListener { + protected TextEditNode fActiveNode; + public void documentAboutToBeChanged(DocumentEvent event) { + } + public void setActiveNode(TextEditNode node) { + fActiveNode= node; + } + public void updateParents(int delta) { + TextEditNode node= fActiveNode.fParent; + while (node != null) { + node.childNodeChanged(delta); + node= node.fParent; + } + } + public static int getDelta(DocumentEvent event) { + return (event.getText() == null ? 0 : event.getText().length()) - event.getLength(); + } + } + private static class DoRangeUpdater extends RangeUpdater { + private List fProcessedNodes= new ArrayList(10); + public void setActiveNode(TextEditNode node) { + if (fActiveNode != null) + fProcessedNodes.add(fActiveNode); + super.setActiveNode(node); + } + public void documentChanged(DocumentEvent event) { + fActiveNode.checkRange(event); + int delta= getDelta(event); + if (!fActiveNode.activeNodeChanged(delta)) { + for (Iterator iter= fProcessedNodes.iterator(); iter.hasNext();) { + ((TextEditNode)iter.next()).previousNodeChanged(delta); + } + } + updateParents(delta); + } + } + private static class UndoRangeUpdater extends RangeUpdater { + private RootNode fRootNode; + public UndoRangeUpdater(RootNode root) { + fRootNode= root; + } + public void setActiveNode(TextEditNode node) { + super.setActiveNode(node); + } + public void documentChanged(DocumentEvent event) { + fActiveNode.checkRange(event); + int delta= getDelta(event); + if (!fActiveNode.activeNodeChanged(delta)) { + int start= fRootNode.getUndoIndex() + 1; + List children= fRootNode.fChildren; + int size= children != null ? children.size() : 0; + for (int i= start; i < size; i++) { + updateUndo((TextEditNode)children.get(i), delta); + } + } + updateParents(delta); + } + private void updateUndo(TextEditNode node, int delta) { + node.previousNodeChanged(delta); + List children= node.fChildren; + int size= children != null ? children.size() : 0; + for (int i= 0; i < size; i++) { + updateUndo((TextEditNode)children.get(i), delta); + } + } + } + + //---- Creating instances --------------------------------------------------------------------------- + + static TextEditNode create(TextEdit edit) { + if (edit instanceof MoveTextEdit) + return new MoveNode(edit); + if (edit instanceof MoveTextEdit.TargetMark) + return new TargetMarkNode(edit); + return new DefaultNode(edit); + } + + static RootNode createRoot(int length) { + return new RootNode(length); + } + + private TextEditNode(TextEdit edit) { + fEdit= edit; + } + + //---- Adding children --------------------------------------------------------------------------- + + protected void add(TextEditNode node) { + if (fChildren == null) { + fChildren= new ArrayList(1); + node.fParent= this; + fChildren.add(node); + return; + } + // Optimize using binary search + for (Iterator iter= fChildren.iterator(); iter.hasNext();) { + TextEditNode child= (TextEditNode)iter.next(); + if (child.covers(node)) { + child.add(node); + return; + } + } + for (int i= 0; i < fChildren.size(); ) { + TextEditNode child= (TextEditNode)fChildren.get(i); + if (node.covers(child)) { + fChildren.remove(i); + node.add(child); + } else { + i++; + } + } + node.fParent= this; + fChildren.add(node); + } + + public boolean covers(TextEditNode node) { + return false; + } + + //---- Accessing -------------------------------------------------------------------------------------- + + protected RootNode getRoot() { + TextEditNode candidate= this; + while(candidate.fParent != null) + candidate= candidate.fParent; + return (RootNode)candidate; + } + + //---- Query interface -------------------------------------------------------------------------------- + + protected boolean isSynthetic() { + return fEdit.isSynthetic; + } + + public boolean isMove() { + return false; + } + + //---- Accessing Ranges ------------------------------------------------------------------------------ + + protected void checkRange(DocumentEvent event) { + TextRange range= getTextRange(); + int eventOffset= event.getOffset(); + int eventLength= event.getLength(); + int eventEnd = eventOffset + eventLength - 1; + // "Edit changes text that lies outside its defined range" + // Assert.isTrue(range.fOffset <= eventOffset && eventEnd <= range.getInclusiveEnd()); + } + + protected TextRange getTextRange() { + return fEdit.getTextRange(); + } + + protected TextRange getChildRange() { + return getTextRange(); + } + + protected TextRange getParentRange() { + return getTextRange(); + } + + public boolean validate(int bufferLength) { + if (fChildren == null) + return true; + // Only Moves and Nops can be parents + if (!(fEdit instanceof MoveTextEdit || fEdit instanceof NopTextEdit)) + return false; + TextRange lastRange= null; + for (Iterator iter= fChildren.iterator(); iter.hasNext(); ) { + TextEditNode node= (TextEditNode)iter.next(); + if (!node.validate(bufferLength)) + return false; + TextRange range= node.fEdit.getTextRange(); + if (!range.isValid() || range.fOffset + range.fLength > bufferLength) + return false; + if (lastRange != null && !(range.isInsertionPointAt(lastRange.fOffset) || range.liesBehind(lastRange))) + return false; + lastRange= range; + } + return true; + } + + //---- Updating ---------------------------------------------------------------------------------------- + + protected boolean activeNodeChanged(int delta) { + TextRange range= getTextRange(); + range.fLength+= delta; + // we didn't adjust any processed nodes. + return false; + } + + protected void previousNodeChanged(int delta) { + TextRange range= getTextRange(); + range.fOffset+= delta; + } + + protected void childNodeChanged(int delta) { + getTextRange().fLength+= delta; + } + + //---- Do it --------------------------------------------------------------------------------------------- + + protected void performDo(TextBuffer buffer, RangeUpdater updater, UndoMemento undo, IProgressMonitor pm) throws CoreException { + int size= fChildren != null ? fChildren.size() : 0; + for (int i= size - 1; i >= 0; i--) { + TextEditNode child= (TextEditNode)fChildren.get(i); + child.performDo(buffer, updater, undo, pm); + } + updater.setActiveNode(this); + if (isSynthetic()) + fEdit.perform(buffer); + else + undo.add(fEdit.perform(buffer)); + pm.worked(1); + } + + public void performedDo() { + int size= fChildren != null ? fChildren.size() : 0; + for (int i= size - 1; i >= 0; i--) { + TextEditNode child= (TextEditNode)fChildren.get(i); + child.performedDo(); + } + fEdit.performed(); + } + + //---- Undo it ------------------------------------------------------------------------------------------- + + protected void performUndo(TextBuffer buffer, RangeUpdater updater, UndoMemento undo, IProgressMonitor pm) throws CoreException { + int size= fChildren != null ? fChildren.size() : 0; + for (int i= 0; i < size; i++) { + setUndoIndex(i); + TextEditNode child= (TextEditNode)fChildren.get(i); + child.performUndo(buffer, updater, undo, pm); + } + updater.setActiveNode(this); + if (isSynthetic()) + fEdit.perform(buffer); + else + undo.add(fEdit.perform(buffer)); + pm.worked(1); + } + + protected void setUndoIndex(int index) { + } + + public void performedUndo() { + int size= fChildren != null ? fChildren.size() : 0; + for (int i= 0; i < size; i++) { + TextEditNode child= (TextEditNode)fChildren.get(i); + child.performedUndo(); + } + fEdit.performed(); + } + +// protected void createUndoList(List list) { +// int size= fChildren != null ? fChildren.size() : 0; +// for (int i= 0; i < size; i++) { +// TextEditNode child= (TextEditNode)fChildren.get(i); +// child.createUndoList(list); +// } +// list.add(this); +// } +} + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextEditNodeComparator.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextEditNodeComparator.java new file mode 100644 index 0000000..849078e --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextEditNodeComparator.java @@ -0,0 +1,48 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.textmanipulation; + +import java.util.Comparator; + + +/** + * A special comparator to comapre TextRanges. + */ +/* package */ class TextEditNodeComparator implements Comparator { + public int compare(Object o1, Object o2) { + TextEditNode node1= (TextEditNode)o1; + TextEditNode node2= (TextEditNode)o2; + TextRange pos1= node1.getTextRange(); + TextRange pos2= node2.getTextRange(); + + int offset1= pos1.fOffset; + int offset2= pos2.fOffset; + if (offset1 < offset2) + return -1; + if (offset1 > offset2) + return 1; + + // same offset + int length1= pos1.fLength; + int length2= pos2.fLength; + + // insertion points come before anything else at the same position. + if (length1 == 0 && length2 != 0) + return -1; + if (length1 != 0 && length2 == 0) + return 1; + + // Longer edits come before shorter edits + if (length1 < length2) + return 1; + if (length1 > length2) + return -1; + + if (node1.fEdit.index < node2.fEdit.index) + return -1; + return 1; + } +} + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextManipulationMessages.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextManipulationMessages.java new file mode 100644 index 0000000..eb8b44a --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextManipulationMessages.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2002 International Business Machines Corp. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Corporation - initial API and implementation + ******************************************************************************/ +package net.sourceforge.phpdt.internal.corext.textmanipulation; + +import java.text.MessageFormat; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class TextManipulationMessages { + + private static final String BUNDLE_NAME= "org.eclipse.jdt.internal.corext.textmanipulation.Messages"; //$NON-NLS-1$ + + private static final ResourceBundle RESOURCE_BUNDLE= ResourceBundle.getBundle(BUNDLE_NAME); + + private TextManipulationMessages() { + } + + public static String getString(String key) { + try { + return RESOURCE_BUNDLE.getString(key); + } catch (MissingResourceException e) { + return '!' + key + '!'; + } + } + + public static String getFormattedString(String key, Object arg) { + return getFormattedString(key, new Object[] { arg }); + } + + public static String getFormattedString(String key, Object[] args) { + return MessageFormat.format(getString(key), args); + } +} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextRange.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextRange.java new file mode 100644 index 0000000..d92fba2 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextRange.java @@ -0,0 +1,195 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.textmanipulation; + +//import org.eclipse.jdt.core.ISourceRange; +// +//import org.eclipse.jdt.internal.corext.Assert; + +public final class TextRange { + + /* package */ int fOffset; + /* package */ int fLength; + + public static final TextRange UNDEFINED= new TextRange((TextRange)null); + + /** + * Creates a insert position with the given offset. + * + * @param offset the position offset, must be >= 0 + */ + public TextRange(int offset) { + this(offset, 0); + } + + /** + * Creates a new range with the given offset and length. + * + * @param offset the position offset, must be >= 0 + * @param length the position length, must be >= 0 + */ + public TextRange(int offset, int length) { + fOffset= offset; +// Assert.isTrue(fOffset >= 0); + fLength= length; +// Assert.isTrue(fLength >= 0); + } + + /** + * Constructor for the undefined text range. + */ + private TextRange(TextRange dummy) { + fOffset= -1; + fLength= -1; + } + + public static TextRange createFromStartAndLength(int start, int length) { + return new TextRange(start, length); + } + + public static TextRange createFromStartAndInclusiveEnd(int start, int end) { + return new TextRange(start, end - start + 1); + } + + public static TextRange createFromStartAndExclusiveEnd(int start, int end) { + return new TextRange(start, end - start); + } + + /** + * Creates a new range from the given source range. + * + * @range the source range denoting offset and length + */ +// public TextRange(ISourceRange range) { +// this(range.getOffset(), range.getLength()); +// } + + /** + * Returns the offset of this range. + * + * @return the length of this range + */ + public int getOffset() { + return fOffset; + } + + /** + * Returns the length of this range. + * + * @return the length of this range + */ + public int getLength() { + return fLength; + } + + /** + * Returns the inclusive end position of this range. That means that the end position + * denotes the last character of this range. + * + * @return the inclusive end position + */ + public int getInclusiveEnd() { + return fOffset + fLength - 1; + } + + /** + * Returns the exclusive end position of this range. That means that the end position + * denotes the first character after this range. + * + * @return the exclusive end position + */ + public int getExclusiveEnd() { + return fOffset + fLength; + } + + /** + * Creates a copy of this TextRange. + * + * @return a copy of this TextRange + */ + public TextRange copy() { + if (isUndefined()) + return this; + return new TextRange(fOffset, fLength); + } + + /** + * Returns true if this text range is the UNDEFINED + * text range. Otherwise false is returned. + */ + public boolean isUndefined() { + return UNDEFINED == this; + } + + /** + * Checks if this TextRange is valid. For valid text range the following + * expression evaluates to true: + *

+	 * 	getOffset() >= 0 && getLength() >= 0
+	 * 
+ * + * @return true if this text range is a valid range. Otherwise + * false + */ + public boolean isValid() { + return fOffset >= 0 && fLength >= 0; + } + + /* package */ boolean isInsertionPoint() { + return fLength == 0; + } + + /* package */ boolean equals(TextRange range) { + return fOffset == range.fOffset && fLength == range.fLength; + } + + /* package */ boolean isEqualInsertionPoint(TextRange range) { + return fLength == 0 && range.fLength == 0 && fOffset == range.fOffset; + } + + /* package */ boolean liesBehind(TextRange range) { + return fOffset >= range.fOffset + range.fLength; + } + + /* package */ boolean isInsertionPointAt(int o) { + return fOffset == o && fLength == 0; + } + + /* package */ boolean covers(TextRange other) { + if (fLength == 0) { // an insertion point can't cover anything + return false; + } else if (other.fLength == 0) { + int otherOffset= other.fOffset; + return fOffset < otherOffset && otherOffset < fOffset + fLength; + } else { + int otherOffset= other.fOffset; + return fOffset <= otherOffset && otherOffset + other.fLength <= fOffset + fLength; + } + } + /* non Java-doc + * @see Object#toString() + */ + public String toString() { + StringBuffer buffer= new StringBuffer(); + buffer.append(TextManipulationMessages.getString("TextRange.offset")); //$NON-NLS-1$ + buffer.append(fOffset); + buffer.append(TextManipulationMessages.getString("TextRange.length")); //$NON-NLS-1$ + buffer.append(fLength); + return buffer.toString(); + } + + public boolean equals(Object obj) { + if (! (obj instanceof TextRange)) + return false; + TextRange other= (TextRange)obj; + return fOffset == other.getOffset() && fLength == other.getLength(); + } + + public int hashCode() { + return fOffset ^ fLength; + } + +} + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextRegion.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextRegion.java new file mode 100644 index 0000000..69919c6 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextRegion.java @@ -0,0 +1,37 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.textmanipulation; + + +/** + * A text region describes a certain range in an ITextBuffer. A region is defined by + * its offset into the text buffer and its length. + *

+ * A region is considered a value object. Its offset or length do not change over time.

+ *

+ * NOTE: This class/interface is part of an interim API that is still under development + * and expected to change significantly before reaching stability. It is being made available at + * this early stage to solicit feedback from pioneering adopters on the understanding that any + * code that uses this API will almost certainly be broken (repeatedly) as the API evolves.

+ */ + +// This class avoids contamination of clients with wrong imports. + +public abstract class TextRegion { + + /** + * Returns the offset of the region. + * + * @return the offset of the region + */ + public abstract int getOffset(); + /** + * Returns the length of the region. + * + * @return the length of the region + */ + public abstract int getLength(); + +} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/UndoMemento.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/UndoMemento.java new file mode 100644 index 0000000..028b267 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/UndoMemento.java @@ -0,0 +1,31 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.textmanipulation; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; + +/** + * This class encapsulates the reverse change of a number of TextEdits + * executed on a TextBufferEditor + */ +public final class UndoMemento { + + /* package */ int fMode; + /* package */ List fEdits; + + /* package */ UndoMemento(int mode) { + fMode= mode; + fEdits= new ArrayList(10); + } + + /* package */ void add(TextEdit edit) { + fEdits.add(edit); + } +} + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/util/IOCloser.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/util/IOCloser.java new file mode 100644 index 0000000..6ed53f7 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/util/IOCloser.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2002 International Business Machines Corp. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Corporation - initial API and implementation + ******************************************************************************/ +package net.sourceforge.phpdt.internal.corext.util; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; + +import net.sourceforge.phpeclipse.PHPeclipsePlugin; + +//import org.eclipse.jdt.internal.ui.JavaPlugin; + +public class IOCloser { + public static void perform(Reader reader, InputStream stream) { + try { + rethrows(reader, stream); + } catch (IOException e) { + PHPeclipsePlugin.log(e); + } + } + + public static void rethrows(Reader reader, InputStream stream) throws IOException { + if (reader != null) { + reader.close(); + return; + } + if (stream != null) { + stream.close(); + return; + } + } +} + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/util/Strings.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/util/Strings.java new file mode 100644 index 0000000..ab80732 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/util/Strings.java @@ -0,0 +1,260 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.corext.util; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.DefaultLineTracker; +import org.eclipse.jface.text.ILineTracker; +import org.eclipse.jface.text.IRegion; + +//import org.eclipse.jdt.internal.corext.Assert; + +/** + * Helper class to provide String manipulation functions not available in standard JDK. + */ +public class Strings { + + public static String removeNewLine(String message) { + StringBuffer result= new StringBuffer(); + int current= 0; + int index= message.indexOf('\n', 0); + while (index != -1) { + result.append(message.substring(current, index)); + if (current < index && index != 0) + result.append(' '); + current= index + 1; + index= message.indexOf('\n', current); + } + result.append(message.substring(current)); + return result.toString(); + } + + /** + * Converts the given string into an array of lines. The lines + * don't contain any line delimiter characters. + * + * @return the string converted into an array of strings. Returns + * null if the input string can't be converted in an array of lines. + */ + public static String[] convertIntoLines(String input) { + try { + ILineTracker tracker= new DefaultLineTracker(); + tracker.set(input); + int size= tracker.getNumberOfLines(); + String result[]= new String[size]; + for (int i= 0; i < size; i++) { + IRegion region= tracker.getLineInformation(i); + int offset= region.getOffset(); + result[i]= input.substring(offset, offset + region.getLength()); + } + return result; + } catch (BadLocationException e) { + return null; + } + } + + /** + * Returns true if the given string only consists of + * white spaces according to Java. If the string is empty, true + * is returned. + * + * @return true if the string only consists of white + * spaces; otherwise false is returned + * + * @see java.lang.Character#isWhitespace(char) + */ + public static boolean containsOnlyWhitespaces(String s) { + int size= s.length(); + for (int i= 0; i < size; i++) { + if (!Character.isWhitespace(s.charAt(i))) + return false; + } + return true; + } + + /** + * Removes leading tabs and spaces from the given string. If the string + * doesn't contain any leading tabs or spaces then the string itself is + * returned. + */ + public static String trimLeadingTabsAndSpaces(String line) { + int size= line.length(); + int start= size; + for (int i= 0; i < size; i++) { + char c= line.charAt(i); + if (c != '\t' && !Character.isSpaceChar(c)) { + start= i; + break; + } + } + if (start == 0) + return line; + else if (start == size) + return ""; //$NON-NLS-1$ + else + return line.substring(start); + } + + public static String trimTrailingTabsAndSpaces(String line) { + int size= line.length(); + int end= size; + for (int i= size - 1; i >= 0; i--) { + char c= line.charAt(i); + if (c == '\t' || Character.isSpaceChar(c)) { + end= i; + } else { + break; + } + } + if (end == size) + return line; + else if (end == 0) + return ""; //$NON-NLS-1$ + else + return line.substring(0, end); + } + + /** + * Returns the indent of the given string. + * + * @param line the text line + * @param tabWidth the width of the '\t' character. + */ + public static int computeIndent(String line, int tabWidth) { + int result= 0; + int blanks= 0; + int size= line.length(); + for (int i= 0; i < size; i++) { + char c= line.charAt(i); + if (c == '\t') { + result++; + blanks= 0; + } else if (Character.isSpaceChar(c)) { + blanks++; + if (blanks == tabWidth) { + result++; + blanks= 0; + } + } else { + return result; + } + } + return result; + } + + /** + * Removes the given number of idents from the line. Asserts that the given line + * has the requested number of indents. If indentsToRemove <= 0 + * the line is returned. + */ + public static String trimIndent(String line, int indentsToRemove, int tabWidth) { + if (line == null || indentsToRemove <= 0) + return line; + + int start= 0; + int indents= 0; + int blanks= 0; + int size= line.length(); + for (int i= 0; i < size; i++) { + char c= line.charAt(i); + if (c == '\t') { + indents++; + blanks= 0; + } else if (Character.isSpaceChar(c)) { + blanks++; + if (blanks == tabWidth) { + indents++; + blanks= 0; + } + } else { +// Assert.isTrue(false, "Line does not have requested number of indents"); //$NON-NLS-1$ + } + if (indents == indentsToRemove) { + start= i + 1; + break; + } + } + if (start == size) + return ""; //$NON-NLS-1$ + else + return line.substring(start); + } + + /** + * Removes all leading indents from the given line. If the line doesn't contain + * any indents the line itself is returned. + */ + public static String trimIndents(String s, int tabWidth) { + int indent= computeIndent(s, tabWidth); + if (indent == 0) + return s; + return trimIndent(s, indent, tabWidth); + } + + /** + * Removes the common number of indents from all lines. If a line + * only consists out of white space it is ignored. + */ + public static void trimIndentation(String[] lines, int tabWidth) { + String[] toDo= new String[lines.length]; + // find indentation common to all lines + int minIndent= Integer.MAX_VALUE; // very large + for (int i= 0; i < lines.length; i++) { + String line= lines[i]; + if (containsOnlyWhitespaces(line)) + continue; + toDo[i]= line; + int indent= computeIndent(line, tabWidth); + if (indent < minIndent) { + minIndent= indent; + } + } + + if (minIndent > 0) { + // remove this indent from all lines + for (int i= 0; i < toDo.length; i++) { + String s= toDo[i]; + if (s != null) + lines[i]= trimIndent(s, minIndent, tabWidth); + else { + String line= lines[i]; + int indent= computeIndent(line, tabWidth); + if (indent > minIndent) + lines[i]= trimIndent(line, minIndent, tabWidth); + else + lines[i]= trimLeadingTabsAndSpaces(line); + } + } + } + } + + public static String getIndentString(String line, int tabWidth) { + int size= line.length(); + int end= 0; + int blanks= 0; + for (int i= 0; i < size; i++) { + char c= line.charAt(i); + if (c == '\t') { + end= i; + blanks= 0; + } else if (Character.isSpaceChar(c)) { + blanks++; + if (blanks == tabWidth) { + end= i; + blanks= 0; + } + } else { + break; + } + } + if (end == 0) + return ""; //$NON-NLS-1$ + else if (end == size) + return line; + else + return line.substring(0, end + 1); + } +} + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaStatusConstants.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaStatusConstants.java new file mode 100644 index 0000000..338afd6 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaStatusConstants.java @@ -0,0 +1,28 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.ui; + +/** + * Defines status codes relevant to the Java UI plug-in. When a + * Core exception is thrown, it contain a status object describing + * the cause of the exception. The status objects originating from the + * Java UI plug-in use the codes defined in this interface. + */ +public class JavaStatusConstants { + + // Prevent instantiation + private JavaStatusConstants() { + } + + /** Status code describing an internal error */ + public static final int INTERNAL_ERROR= 1; + + /** + * Status constant indicating that an exception occured on + * storing or loading templates. + */ + public static final int TEMPLATE_IO_EXCEPTION = 2; + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaUIException.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaUIException.java new file mode 100644 index 0000000..20fc671 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaUIException.java @@ -0,0 +1,21 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.ui; + + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; + +/** + * An exception to wrap a status. This is necessary to use the core's IRunnableWithProgress + * support + */ + +public class JavaUIException extends CoreException { + + public JavaUIException(IStatus status) { + super(status); + } +} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaUIMessages.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaUIMessages.java new file mode 100644 index 0000000..aee11a9 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaUIMessages.java @@ -0,0 +1,36 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.ui; + +import java.text.MessageFormat; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class JavaUIMessages { + + private static final String RESOURCE_BUNDLE= "org.eclipse.jdt.internal.ui.JavaUIMessages";//$NON-NLS-1$ + + private static ResourceBundle fgResourceBundle= ResourceBundle.getBundle(RESOURCE_BUNDLE); + + private JavaUIMessages() { + } + + public static String getString(String key) { + try { + return fgResourceBundle.getString(key); + } catch (MissingResourceException e) { + return '!' + key + '!'; + } + } + + public static String getFormattedString(String key, String arg) { + return getFormattedString(key, new String[] { arg }); + } + + public static String getFormattedString(String key, String[] args) { + return MessageFormat.format(getString(key), args); + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaUIMessages.properties b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaUIMessages.properties new file mode 100644 index 0000000..c6bf376 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaUIMessages.properties @@ -0,0 +1,542 @@ +######### +## jdt.internal.ui +######### + +JavaPlugin.internal_error=Internal Error +JavaElementProperties.name=Name + +######### +## actions +######### +AddWatchpointAction.errorTitle=Error Adding Watchpoint + +AddGetterSetterAction.label=&Create Getter and Setter +AddGetterSetterAction.description=Create getter and setter methods for the field +AddGetterSetterAction.tooltip=Create Getter and Setter Methods for the Field + +AddGetterSetterAction.error.title=Generate Getter and Setter +AddGetterSetterAction.error.actionfailed=Generate Getter and Setter Failed. +AddGetterSetterAction.error.fieldNotExisting=The field ''{0}'' has been removed in the editor. + +AddGetterSetterAction.QueryDialog.title=Generate Getter and Setter +AddGetterSetterAction.SkipSetterForFinalDialog.message=Field ''{0}'' is final.\nOK to only create getter? +AddGetterSetterAction.SkipExistingDialog.message=Method ''{0}'' already exists.\nSkip creation? +AddGetterSetterAction.SkipExistingDialog.skip.label=&Skip +AddGetterSetterAction.SkipExistingDialog.replace.label=&Replace +AddGetterSetterAction.SkipExistingDialog.skipAll.label=Skip &All + +AddMethodStubAction.label=Create Method +AddMethodStubAction.detailed.implement=&Implement in ''{0}'' +AddMethodStubAction.detailed.override=&Override in ''{0}'' +AddMethodStubAction.description=Add method stub to type +AddMethodStubAction.tooltip=Add Method Stub to Type + +AddMethodStubAction.error.title=Add Method Stub Failed +AddMethodStubAction.error.type_removed_in_editor=Input type has been removed in editor + +AddMethodStubAction.QueryDialog.title=Create Method Stub +AddMethodStubAction.OverridesFinalDialog.message=This will override the final method ''{0}'' from ''{1}''\nOK to continue? +AddMethodStubAction.OverridesPrivateDialog.message=This will override the private method ''{0}'' from ''{1}''\nOK to continue? +AddMethodStubAction.ReplaceExistingDialog.message=This will replace the existing method ''{0}''.\nOK to continue? + +AddJavaDocStubAction.label=Add &Javadoc Comment +AddJavaDocStubAction.description=Add a Javadoc comment stub to the member element +AddJavaDocStubAction.tooltip=Add a Javadoc comment stub to the member element + +AddJavaDocStubsAction.error.dialogTitle=Add Javadoc Comment +AddJavaDocStubsAction.error.noWorkingCopy=Could not find working copy. +AddJavaDocStubsAction.error.memberNotExisting=Member has been removed in editor. +AddJavaDocStubsAction.error.actionFailed=Error while adding Javadoc comment + +AddUnimplementedMethodsAction.label=&Override Methods... +AddUnimplementedMethodsAction.description=Override Methods from super types. +AddUnimplementedMethodsAction.tooltip=Override Methods + +AddUnimplementedMethodsAction.error.title=Override Methods +AddUnimplementedMethodsAction.error.nothing_found=No methods to override found for this type. +AddUnimplementedMethodsAction.error.type_removed_in_editor=Input type has been removed in editor. + +AddUnimplementedConstructorsAction.label=Add &Constructors from Superclass +AddUnimplementedConstructorsAction.description=Evaluate and add constructors from superclass +AddUnimplementedConstructorsAction.tooltip=Add Constructors from Superclass + +AddUnimplementedConstructorsAction.error.title=Add Constructors from Superclass +AddUnimplementedConstructorsAction.error.nothing_found=No unimplemented constructors found. +AddUnimplementedConstructorsAction.error.type_removed_in_editor=Input type has been removed in editor. + +OpenHierarchyPerspectiveItem.menulabel=Open Type &Hierarchy + +OpenImportDeclarationAction.errorMessage=Cannot open resource +OpenImportDeclarationAction.errorTitle=Error On Open +OpenImportDeclarationAction.label=&Open +OpenImportDeclarationAction.description=Open the selected element in the editor\t +OpenImportDeclarationAction.tooltip=Open the Selected Element in the Editor + +OpenJavaElementAction.description=Open the selected element +OpenJavaElementAction.tooltip=Open the Selected Element +OpenJavaElementAction.errorMessage=Cannot open element: +OpenJavaElementAction.errorTitle=Problems while Opening Element +OpenJavaElementAction.label=&Open + +OpenTypeAction.description=Open a type in the editor +OpenTypeAction.tooltip=Open a Type +OpenTypeAction.dialogMessage=&Choose a type (? = any character, * = any string): +OpenTypeAction.dialogTitle=Open Type +OpenTypeAction.errorMessage=An exception occurred while opening the type. +OpenTypeAction.errorTitle=Open Type +OpenTypeAction.label=Open Type...@Ctrl+Shift+T + +OpenSuperImplementationAction.label=Open S&uper Implementation +OpenSuperImplementationAction.description=Open the Implementation in the Super Type +OpenSuperImplementationAction.tooltip=Open the Implementation in the Super Type +OpenSuperImplementationAction.error.title=Open Super Implementation +OpenSuperImplementationAction.error.message=Opening failed. Check log for details. + +ShowInPackageViewAction.label=Show in &Package Explorer +ShowInPackageViewAction.description=Show the selected element in Package Explorer +ShowInPackageViewAction.tooltip=Show in Package Explorer +ShowInPackageViewAction.error.title=Show In Package Explorer +ShowInPackageViewAction.error.message=Internal error. Please see log for details. + +ShowTypeHierarchyAction.label=&Show in Type Hierarchy +ShowTypeHierarchyAction.tooltip=Show in Type Hierarchy +ShowTypeHierarchyAction.description=Show the type hierarchy of the selected type + +ShowTypeHierarchyAction.selectiondialog.title=Show In Type Hierarchy +ShowTypeHierarchyAction.selectiondialog.message=&Select the type to be shown in the Type Hierarchy view: + +ShowTypeHierarchyAction.error.title=Problems Opening Type Hierarchy + + +####### +## dialogs +####### + +ElementTreeSelectionDialog.nothing_available=No entries available. + +CheckedTreeSelectionDialog.nothing_available=No entries available. +CheckedTreeSelectionDialog.select_all=Select &All +CheckedTreeSelectionDialog.deselect_all=&Deselect All + +MultiElementListSelectionDialog.pageInfoMessage=Page {0} of {1} + +MultiTypeSelectionDialog.dialogMessage=Could not uniquely map the type name to a type. +MultiTypeSelectionDialog.dialogTitle=Select Type +MultiTypeSelectionDialog.errorMessage=Could not uniquely map the type name to a type. +MultiTypeSelectionDialog.errorTitle=Select Type +MultiTypeSelectionDialog.error2Message=Unexpected exception. See log for details. +MultiTypeSelectionDialog.error2Title=Exception + +TypeSelectionDialog.errorMessage=Could not uniquely map the type name to a type. +TypeSelectionDialog.errorTitle=Select Type +TypeSelectionDialog.lowerLabel=&Qualifier: +TypeSelectionDialog.upperLabel=&Matching types: +TypeSelectionDialog.notypes.title=Type Selection +TypeSelectionDialog.notypes.message=No types available. +TypeSelectionDialog.error2Message=Unexpected exception. See log for details. +TypeSelectionDialog.error2Title=Exception +TypeSelectionDialog.error3Message=Unexpected exception. See log for details. +TypeSelectionDialog.error3Title=Exception + +ExceptionDialog.seeErrorLogMessage= See error log for more details. + +MainTypeSelectionDialog.errorTitle=Error +MultiMainTypeSelectionDialog.errorTitle=Error + +###### +## dnd +###### +LocalSelectionTransfer.errorMessage=Received wrong transfer data. + +########### +## preferences +########### +BuildPathsPropertyPage.error.message=An error occurred while setting the build path +BuildPathsPropertyPage.error.title=Error Setting Build Path +BuildPathsPropertyPage.no_java_project.message=Not a Java project. +BuildPathsPropertyPage.closed_project.message=Java information is not available for a closed project. + +ClasspathVariablesPreferencePage.description=A classpath variable can be added to a project's class path. It can be used to define the location of a JAR file that isn't part of the workspace. The reserved class path variables JRE_LIB, JRE_SRC, JRE_SRCROOT are set internally depending on the JRE setting. + +ImportOrganizePreferencePage.description=Preferences used by the Organize Imports action: + +ImportOrganizePreferencePage.order.label=Define the &sorting order of import statements. A package name prefix (e.g. org.eclipse) is a valid entry. + +ImportOrganizePreferencePage.order.add.button=&New.. +ImportOrganizePreferencePage.order.edit.button=&Edit... +ImportOrganizePreferencePage.order.up.button=&Up +ImportOrganizePreferencePage.order.down.button=Do&wn +ImportOrganizePreferencePage.order.remove.button=&Remove +ImportOrganizePreferencePage.order.load.button=&Load... +ImportOrganizePreferencePage.order.save.button=Sa&ve... +ImportOrganizePreferencePage.ignoreLowerCase.label=Do not create imports for &types starting with a lowercase letter + +ImportOrganizePreferencePage.threshold.label=Number of &qualified imports before .* is used (e.g. org.eclipse.*): +ImportOrganizePreferencePage.error.invalidthreshold=Invalid import number. + +ImportOrganizePreferencePage.loadDialog.title=Load Import Order from File +ImportOrganizePreferencePage.loadDialog.error.title=Load Import Order +ImportOrganizePreferencePage.loadDialog.error.message=Loading failed. Not a valid import order file. + +ImportOrganizePreferencePage.saveDialog.title=Save Import Order to File +ImportOrganizePreferencePage.saveDialog.error.title=Save Import Order +ImportOrganizePreferencePage.saveDialog.error.message=Writing import order file failed. + + +ImportOrganizeInputDialog.title=Import Order Entry +ImportOrganizeInputDialog.message=&Package name or package name prefix: +ImportOrganizeInputDialog.browse.button=&Browse... +ImportOrganizeInputDialog.ChoosePackageDialog.title=Package Selection +ImportOrganizeInputDialog.ChoosePackageDialog.description=Choose package name or package prefix: +ImportOrganizeInputDialog.ChoosePackageDialog.empty=No packages available. +ImportOrganizeInputDialog.error.enterName=Enter a package name. +ImportOrganizeInputDialog.error.invalidName=Not a valid package name. {0} +ImportOrganizeInputDialog.error.entryExists=Package name already exists in list. + +JavaBasePreferencePage.description=General settings for Java development: + +JavaBasePreferencePage.linkPackageView= L&ink Package Explorer selection to active editor +JavaBasePreferencePage.dblClick=A&ction on double-clicking in Package Explorer on container is 'Go Into' +JavaBasePreferencePage.cuChildren=S&how members in Package Explorer + +JavaBasePreferencePage.updateJavaViews=Update Java views: +JavaBasePreferencePage.onSave=On &save only +JavaBasePreferencePage.whileEditing=While &editing +JavaBasePreferencePage.notice.outliner=Note: This preference is not applied to already opened views (Outline view is always updated while editing) + +JavaBasePreferencePage.typeHierarchySettings=Type Hierarchy settings +JavaBasePreferencePage.linkTypeHierarchy=Lin&k Type Hierarchy view selection to active editor +JavaBasePreferencePage.openTypeHierarchy=When opening a Type Hierarchy: +JavaBasePreferencePage.inPerspective=Open a new Type Hierarchy &Perspective +JavaBasePreferencePage.inView=Show the &Type Hierarchy View in the current perspective +JavaBasePreferencePage.doubleclick.action=Action on double click in the Package Explorer: +JavaBasePreferencePage.doubleclick.gointo=&Go into the selected element +JavaBasePreferencePage.doubleclick.expand=E&xpand the selected element + +JavaBasePreferencePage.linkSettings.text=Link settings: +JavaBasePreferencePage.linkJavaBrowsingViewsCheckbox.text=&Link Java Browsing views selection to active editor + + +NewJavaProjectPreferencePage.description=Specify the classpath entries used as default by the New Java Project creation wizard: + +NewJavaProjectPreferencePage.sourcefolder.label=As source and output location use: +NewJavaProjectPreferencePage.sourcefolder.project=&Project +NewJavaProjectPreferencePage.sourcefolder.folder=&Folders +NewJavaProjectPreferencePage.folders.src=&Source folder name: +NewJavaProjectPreferencePage.folders.bin=&Output location name: + +NewJavaProjectPreferencePage.jrelibrary.label=As &JRE library use: +NewJavaProjectPreferencePage.jre_variable.description=JRE_LIB variable +NewJavaProjectPreferencePage.jre_container.description=JRE container + +NewJavaProjectPreferencePage.folders.error.namesempty=Enter folder names. +NewJavaProjectPreferencePage.folders.error.invalidsrcname=Invalid source folder name: {0} +NewJavaProjectPreferencePage.folders.error.invalidbinname=Invalid output folder name: {0} + +NewJavaProjectPreferencePage.error.decode=Error while decoding JRE entry + +JavaEditorPreferencePage.updatesOnNextChangeIinEditor.label=Note: Updates on next change in the editor +JavaEditorPreferencePage.problemIndicationTab.title=Problem Indi&cation + +JavaEditorPreferencePage.description=Java Editor settings: +JavaEditorPreferencePage.font=Text Font: +JavaEditorPreferencePage.multiLineComment=Multi-line comment +JavaEditorPreferencePage.singleLineComment=Single-line comment +JavaEditorPreferencePage.keywords=Keywords +JavaEditorPreferencePage.strings=Strings +JavaEditorPreferencePage.others=Others +JavaEditorPreferencePage.javaDocKeywords=Javadoc keywords +JavaEditorPreferencePage.javaDocHtmlTags=Javadoc HTML tags +JavaEditorPreferencePage.javaDocLinks=Javadoc links +JavaEditorPreferencePage.javaDocOthers=Javadoc others +JavaEditorPreferencePage.backgroundColor=Background color +JavaEditorPreferencePage.systemDefault=S&ystem Default +JavaEditorPreferencePage.custom=C&ustom: +JavaEditorPreferencePage.foreground=Fo®round: +JavaEditorPreferencePage.color=C&olor: +JavaEditorPreferencePage.bold=&Bold +JavaEditorPreferencePage.preview=Preview: +JavaEditorPreferencePage.textFont=Text &font: +JavaEditorPreferencePage.displayedTabWidth=Displayed &tab width: +JavaEditorPreferencePage.insertSpaceForTabs=&Insert space for tabs (see Formatting preferences) +JavaEditorPreferencePage.showProblemsBeforeCompiling=Show problems before c&ompiling +JavaEditorPreferencePage.showOverviewRuler=Show overview &ruler +JavaEditorPreferencePage.highlightMatchingBrackets=Highlight &matching brackets +JavaEditorPreferencePage.matchingBracketsHighlightColor=Matching &brackets highlight color: +JavaEditorPreferencePage.highlightCurrentLine=Hi&ghlight current line +JavaEditorPreferencePage.currentLineHighlightColor=Current &line highlight color: +JavaEditorPreferencePage.highlightProblems=Highlight &problems +JavaEditorPreferencePage.problemHighlightColor=Prob&lem highlight color: +JavaEditorPreferencePage.showPrintMargin=Sho&w print margin +JavaEditorPreferencePage.printMarginColor=Print m&argin color: +JavaEditorPreferencePage.printMarginColumn=Print margin col&umn: +JavaEditorPreferencePage.findScopeColor=F&ind Scope Color: +JavaEditorPreferencePage.linkedPositionColor=Lin&ked Position Color: +JavaEditorPreferencePage.insertSingleProposalsAutomatically=Insert single &proposals automatically +JavaEditorPreferencePage.showOnlyProposalsVisibleInTheInvocationContext=Show only proposals &visible in the invocation context +JavaEditorPreferencePage.presentProposalsInAlphabeticalOrder=Present proposals in a&lphabetical order +JavaEditorPreferencePage.enableAutoActivation=&Enable auto activation +JavaEditorPreferencePage.automaticallyAddImportInsteadOfQualifiedName=Automatically add &import instead of qualified name +JavaEditorPreferencePage.fillArgumentNamesOnMethodCompletion=&Fill argument names on method completion +JavaEditorPreferencePage.autoActivationDelay=Auto activation dela&y: +JavaEditorPreferencePage.autoActivationTriggersForJava=Auto activation &triggers for Java: +JavaEditorPreferencePage.autoActivationTriggersForJavaDoc=Auto activation triggers for &Javadoc: +JavaEditorPreferencePage.backgroundForCompletionProposals=&Background for completion proposals: +JavaEditorPreferencePage.foregroundForCompletionProposals=&Foreground for completion proposals: +JavaEditorPreferencePage.backgroundForMethodParameters=Bac&kground for method parameters: +JavaEditorPreferencePage.foregroundForMethodParameters=Fo®round for method parameters: +JavaEditorPreferencePage.general=Appeara&nce +JavaEditorPreferencePage.colors=Synta&x +JavaEditorPreferencePage.codeAssist=Code A&ssist +JavaEditorPreferencePage.change=C&hange... +JavaEditorPreferencePage.empty_input=Empty input +JavaEditorPreferencePage.invalid_input=''{0}'' is not a valid input. +JavaEditorPreferencePage.showLineNumbers=Show &line numbers +JavaEditorPreferencePage.lineNumberColor=Line number foreground color: +JavaEditorPreferencePage.lineNumberForegroundColor=Line number foreground +JavaEditorPreferencePage.matchingBracketsHighlightColor2=Matching brackets highlight +JavaEditorPreferencePage.currentLineHighlighColor=Current line highlight +JavaEditorPreferencePage.problemsHighlightColor=Problems highlight +JavaEditorPreferencePage.printMarginColor2=Print margin +JavaEditorPreferencePage.findScopeColor2=Find scope +JavaEditorPreferencePage.linkedPositionColor2=Linked position +JavaEditorPreferencePage.showQuickFixables=&Indicate problems solvable with Quick Fix in vertical ruler +JavaEditorPreferencePage.synchronizeOnCursor=Synchroni&ze outline selection on cursor move (editor must be reopened) +JavaEditorPreferencePage.appearanceOptions=Appearance co&lor options: + + +JavaElementInfoPage.binary=binary +JavaElementInfoPage.classpath_entry_kind=Classpath entry kind: +JavaElementInfoPage.library=library +JavaElementInfoPage.nameLabel=Name: +JavaElementInfoPage.not_present=not present +JavaElementInfoPage.package=Package: +JavaElementInfoPage.package_contents=Package contents: +JavaElementInfoPage.project=project +JavaElementInfoPage.resource_path=Resource path: +JavaElementInfoPage.source=source +JavaElementInfoPage.variable=variable +JavaElementInfoPage.variable_path=Variable path: +JavaElementInfoPage.location=Location: + +JavadocConfigurationPropertyPage.IsPackageFragmentRoot.description=Specify the location (URL) of the documentation generated by Javadoc. The Javadoc location will contain a file called 'package-list'. For example: \'http://www.sample-url.org/doc/\' +JavadocConfigurationPropertyPage.IsIncorrectElement.description=Javadoc location can only be attached to JAR files in projects or Java projects +JavadocConfigurationPropertyPage.IsJavaProject.description=Specify the location (URL) of the project\'s Javadoc documentation. This location is used by the Javadoc export wizard as default value and by the \'Open External Javadoc\' action. For example: \'file://c:/myworkspace/myproject/doc/\'. + +JavadocConfigurationBlock.location.label=Javadoc &Location: +JavadocConfigurationBlock.location.button=Bro&wse... + +JavadocConfigurationBlock.error.invalidurl=Not a valid URL: {0} +JavadocConfigurationBlock.error.notafolder=Location does not exist. +JavadocConfigurationBlock.warning.packagelistnotfound=Location does not contain file 'package-list'. + +JavadocConfigurationBlock.javadocLocationDialog.label=Javadoc Location Selection +JavadocConfigurationBlock.javadocLocationDialog.message=&Select Javadoc location: + +JavadocConfigurationBlock.MalformedURL.error=Invalid URL + +JavadocConfigurationBlock.ValidateButton.label=&Validate... +JavadocConfigurationBlock.InvalidLocation.message= Location is invalid. Location contains neither the file \'package-list\' nor \'index.html'. +JavadocConfigurationBlock.ValidLocation.message= Location is valid. Files \'package-list\' and \'index.html\' found. Click OK to open in browser. +JavadocConfigurationBlock.UnableToValidateLocation.message=Unable to validate location +JavadocConfigurationBlock.MessageDialog.title=Validating Javadoc Location +JavadocConfigurationBlock.EmptyJavadocLocation.warning=Enter a javadoc location + +JavadocPreferencePage.description=Specify the location of the Javadoc command to be used by the Javadoc export wizard. Location must be an absolute path. +JavadocPreferencePage.command.label=&Javadoc command: +JavadocPreferencePage.command.button=Bro&wse... + +JavadocPreferencePage.error.notexists=Javadoc command does not exist + +JavadocPreferencePage.browsedialog.title=Javadoc Command Selection + +SourceAttachmentPropertyPage.error.title=Error Attaching Source +SourceAttachmentPropertyPage.error.message=An error occurred while associating the source + +SourceAttachmentPropertyPage.noarchive.message=Source can only be attached to JAR files in Java projects. +SourceAttachmentPropertyPage.containerentry.message=JAR belongs to the container ''{0}''.\nTo configure the source attachment, go directly to the corresponding configuration page (For example for JREs go to ''Installed JREs'' page in the preferences). + +AppearancePreferencePage.description= Appearance of Java elements in viewers: +AppearancePreferencePage.methodreturntype.label= Show &method return types +AppearancePreferencePage.overrideindicator.label= Show &override indicators in outline and hierarchy +AppearancePreferencePage.pkgNamePatternEnable.label= &Compress package name segments (except for the last one) +AppearancePreferencePage.pkgNamePattern.label= Com&pression pattern (e.g. given package name 'org.eclipse.jdt' pattern '.' will compress it to '..jdt', '0' to 'jdt', '1~.' to 'o~.e~.jdt'): + +AppearancePreferencePage.showMembersInPackagesView=S&how members in Package Explorer +AppearancePreferencePage.stackViewsVerticallyInTheJavaBrowsingPerspective=&Stack views vertically in the Java Browsing perspective +AppearancePreferencePage.preferenceOnlyEffectiveForNewPerspectives=Note: This preference will only take effect on new perspectives +AppearancePreferencePage.packageNameCompressionPattern.error.isEmpty=Enter a package name compression pattern + +CodeFormatterPreferencePage.description=Options for the Java Code Formatter: + +CodeFormatterPreferencePage.empty_input=Empty input +CodeFormatterPreferencePage.invalid_input=''{0}'' is not a valid input. + +CodeFormatterPreferencePage.newline_opening_braces.label=I&nsert a new line before an opening brace +CodeFormatterPreferencePage.newline_control_statement.label=Insert new &lines in control statements +CodeFormatterPreferencePage.newline_clear_lines=Clear all &blank lines +CodeFormatterPreferencePage.newline_else_if.label=&Insert new line between 'else if' +CodeFormatterPreferencePage.newline_empty_block.label=In&sert a new line inside an empty block +CodeFormatterPreferencePage.split_line.label=Ma&ximum line length: +CodeFormatterPreferencePage.style_compact_assignement.label=&Compact assignment +CodeFormatterPreferencePage.tab_char.label=Indentation is represented by a &tab +CodeFormatterPreferencePage.tab_size.label=&Number of spaces representing a tab: + +CodeFormatterPreferencePage.tab.newline.tabtitle=Ne&w Lines +CodeFormatterPreferencePage.tab.linesplit.tabtitle=Line S&plitting +CodeFormatterPreferencePage.tab.style.tabtitle=St&yle + +CompilerPreferencePage.description=Options for the Java compiler:\nNote that a full rebuild is required to make changes effective. +CompilerPreferencePage.generation.tabtitle=Classfile &Generation +CompilerPreferencePage.warnings.tabtitle=&Errors and Warnings +CompilerPreferencePage.compliance.tabtitle=&JDK Compliance +CompilerPreferencePage.others.tabtitle=&Other + +CompilerPreferencePage.warnings.description=Select the severity level for the following problems: + +CompilerPreferencePage.variable_attr.label=Add &variable attributes to generated class files (used by the debugger) +CompilerPreferencePage.line_number_attr.label=Add &line number attributes to generated class files (used by the debugger) +CompilerPreferencePage.source_file_attr.label=Add &source file name to generated class file (used by the debugger) +CompilerPreferencePage.codegen_unused_local.label=Preserve &unused local variables (i.e. never read) + +CompilerPreferencePage.compiler_compliance.label=&Compiler compliance level: +CompilerPreferencePage.default_settings.label=&Use default compliance settings +CompilerPreferencePage.source_compatibility.label=&Source compatibility: +CompilerPreferencePage.codegen_targetplatform.label=Ge&nerated .class files compatibility: +CompilerPreferencePage.pb_assert_as_identifier.label=&Report 'assert' as identifier: + +CompilerPreferencePage.pb_unreachable_code.label=&Unreachable code: +CompilerPreferencePage.pb_invalid_import.label=Unresol&vable import statements: +CompilerPreferencePage.pb_overriding_pkg_dflt.label=&Methods overridden but not package visible: +CompilerPreferencePage.pb_method_naming.label=Me&thods with a constructor name: +CompilerPreferencePage.pb_deprecation.label=Usage of de&precated API: +CompilerPreferencePage.pb_hidden_catchblock.label=&Hidden catch blocks: +CompilerPreferencePage.pb_unused_imports.label=Unu&sed imports: +CompilerPreferencePage.pb_unused_local.label=Unused &local variables (i.e. never read): +CompilerPreferencePage.pb_unused_parameter.label=U&nused parameters (i.e. never read): +CompilerPreferencePage.pb_synth_access_emul.label=A&ccess to a non-accessible member of an enclosing type: +CompilerPreferencePage.pb_non_externalized_strings.label=Non-e&xternalized strings: +CompilerPreferencePage.pb_max_per_unit.label=Maximum number of problems &reported per compilation unit: + +CompilerPreferencePage.resource_filter.description=Enter resources and resource types that should not be copied to the output folder during a build. List is comma separated (e.g. '*.doc, plugin.xml, scripts/') +CompilerPreferencePage.resource_filter.label=Filtered &Resources: +CompilerPreferencePage.build_invalid_classpath.label=Stop &building when an invalid classpath is detected + +CompilerPreferencePage.error=Error +CompilerPreferencePage.warning=Warning +CompilerPreferencePage.ignore=Ignore + +CompilerPreferencePage.jvm11=JVM 1.1 +CompilerPreferencePage.jvm12=JVM 1.2 +CompilerPreferencePage.jvm13=JVM 1.3 +CompilerPreferencePage.jvm14=JVM 1.4 + +CompilerPreferencePage.version11=1.1 +CompilerPreferencePage.version12=1.2 +CompilerPreferencePage.version13=1.3 +CompilerPreferencePage.version14=1.4 + +CompilerPreferencePage.needsbuild.title=Compiler Settings Changed +CompilerPreferencePage.needsbuild.message=The compiler settings have changed. A full rebuild is required to make changes effective. Do the full build now? + +CompilerPreferencePage.builderror.title=Compiler Settings +CompilerPreferencePage.builderror.message=Problem while building. Check log for details. + +CompilerPreferencePage.cpl13src14.error=In 1.3 compliance level, source compatibility can not be 1.4 +CompilerPreferencePage.cpl13trg14.error=In 1.3 compliance level, the classfile compatibility can not be 1.4 +CompilerPreferencePage.src14asrterr.error=With 1.4 source compatibility, 'assert' can not be an identifier. +CompilerPreferencePage.src14tgt14.error=With 1.4 source compatibility, the classfile compatibility must be 1.4 + +CompilerPreferencePage.empty_input=Number of problems can not be empty. +CompilerPreferencePage.invalid_input={0} is not a valid number of problems. + +CompilerPreferencePage.filter.invalidsegment.error=Filter is invalid: {0} + +CodeGenerationPreferencePage.description=Options for Code Generation: + +CodeGenerationPreferencePage.gettersetter.label=Getter and Setter Creation: +CodeGenerationPreferencePage.gettersetter.prefix.checkbox=Remove &prefix from field names +CodeGenerationPreferencePage.gettersetter.prefix.list=P&refix list (comma separated): +CodeGenerationPreferencePage.gettersetter.suffix.checkbox=Remove &suffix from field names +CodeGenerationPreferencePage.gettersetter.suffix.list=S&uffix list (comma separated): + +CodeGenerationPreferencePage.comments.label=Comments Creation: +CodeGenerationPreferencePage.javadoc_comment.label=Create &Javadoc comments for methods and types (template 'typecomment') +CodeGenerationPreferencePage.see_comment.label=Create &non-Javadoc comments for overridden methods +CodeGenerationPreferencePage.file_comment.label=Create &file comments for new files (template 'filecomment') + +CodeGenerationPreferencePage.gettersetter.error.emptyprefix=Prefix strings can not contain an empty entry. +CodeGenerationPreferencePage.gettersetter.error.emptysuffix=Suffix strings can not contain an empty entry. +CodeGenerationPreferencePage.gettersetter.error.invalidprefix={0} is not a valid prefix. +CodeGenerationPreferencePage.gettersetter.error.invalidsuffix={0} is not a valid suffix. + +########### +## viewsupport +########### +JavaImageLabelprovider.assert.wrongImage=no image for this JavaElement Type + +JavaTextLabelProvider.default_package=(default package) +JavaTextLabelProvider.import_declarations=import declarations +JavaTextLabelProvider.initializer=\{...\} + +JavaElementLabels.default_package=(default package) +JavaElementLabels.import_container=import declarations +JavaElementLabels.initializer=\{...\} +JavaElementLabels.concat_string=\ -\ +JavaElementLabels.comma_string=,\ +JavaElementLabels.declseparator_string=\ :\ + +StatusBarUpdater.num_elements_selected={0} items selected +StatusBarUpdater.twopart={0} - {1} +StatusBarUpdater.threepart={0} - {1} - {2} + + +######### +## jdt.ui +######### +JavaElementContentProvider.errorMessage=Child not present + +######### +## util +######### + +OpenTypeHierarchyUtil.error.open_view=Problems opening Type Hierarchy View +OpenTypeHierarchyUtil.error.open_perspective=Problems opening Type Hierarchy Perspective +OpenTypeHierarchyUtil.error.open_editor=Problems opening Java Editor +OpenTypeHierarchyUtil.error.no_perspective=Type Hierarchy perspective not found +OpenTypeHierarchyUtil.selectionDialog.title=Open In Type Hierarchy +OpenTypeHierarchyUtil.selectionDialog.message=&Select the type to be shown in the Type Hierarchy: + +TypeInfoLabelProvider.default_package=(default package) +TypeInfoLabelProvider.dash=\ - + +JavaUIHelp.link.label=Javadoc for {0} + +######### +# DnD +######### +ResourceTransferDragAdapter.cannot_delete_resource=Cannot delete resources +ResourceTransferDragAdapter.moving_resource=Moving Resources via DND +ResourceTransferDragAdapter.cannot_delete_files=Cannot delete the following file(s) + +######### +# misc +######### + +AddImportOnSelectionAction.error.message=AddImportOnSelectionAction: Failed to resolve TypeRef: {0} + +CompilationUnitDocumentProvider.problemsCreatingBuffer=Problems creating buffer + +_ClassFileDocumentProvider.problemsCreatingBuffer=Problems creating buffer + +NewMethodCompletionProposal.method=Method {0} + +JavaAnnotationHover.multipleMarkersAtThisLine=Multiple markers at this line +JavaTextHover.createTextHover=Could not create java text hover + +HTMLTextPresenter.ellipsis= +HTML2TextReader.dash=- + +JavaEditor.codeassist.noCompletions=No completions available. + +OptionalMessageDialog.dontShowAgain= Don't show this message again \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaUIStatus.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaUIStatus.java new file mode 100644 index 0000000..e9adab1 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaUIStatus.java @@ -0,0 +1,28 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.ui; + +import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; + +/** + * Convenience class for error exceptions thrown inside JavaUI plugin. + */ +public class JavaUIStatus extends Status { + + public JavaUIStatus(int code, String message, Throwable throwable) { + super(IStatus.ERROR, PHPeclipsePlugin.getPluginId(), code, message, throwable); + } + + public JavaUIStatus(int code, String message) { + this(code, message, null); + } + + public JavaUIStatus(int code) { + this(code, ""); //$NON-NLS-1$ + } +} + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/IJavaCompletionProposal.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/IJavaCompletionProposal.java new file mode 100644 index 0000000..01bcec2 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/IJavaCompletionProposal.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2000, 2002 International Business Machines Corp. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Corporation - initial API and implementation + ******************************************************************************/ + +package net.sourceforge.phpdt.internal.ui.text.java; + +import org.eclipse.jface.text.contentassist.ICompletionProposal; + +/* + * CompletionProposal with a relevance value. + * The relevance value is used to sort the completion proposals. Proposals with higher relevance + * should be listed before proposals with lower relevance. + */ +public interface IJavaCompletionProposal extends ICompletionProposal { + + /** + * Returns the relevance of the proposal. + */ + int getRelevance(); + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaCompletionProcessor_NotInUseVersion.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaCompletionProcessor_NotInUseVersion.java new file mode 100644 index 0000000..6d168b5 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaCompletionProcessor_NotInUseVersion.java @@ -0,0 +1,378 @@ +package net.sourceforge.phpdt.internal.ui.text.java; + +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ + + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Hashtable; +import java.util.List; + +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Shell; + +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.contentassist.ICompletionProposal; +import org.eclipse.jface.text.contentassist.IContentAssistProcessor; +import org.eclipse.jface.text.contentassist.IContextInformation; +import org.eclipse.jface.text.contentassist.IContextInformationExtension; +import org.eclipse.jface.text.contentassist.IContextInformationValidator; + +import org.eclipse.ui.IEditorPart; + +//import org.eclipse.jdt.core.ICompilationUnit; +//import org.eclipse.jdt.core.JavaCore; +//import org.eclipse.jdt.core.JavaModelException; +// +//import org.eclipse.jdt.ui.IWorkingCopyManager; +//import org.eclipse.jdt.ui.PreferenceConstants; + +import net.sourceforge.phpdt.internal.corext.template.ContextType; +import net.sourceforge.phpdt.internal.corext.template.ContextTypeRegistry; +//import org.eclipse.jdt.internal.ui.JavaPlugin; +import net.sourceforge.phpdt.internal.ui.JavaUIMessages; +//import org.eclipse.jdt.internal.ui.text.JavaCodeReader; +import net.sourceforge.phpdt.internal.ui.text.template.TemplateEngine; + + +/** + * Java completion processor. + */ +public class JavaCompletionProcessor_NotInUseVersion implements IContentAssistProcessor { + + private static class ContextInformationWrapper implements IContextInformation, IContextInformationExtension { + + private final IContextInformation fContextInformation; + private int fPosition; + + public ContextInformationWrapper(IContextInformation contextInformation) { + fContextInformation= contextInformation; + } + + /* + * @see IContextInformation#getContextDisplayString() + */ + public String getContextDisplayString() { + return fContextInformation.getContextDisplayString(); + } + + /* + * @see IContextInformation#getImage() + */ + public Image getImage() { + return fContextInformation.getImage(); + } + + /* + * @see IContextInformation#getInformationDisplayString() + */ + public String getInformationDisplayString() { + return fContextInformation.getInformationDisplayString(); + } + + /* + * @see IContextInformationExtension#getContextInformationPosition() + */ + public int getContextInformationPosition() { + return fPosition; + } + + public void setContextInformationPosition(int position) { + fPosition= position; + } + }; + + +// private final static String VISIBILITY= JavaCore.CODEASSIST_VISIBILITY_CHECK; + private final static String ENABLED= "enabled"; //$NON-NLS-1$ + private final static String DISABLED= "disabled"; //$NON-NLS-1$ + + + + private IEditorPart fEditor; +// private ResultCollector fCollector; +// private IWorkingCopyManager fManager; + private IContextInformationValidator fValidator; + + private char[] fProposalAutoActivationSet; + private JavaCompletionProposalComparator fComparator; + private boolean fAllowAddImports; + + private TemplateEngine fTemplateEngine; +// private ExperimentalResultCollector fExperimentalCollector; + + private int fNumberOfComputedResults= 0; + + + public JavaCompletionProcessor_NotInUseVersion(IEditorPart editor) { + fEditor= editor; +// fCollector= new ResultCollector(); +// fManager= JavaPlugin.getDefault().getWorkingCopyManager(); + ContextType contextType= ContextTypeRegistry.getInstance().getContextType("php"); //$NON-NLS-1$ + if (contextType != null) + fTemplateEngine= new TemplateEngine(contextType); +// fExperimentalCollector= new ExperimentalResultCollector(); + fAllowAddImports= true; + + fComparator= new JavaCompletionProposalComparator(); + } + + /** + * Sets this processor's set of characters triggering the activation of the + * completion proposal computation. + * + * @param activationSet the activation set + */ + public void setCompletionProposalAutoActivationCharacters(char[] activationSet) { + fProposalAutoActivationSet= activationSet; + } + + /** + * Tells this processor to restrict its proposal to those element + * visible in the actual invocation context. + * + * @param restrict true if proposals should be restricted + */ + public void restrictProposalsToVisibility(boolean restrict) { +// Hashtable options= JavaCore.getOptions(); +// Object value= options.get(VISIBILITY); +// if (value instanceof String) { +// String newValue= restrict ? ENABLED : DISABLED; +// if ( !newValue.equals((String) value)) { +// options.put(VISIBILITY, newValue); +// JavaCore.setOptions(options); +// } +// } + } + + /** + * Tells this processor to order the proposals alphabetically. + * + * @param order true if proposals should be ordered. + */ + public void orderProposalsAlphabetically(boolean order) { + fComparator.setOrderAlphabetically(order); + } + + /** + * Tells this processor to restrict is proposals to those + * starting with matching cases. + * + * @param restrict true if proposals should be restricted + */ + public void restrictProposalsToMatchingCases(boolean restrict) { + // not yet supported + } + + /** + * Tells this processor to add import statement for proposals that have + * a fully qualified type name + * + * @param restrict true if import can be added + */ + public void allowAddingImports(boolean allowAddingImports) { + fAllowAddImports= allowAddingImports; + } + + /** + * @see IContentAssistProcessor#getErrorMessage() + */ + public String getErrorMessage() { + // if (fNumberOfComputedResults == 0) + return JavaUIMessages.getString("JavaEditor.codeassist.noCompletions"); //$NON-NLS-1$ +// return fCollector.getErrorMessage(); + } + + /** + * @see IContentAssistProcessor#getContextInformationValidator() + */ + public IContextInformationValidator getContextInformationValidator() { +// if (fValidator == null) +// fValidator= new JavaParameterListValidator(); + return fValidator; + } + + /** + * @see IContentAssistProcessor#getContextInformationAutoActivationCharacters() + */ + public char[] getContextInformationAutoActivationCharacters() { + return null; + } + + /** + * @see IContentAssistProcessor#getCompletionProposalAutoActivationCharacters() + */ + public char[] getCompletionProposalAutoActivationCharacters() { + return fProposalAutoActivationSet; + } + +// private boolean looksLikeMethod(JavaCodeReader reader) throws IOException { +// int curr= reader.read(); +// while (curr != JavaCodeReader.EOF && Character.isWhitespace((char) curr)) +// curr= reader.read(); +// +// if (curr == JavaCodeReader.EOF) +// return false; +// +// return Character.isJavaIdentifierPart((char) curr) || Character.isJavaIdentifierStart((char) curr); +// } + + private int guessContextInformationPosition(ITextViewer viewer, int offset) { + int contextPosition= offset; + + IDocument document= viewer.getDocument(); + +// try { +// +// JavaCodeReader reader= new JavaCodeReader(); +// reader.configureBackwardReader(document, offset, true, true); +// +// int nestingLevel= 0; +// +// int curr= reader.read(); +// while (curr != JavaCodeReader.EOF) { +// +// if (')' == (char) curr) +// ++ nestingLevel; +// +// else if ('(' == (char) curr) { +// -- nestingLevel; +// +// if (nestingLevel < 0) { +// int start= reader.getOffset(); +// if (looksLikeMethod(reader)) +// return start + 1; +// } +// } +// +// curr= reader.read(); +// } +// } catch (IOException e) { +// } + + return contextPosition; + } + + private List addContextInformations(ITextViewer viewer, int offset) { + ICompletionProposal[] proposals= internalComputeCompletionProposals(viewer, offset, -1); + + List result= new ArrayList(); + for (int i= 0; i < proposals.length; i++) { + IContextInformation contextInformation= proposals[i].getContextInformation(); + if (contextInformation != null) { + ContextInformationWrapper wrapper= new ContextInformationWrapper(contextInformation); + wrapper.setContextInformationPosition(offset); + result.add(wrapper); + } + } + return result; + } + + /** + * @see IContentAssistProcessor#computeContextInformation(ITextViewer, int) + */ + public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) { + int contextInformationPosition= guessContextInformationPosition(viewer, offset); + List result= addContextInformations(viewer, contextInformationPosition); + return (IContextInformation[]) result.toArray(new IContextInformation[result.size()]); + } + + /** + * Order the given proposals. + */ + private ICompletionProposal[] order(ICompletionProposal[] proposals) { + Arrays.sort(proposals, fComparator); + return proposals; + } + + /** + * @see IContentAssistProcessor#computeCompletionProposals(ITextViewer, int) + */ + public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) { + int contextInformationPosition= guessContextInformationPosition(viewer, offset); + return internalComputeCompletionProposals(viewer, offset, contextInformationPosition); + } + + private ICompletionProposal[] internalComputeCompletionProposals(ITextViewer viewer, int offset, int contextOffset) { + +// ICompilationUnit unit= fManager.getWorkingCopy(fEditor.getEditorInput()); +// IJavaCompletionProposal[] results; +// +// if (JavaPlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.CODEASSIST_FILL_ARGUMENT_NAMES)) { +// +// try { +// if (unit != null) { +// +// fExperimentalCollector.reset(offset, contextOffset, unit.getJavaProject(), fAllowAddImports ? unit : null); +// fExperimentalCollector.setViewer(viewer); +// +// Point selection= viewer.getSelectedRange(); +// if (selection.y > 0) +// fExperimentalCollector.setReplacementLength(selection.y); +// +// unit.codeComplete(offset, fExperimentalCollector); +// } +// } catch (JavaModelException x) { +// Shell shell= viewer.getTextWidget().getShell(); +// ErrorDialog.openError(shell, JavaTextMessages.getString("CompletionProcessor.error.accessing.title"), JavaTextMessages.getString("CompletionProcessor.error.accessing.message"), x.getStatus()); //$NON-NLS-2$ //$NON-NLS-1$ +// } +// +// results= fExperimentalCollector.getResults(); +// +// } else { +// +// try { +// if (unit != null) { +// +// fCollector.reset(offset, contextOffset, unit.getJavaProject(), fAllowAddImports ? unit : null); +// Point selection= viewer.getSelectedRange(); +// if (selection.y > 0) +// fCollector.setReplacementLength(selection.y); +// +// unit.codeComplete(offset, fCollector); +// } +// } catch (JavaModelException x) { +// Shell shell= viewer.getTextWidget().getShell(); +// ErrorDialog.openError(shell, JavaTextMessages.getString("CompletionProcessor.error.accessing.title"), JavaTextMessages.getString("CompletionProcessor.error.accessing.message"), x.getStatus()); //$NON-NLS-2$ //$NON-NLS-1$ +// } +// +// results= fCollector.getResults(); +// } + + if (fTemplateEngine != null) { + IJavaCompletionProposal[] results; +// try { + fTemplateEngine.reset(); + fTemplateEngine.complete(viewer, offset); //, unit); +// } catch (JavaModelException x) { +// Shell shell= viewer.getTextWidget().getShell(); +// ErrorDialog.openError(shell, JavaTextMessages.getString("CompletionProcessor.error.accessing.title"), JavaTextMessages.getString("CompletionProcessor.error.accessing.message"), x.getStatus()); //$NON-NLS-2$ //$NON-NLS-1$ +// } + + IJavaCompletionProposal[] templateResults= fTemplateEngine.getResults(); + + // concatenate arrays + IJavaCompletionProposal[] total= new IJavaCompletionProposal[templateResults.length]; // +results.length ]; + System.arraycopy(templateResults, 0, total, 0, templateResults.length); +// System.arraycopy(results, 0, total, templateResults.length, results.length); + results= total; +// } + + fNumberOfComputedResults= (results == null ? 0 : results.length); + + /* + * Order here and not in result collector to make sure that the order + * applies to all proposals and not just those of the compilation unit. + */ + return order(results); + } + return new IJavaCompletionProposal[0]; + } +} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaCompletionProposalComparator.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaCompletionProposalComparator.java new file mode 100644 index 0000000..8b43bb3 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaCompletionProposalComparator.java @@ -0,0 +1,35 @@ +package net.sourceforge.phpdt.internal.ui.text.java; + +import java.util.Comparator; + +public class JavaCompletionProposalComparator implements Comparator { + + private boolean fOrderAlphabetically; + + /** + * Constructor for CompletionProposalComparator. + */ + public JavaCompletionProposalComparator() { + fOrderAlphabetically= false; + } + + public void setOrderAlphabetically(boolean orderAlphabetically) { + fOrderAlphabetically= orderAlphabetically; + } + + /* (non-Javadoc) + * @see Comparator#compare(Object, Object) + */ + public int compare(Object o1, Object o2) { + IJavaCompletionProposal c1= (IJavaCompletionProposal) o1; + IJavaCompletionProposal c2= (IJavaCompletionProposal) o2; + if (!fOrderAlphabetically) { + int relevanceDif= c2.getRelevance() - c1.getRelevance(); + if (relevanceDif != 0) { + return relevanceDif; + } + } + return c1.getDisplayString().compareToIgnoreCase(c2.getDisplayString()); + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateContentProvider.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateContentProvider.java new file mode 100644 index 0000000..a675702 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateContentProvider.java @@ -0,0 +1,38 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.ui.text.template; + +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.Viewer; + +import net.sourceforge.phpdt.internal.corext.template.TemplateSet; + +public class TemplateContentProvider implements IStructuredContentProvider { + + private TemplateSet fTemplateSet; + + /* + * @see IStructuredContentProvider#getElements(Object) + */ + public Object[] getElements(Object input) { + return fTemplateSet.getTemplates(); + } + + /* + * @see IContentProvider#inputChanged(Viewer, Object, Object) + */ + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + fTemplateSet= (TemplateSet) newInput; + } + + /* + * @see IContentProvider#dispose() + */ + public void dispose() { + fTemplateSet= null; + } + +} + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateEngine.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateEngine.java new file mode 100644 index 0000000..d14b31e --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateEngine.java @@ -0,0 +1,93 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.ui.text.template; + +import java.util.ArrayList; + +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.Region; + +//import org.eclipse.jdt.core.ICompilationUnit; +//import org.eclipse.jdt.core.JavaModelException; + +//import org.eclipse.jdt.internal.corext.Assert; +import net.sourceforge.phpdt.internal.corext.template.ContextType; +import net.sourceforge.phpdt.internal.corext.template.Template; +import net.sourceforge.phpdt.internal.corext.template.Templates; +import net.sourceforge.phpdt.internal.corext.template.java.CompilationUnitContext; +import net.sourceforge.phpdt.internal.corext.template.java.CompilationUnitContextType; +//import org.eclipse.jdt.internal.ui.JavaPluginImages; +import net.sourceforge.phpdt.internal.ui.text.java.IJavaCompletionProposal; +//import org.eclipse.jdt.internal.ui.text.link.LinkedPositionManager; + +public class TemplateEngine { + + /** The context type. */ + private ContextType fContextType; + /** The result proposals. */ + private ArrayList fProposals= new ArrayList(); + + /** + * Creates the template engine for a particular context type. + * See TemplateContext for supported context types. + */ + public TemplateEngine(ContextType contextType) { + // Assert.isNotNull(contextType); + fContextType= contextType; + } + + /** + * Empties the collector. + * + * @param viewer the text viewer + * @param unit the compilation unit (may be null) + */ + public void reset() { + fProposals.clear(); + } + + /** + * Returns the array of matching templates. + */ + public IJavaCompletionProposal[] getResults() { + return (IJavaCompletionProposal[]) fProposals.toArray(new IJavaCompletionProposal[fProposals.size()]); + } + + /** + * Inspects the context of the compilation unit around completionPosition + * and feeds the collector with proposals. + * @param viewer the text viewer + * @param completionPosition the context position in the document of the text viewer + * @param compilationUnit the compilation unit (may be null) + */ + public void complete(ITextViewer viewer, int completionPosition) + //,ICompilationUnit compilationUnit) + //hrows JavaModelException + { + IDocument document= viewer.getDocument(); + + // prohibit recursion +// if (LinkedPositionManager.hasActiveManager(document)) +// return; + + if (!(fContextType instanceof CompilationUnitContextType)) + return; + + ((CompilationUnitContextType) fContextType).setContextParameters(document, completionPosition);//mpilationUnit); + CompilationUnitContext context= (CompilationUnitContext) fContextType.createContext(); + int start= context.getStart(); + int end= context.getEnd(); + IRegion region= new Region(start, end - start); + + Template[] templates= Templates.getInstance().getTemplates(); + for (int i= 0; i != templates.length; i++) + if (context.canEvaluate(templates[i])) + fProposals.add(new TemplateProposal(templates[i], context, region, viewer)); //luginImages.get(JavaPluginImages.IMG_OBJS_TEMPLATE))); + } + +} + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateLabelProvider.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateLabelProvider.java new file mode 100644 index 0000000..69765ad --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateLabelProvider.java @@ -0,0 +1,67 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.ui.text.template; + +import org.eclipse.swt.graphics.Image; + +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.ITableLabelProvider; + +import net.sourceforge.phpdt.internal.corext.template.Template; + +public class TemplateLabelProvider implements ITableLabelProvider { + + /* + * @see ITableLabelProvider#getColumnImage(Object, int) + */ + public Image getColumnImage(Object element, int columnIndex) { + return null; + } + + /* + * @see ITableLabelProvider#getColumnText(Object, int) + */ + public String getColumnText(Object element, int columnIndex) { + Template template = (Template) element; + + switch (columnIndex) { + case 0: + return template.getName(); + case 1: + return template.getContextTypeName(); + case 2: + return template.getDescription(); + default: + return null; + } + } + + /* + * @see IBaseLabelProvider#addListener(ILabelProviderListener) + */ + public void addListener(ILabelProviderListener listener) { + } + + /* + * @see IBaseLabelProvider#dispose() + */ + public void dispose() { + } + + /* + * @see IBaseLabelProvider#isLabelProperty(Object, String) + */ + public boolean isLabelProperty(Object element, String property) { + return false; + } + + /* + * @see IBaseLabelProvider#removeListener(ILabelProviderListener) + */ + public void removeListener(ILabelProviderListener listener) { + } + +} + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateProposal.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateProposal.java new file mode 100644 index 0000000..5178caa --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateProposal.java @@ -0,0 +1,241 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.ui.text.template; + +import net.sourceforge.phpdt.internal.corext.template.Template; +import net.sourceforge.phpdt.internal.corext.template.TemplateBuffer; +import net.sourceforge.phpdt.internal.corext.template.TemplateContext; +import net.sourceforge.phpdt.internal.corext.template.TemplateMessages; +import net.sourceforge.phpdt.internal.corext.template.TemplatePosition; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import org.eclipse.core.runtime.CoreException; +import net.sourceforge.phpdt.internal.corext.template.java.CompilationUnitContext; +import net.sourceforge.phpdt.internal.corext.template.java.JavaTemplateMessages; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.contentassist.IContextInformation; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Shell; +//import org.eclipse.jdt.internal.ui.JavaPlugin; +import net.sourceforge.phpdt.internal.ui.text.java.IJavaCompletionProposal; +//import org.eclipse.jdt.internal.ui.text.link.LinkedPositionManager; +//import org.eclipse.jdt.internal.ui.text.link.LinkedPositionUI; +//import org.eclipse.jdt.internal.ui.util.ExceptionHandler; + +/** + * A template proposal. + */ +public class TemplateProposal implements IJavaCompletionProposal { + + private final Template fTemplate; + private final TemplateContext fContext; + private final ITextViewer fViewer; +// private final Image fImage; + private final IRegion fRegion; + + private TemplateBuffer fTemplateBuffer; + private String fOldText; +// private IRegion fSelectedRegion; // initialized by apply() + + /** + * Creates a template proposal with a template and its context. + * @param template the template + * @param context the context in which the template was requested. + * @param image the icon of the proposal. + */ + public TemplateProposal(Template template, TemplateContext context, IRegion region, ITextViewer viewer){ //, Image image) { +// Assert.isNotNull(template); +// Assert.isNotNull(context); +// Assert.isNotNull(region); +// Assert.isNotNull(viewer); + + fTemplate= template; + fContext= context; + fViewer= viewer; +// fImage= image; + fRegion= region; + } + + /* + * @see ICompletionProposal#apply(IDocument) + */ + public void apply(IDocument document) { + try { + if (fTemplateBuffer == null) + fTemplateBuffer= fContext.evaluate(fTemplate); + + int start= fRegion.getOffset(); + int end= fRegion.getOffset() + fRegion.getLength(); + + // insert template string + String templateString= fTemplateBuffer.getString(); + document.replace(start, end - start, templateString); + + // translate positions + // LinkedPositionManager manager= new LinkedPositionManager(document); + TemplatePosition[] variables= fTemplateBuffer.getVariables(); + for (int i= 0; i != variables.length; i++) { + TemplatePosition variable= variables[i]; + + if (variable.isResolved()) + continue; + + int[] offsets= variable.getOffsets(); + int length= variable.getLength(); + +// for (int j= 0; j != offsets.length; j++) +// manager.addPosition(offsets[j] + start, length); + } + +// LinkedPositionUI editor= new LinkedPositionUI(fViewer, manager); +// editor.setFinalCaretOffset(getCaretOffset(fTemplateBuffer) + start); +// editor.enter(); + +// fSelectedRegion= editor.getSelectedRegion(); + + } catch (BadLocationException e) { + PHPeclipsePlugin.log(e); + openErrorDialog(e); + + } catch (CoreException e) { + handleException(e); + } + } + + private static int getCaretOffset(TemplateBuffer buffer) { + TemplatePosition[] variables= buffer.getVariables(); + for (int i= 0; i != variables.length; i++) { + TemplatePosition variable= variables[i]; + + if (variable.getName().equals(JavaTemplateMessages.getString("GlobalVariables.variable.name.cursor"))) //$NON-NLS-1$ + return variable.getOffsets()[0]; + } + + return buffer.getString().length(); + } + + /* + * @see ICompletionProposal#getSelection(IDocument) + */ + public Point getSelection(IDocument document) { +// return new Point(fSelectedRegion.getOffset(), fSelectedRegion.getLength()); + return null; + } + + /* + * @see ICompletionProposal#getAdditionalProposalInfo() + */ + public String getAdditionalProposalInfo() { + try { + if (fTemplateBuffer == null) + fTemplateBuffer= fContext.evaluate(fTemplate); + + return textToHTML(fTemplateBuffer.getString()); + + } catch (CoreException e) { + handleException(e); + return null; + } + } + + /* + * @see ICompletionProposal#getDisplayString() + */ + public String getDisplayString() { + return fTemplate.getName() + TemplateMessages.getString("TemplateProposal.delimiter") + fTemplate.getDescription(); // $NON-NLS-1$ //$NON-NLS-1$ + } + + /* + * @see ICompletionProposal#getImage() + */ + public Image getImage() { +// return fImage; + return null; + } + + /* + * @see ICompletionProposal#getContextInformation() + */ + public IContextInformation getContextInformation() { + return null; + } + + private static String textToHTML(String string) { + StringBuffer buffer= new StringBuffer(string.length()); + buffer.append("
"); //$NON-NLS-1$
+	
+		for (int i= 0; i != string.length(); i++) {
+			char ch= string.charAt(i);
+			
+			switch (ch) {
+				case '&':
+					buffer.append("&"); //$NON-NLS-1$
+					break;
+					
+				case '<':
+					buffer.append("<"); //$NON-NLS-1$
+					break;
+
+				case '>':
+					buffer.append(">"); //$NON-NLS-1$
+					break;
+
+				case '\t':
+					buffer.append("    "); //$NON-NLS-1$
+					break;
+
+				case '\n':
+					buffer.append("
"); //$NON-NLS-1$ + break; + + default: + buffer.append(ch); + break; + } + } + + buffer.append("
"); //$NON-NLS-1$ + return buffer.toString(); + } + + private void openErrorDialog(BadLocationException e) { + Shell shell= fViewer.getTextWidget().getShell(); + MessageDialog.openError(shell, TemplateMessages.getString("TemplateEvaluator.error.title"), e.getMessage()); //$NON-NLS-1$ + } + + private void handleException(CoreException e) { + Shell shell= fViewer.getTextWidget().getShell(); + PHPeclipsePlugin.log(e); +// ExceptionHandler.handle(e, shell, TemplateMessages.getString("TemplateEvaluator.error.title"), null); //$NON-NLS-1$ + } + + /* + * @see IJavaCompletionProposal#getRelevance() + */ + public int getRelevance() { + + if (fContext instanceof CompilationUnitContext) { + CompilationUnitContext context= (CompilationUnitContext) fContext; + switch (context.getCharacterBeforeStart()) { + // high relevance after whitespace + case ' ': + case '\r': + case '\n': + case '\t': + return 90; + + default: + return 0; + } + } else { + return 90; + } + } + +} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateVariableProcessor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateVariableProcessor.java new file mode 100644 index 0000000..ec60207 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateVariableProcessor.java @@ -0,0 +1,129 @@ +package net.sourceforge.phpdt.internal.ui.text.template; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.contentassist.ICompletionProposal; +import org.eclipse.jface.text.contentassist.IContentAssistProcessor; +import org.eclipse.jface.text.contentassist.IContextInformation; +import org.eclipse.jface.text.contentassist.IContextInformationValidator; + +import net.sourceforge.phpdt.internal.corext.template.ContextType; +import net.sourceforge.phpdt.internal.corext.template.TemplateVariable; + +public class TemplateVariableProcessor implements IContentAssistProcessor { + + private static Comparator fgTemplateVariableProposalComparator= new Comparator() { + public int compare(Object arg0, Object arg1) { + TemplateVariableProposal proposal0= (TemplateVariableProposal) arg0; + TemplateVariableProposal proposal1= (TemplateVariableProposal) arg1; + + return proposal0.getDisplayString().compareTo(proposal1.getDisplayString()); + } + + public boolean equals(Object arg0) { + return false; + } + }; + + + /** the context type */ + private ContextType fContextType; + + /** + * Sets the context type. + */ + public void setContextType(ContextType contextType) { + fContextType= contextType; + } + + /* + * @see IContentAssistProcessor#computeCompletionProposals(ITextViewer, int) + */ + public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int documentOffset) { + + if (fContextType == null) + return null; + + List proposals= new ArrayList(); + + String text= viewer.getDocument().get(); + int start= getStart(text, documentOffset); + int end= documentOffset; + + String string= text.substring(start, end); + String prefix= (string.length() >= 2) + ? string.substring(2) + : null; + + int offset= start; + int length= end - start; + + for (Iterator iterator= fContextType.variableIterator(); iterator.hasNext(); ) { + TemplateVariable variable= (TemplateVariable) iterator.next(); + + if (prefix == null || variable.getName().startsWith(prefix)) + proposals.add(new TemplateVariableProposal(variable, offset, length, viewer)); + } + + Collections.sort(proposals, fgTemplateVariableProposalComparator); + return (ICompletionProposal[]) proposals.toArray(new ICompletionProposal[proposals.size()]); + } + + /* Guesses the start position of the completion */ + private int getStart(String string, int end) { + int start= end; + + if (start >= 1 && string.charAt(start - 1) == '$') + return start - 1; + + while ((start != 0) && Character.isUnicodeIdentifierPart(string.charAt(start - 1))) + start--; + + if (start >= 2 && string.charAt(start - 1) == '{' && string.charAt(start - 2) == '$') + return start - 2; + + return end; + } + + /* + * @see IContentAssistProcessor#computeContextInformation(ITextViewer, int) + */ + public IContextInformation[] computeContextInformation(ITextViewer viewer, int documentOffset) { + return null; + } + + /* + * @see IContentAssistProcessor#getCompletionProposalAutoActivationCharacters() + */ + public char[] getCompletionProposalAutoActivationCharacters() { + return new char[] {'$'}; + } + + /* + * @see IContentAssistProcessor#getContextInformationAutoActivationCharacters() + */ + public char[] getContextInformationAutoActivationCharacters() { + return null; + } + + /* + * @see IContentAssistProcessor#getErrorMessage() + */ + public String getErrorMessage() { + return null; + } + + /* + * @see IContentAssistProcessor#getContextInformationValidator() + */ + public IContextInformationValidator getContextInformationValidator() { + return null; + } + +} + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateVariableProposal.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateVariableProposal.java new file mode 100644 index 0000000..794209d --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateVariableProposal.java @@ -0,0 +1,100 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package net.sourceforge.phpdt.internal.ui.text.template; + +import net.sourceforge.phpdt.internal.corext.template.TemplateMessages; +import net.sourceforge.phpdt.internal.corext.template.TemplateVariable; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.contentassist.ICompletionProposal; +import org.eclipse.jface.text.contentassist.IContextInformation; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Shell; +//import org.eclipse.jdt.internal.ui.JavaPlugin; + +/** + * A proposal for insertion of template variables. + */ +public class TemplateVariableProposal implements ICompletionProposal { + + private TemplateVariable fVariable; + private int fOffset; + private int fLength; + private ITextViewer fViewer; + + private Point fSelection; + + /** + * Creates a template variable proposal. + * + * @param variable the template variable + * @param offset the offset to replace + * @param length the length to replace + * @param viewer the viewer + */ + public TemplateVariableProposal(TemplateVariable variable, int offset, int length, ITextViewer viewer) { + fVariable= variable; + fOffset= offset; + fLength= length; + fViewer= viewer; + } + + /* + * @see ICompletionProposal#apply(IDocument) + */ + public void apply(IDocument document) { + + try { + String variable= fVariable.getName().equals("dollar") ? "$$" : "${" + fVariable.getName() + '}'; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + document.replace(fOffset, fLength, variable); + fSelection= new Point(fOffset + variable.length(), 0); + + } catch (BadLocationException e) { + PHPeclipsePlugin.log(e); + + Shell shell= fViewer.getTextWidget().getShell(); + MessageDialog.openError(shell, TemplateMessages.getString("TemplateVariableProposal.error.title"), e.getMessage()); //$NON-NLS-1$ + } + } + + /* + * @see ICompletionProposal#getSelection(IDocument) + */ + public Point getSelection(IDocument document) { + return fSelection; + } + + /* + * @see ICompletionProposal#getAdditionalProposalInfo() + */ + public String getAdditionalProposalInfo() { + return null; + } + + /* + * @see ICompletionProposal#getDisplayString() + */ + public String getDisplayString() { + return fVariable.getName() + " - " + fVariable.getDescription(); //$NON-NLS-1$ + } + + /* + * @see ICompletionProposal#getImage() + */ + public Image getImage() { + return null; + } + + /* + * @see ICompletionProposal#getContextInformation() + */ + public IContextInformation getContextInformation() { + return null; + } +} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCompletionProcessor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCompletionProcessor.java index 6fd4ce7..c7ad06a 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCompletionProcessor.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCompletionProcessor.java @@ -13,7 +13,14 @@ package net.sourceforge.phpeclipse.phpeditor.php; import java.text.MessageFormat; import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import net.sourceforge.phpdt.internal.corext.template.ContextType; +import net.sourceforge.phpdt.internal.corext.template.ContextTypeRegistry; +import net.sourceforge.phpdt.internal.ui.text.java.IJavaCompletionProposal; +import net.sourceforge.phpdt.internal.ui.text.java.JavaCompletionProposalComparator; +import net.sourceforge.phpdt.internal.ui.text.template.TemplateEngine; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ITextViewer; @@ -23,9 +30,10 @@ import org.eclipse.jface.text.contentassist.ContextInformation; import org.eclipse.jface.text.contentassist.ICompletionProposal; import org.eclipse.jface.text.contentassist.IContentAssistProcessor; import org.eclipse.jface.text.contentassist.IContextInformation; +import org.eclipse.jface.text.contentassist.IContextInformationExtension; import org.eclipse.jface.text.contentassist.IContextInformationPresenter; import org.eclipse.jface.text.contentassist.IContextInformationValidator; -import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Image; /** * Example PHP completion processor. @@ -62,6 +70,48 @@ public class PHPCompletionProcessor implements IContentAssistProcessor { } }; + private static class ContextInformationWrapper implements IContextInformation, IContextInformationExtension { + + private final IContextInformation fContextInformation; + private int fPosition; + + public ContextInformationWrapper(IContextInformation contextInformation) { + fContextInformation = contextInformation; + } + + /* + * @see IContextInformation#getContextDisplayString() + */ + public String getContextDisplayString() { + return fContextInformation.getContextDisplayString(); + } + + /* + * @see IContextInformation#getImage() + */ + public Image getImage() { + return fContextInformation.getImage(); + } + + /* + * @see IContextInformation#getInformationDisplayString() + */ + public String getInformationDisplayString() { + return fContextInformation.getInformationDisplayString(); + } + + /* + * @see IContextInformationExtension#getContextInformationPosition() + */ + public int getContextInformationPosition() { + return fPosition; + } + + public void setContextInformationPosition(int position) { + fPosition = position; + } + }; + protected final static String[] fgProposals = PHPFunctionNames.FUNCTION_NAMES; // { // "array", @@ -101,51 +151,64 @@ public class PHPCompletionProcessor implements IContentAssistProcessor { // "var" }; protected IContextInformationValidator fValidator = new Validator(); + private TemplateEngine fTemplateEngine; + private JavaCompletionProposalComparator fComparator; + private int fNumberOfComputedResults = 0; + + public PHPCompletionProcessor() { + ContextType contextType = ContextTypeRegistry.getInstance().getContextType("php"); //$NON-NLS-1$ + if (contextType != null) + fTemplateEngine = new TemplateEngine(contextType); + + fComparator = new JavaCompletionProposalComparator(); + } /* (non-Javadoc) * Method declared on IContentAssistProcessor */ public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int documentOffset) { - - // ArrayList arrList = new ArrayList(5); // IDocument document = viewer.getDocument(); // if (documentOffset > 0) { // try { + // ICompletionProposal[] result; // char character = document.getChar(documentOffset - 1); - // Point point = PHPWordExtractor.findWord(document, documentOffset); - // if (point != null) { - // String word = document.get(point.x, point.y); + // if (character == '$') { + ////viewer. .getActivePage().getActiveEditor(); + // result = new ICompletionProposal[fgProposals.length]; // for (int i = 0; i < fgProposals.length; i++) { - // if ((fgProposals[i].length() >= point.y) && fgProposals[i].substring(0, point.y).equals(word)) { - // IContextInformation info = new ContextInformation(fgProposals[i], MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.Proposal.ContextInfo.pattern"), new Object[] { fgProposals[i] })); //$NON-NLS-1$ - // arrList.add(new CompletionProposal(fgProposals[i], documentOffset, 0, fgProposals[i].length(), null, fgProposals[i], info, MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.Proposal.hoverinfo.pattern"), new Object[] { fgProposals[i] }))); //$NON-NLS-1$ - // } - // } - // if (arrList.size() > 0) { - // ICompletionProposal[] result = new ICompletionProposal[arrList.size()]; - // for (int i=0;i 0) { + if (offset > 0) { try { ICompletionProposal[] result; - char character = document.getChar(documentOffset - 1); + char character = document.getChar(offset - 1); if (character == '$') { -//viewer. .getActivePage().getActiveEditor(); + //viewer. .getActivePage().getActiveEditor(); result = new ICompletionProposal[fgProposals.length]; for (int i = 0; i < fgProposals.length; i++) { IContextInformation info = new ContextInformation(fgProposals[i], MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.Proposal.ContextInfo.pattern"), new Object[] { fgProposals[i] })); //$NON-NLS-1$ - result[i] = new CompletionProposal(fgProposals[i], documentOffset, 0, fgProposals[i].length(), null, fgProposals[i], info, MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.Proposal.hoverinfo.pattern"), new Object[] { fgProposals[i] })); //$NON-NLS-1$ + result[i] = new CompletionProposal(fgProposals[i], offset, 0, fgProposals[i].length(), null, fgProposals[i], info, MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.Proposal.hoverinfo.pattern"), new Object[] { fgProposals[i] })); //$NON-NLS-1$ } return result; } @@ -154,26 +217,114 @@ public class PHPCompletionProcessor implements IContentAssistProcessor { } } - ICompletionProposal[] result = new ICompletionProposal[fgProposals.length]; - for (int i = 0; i < fgProposals.length; i++) { - IContextInformation info = new ContextInformation(fgProposals[i], MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.Proposal.ContextInfo.pattern"), new Object[] { fgProposals[i] })); //$NON-NLS-1$ - result[i] = new CompletionProposal(fgProposals[i], documentOffset, 0, fgProposals[i].length(), null, fgProposals[i], info, MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.Proposal.hoverinfo.pattern"), new Object[] { fgProposals[i] })); //$NON-NLS-1$ + if (fTemplateEngine != null) { + IJavaCompletionProposal[] results; + // try { + fTemplateEngine.reset(); + fTemplateEngine.complete(viewer, offset); //, unit); + // } catch (JavaModelException x) { + // Shell shell= viewer.getTextWidget().getShell(); + // ErrorDialog.openError(shell, JavaTextMessages.getString("CompletionProcessor.error.accessing.title"), JavaTextMessages.getString("CompletionProcessor.error.accessing.message"), x.getStatus()); //$NON-NLS-2$ //$NON-NLS-1$ + // } + + IJavaCompletionProposal[] templateResults = fTemplateEngine.getResults(); + + // concatenate arrays + IJavaCompletionProposal[] total = new IJavaCompletionProposal[templateResults.length]; // +results.length ]; + System.arraycopy(templateResults, 0, total, 0, templateResults.length); + // System.arraycopy(results, 0, total, templateResults.length, results.length); + results = total; + // } + + fNumberOfComputedResults = (results == null ? 0 : results.length); + + /* + * Order here and not in result collector to make sure that the order + * applies to all proposals and not just those of the compilation unit. + */ + return order(results); } + return new IJavaCompletionProposal[0]; + } - return result; + private int guessContextInformationPosition(ITextViewer viewer, int offset) { + int contextPosition = offset; + + IDocument document = viewer.getDocument(); + + // try { + // + // JavaCodeReader reader= new JavaCodeReader(); + // reader.configureBackwardReader(document, offset, true, true); + // + // int nestingLevel= 0; + // + // int curr= reader.read(); + // while (curr != JavaCodeReader.EOF) { + // + // if (')' == (char) curr) + // ++ nestingLevel; + // + // else if ('(' == (char) curr) { + // -- nestingLevel; + // + // if (nestingLevel < 0) { + // int start= reader.getOffset(); + // if (looksLikeMethod(reader)) + // return start + 1; + // } + // } + // + // curr= reader.read(); + // } + // } catch (IOException e) { + // } + + return contextPosition; } /* (non-Javadoc) * Method declared on IContentAssistProcessor */ - public IContextInformation[] computeContextInformation(ITextViewer viewer, int documentOffset) { - IContextInformation[] result = new IContextInformation[5]; - for (int i = 0; i < result.length; i++) - result[i] = new ContextInformation(MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.ContextInfo.display.pattern"), new Object[] { new Integer(i), new Integer(documentOffset)}), //$NON-NLS-1$ - MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.ContextInfo.value.pattern"), new Object[] { new Integer(i), new Integer(documentOffset - 5), new Integer(documentOffset + 5)})); //$NON-NLS-1$ + // public IContextInformation[] computeContextInformation(ITextViewer viewer, int documentOffset) { + // IContextInformation[] result = new IContextInformation[5]; + // for (int i = 0; i < result.length; i++) + // result[i] = new ContextInformation(MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.ContextInfo.display.pattern"), new Object[] { new Integer(i), new Integer(documentOffset)}), //$NON-NLS-1$ + // MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.ContextInfo.value.pattern"), new Object[] { new Integer(i), new Integer(documentOffset - 5), new Integer(documentOffset + 5)})); //$NON-NLS-1$ + // return result; + // } + /** + * @see IContentAssistProcessor#computeContextInformation(ITextViewer, int) + */ + public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) { + int contextInformationPosition = guessContextInformationPosition(viewer, offset); + List result = addContextInformations(viewer, contextInformationPosition); + return (IContextInformation[]) result.toArray(new IContextInformation[result.size()]); + } + + private List addContextInformations(ITextViewer viewer, int offset) { + ICompletionProposal[] proposals = internalComputeCompletionProposals(viewer, offset, -1); + + List result = new ArrayList(); + for (int i = 0; i < proposals.length; i++) { + IContextInformation contextInformation = proposals[i].getContextInformation(); + if (contextInformation != null) { + ContextInformationWrapper wrapper = new ContextInformationWrapper(contextInformation); + wrapper.setContextInformationPosition(offset); + result.add(wrapper); + } + } return result; } + /** + * Order the given proposals. + */ + private ICompletionProposal[] order(ICompletionProposal[] proposals) { + Arrays.sort(proposals, fComparator); + return proposals; + } + /* (non-Javadoc) * Method declared on IContentAssistProcessor */ -- 1.7.1