<nature>org.eclipse.pde.PluginNature</nature>
</natures>
</projectDescription>
+
xmlFileExtension=xml
tplFileExtension=tpl
+javaDocumentFactory=PHP Document Factory
+javaDocumentSetupParticipant=PHP Document Setup Participant
+
sourceHover= Source
sourceHoverDescription= Shows the source of the selected element.
javadocHover= PHPdoc
OccurrenceAnnotation.label= PHP Marker Occurrences
-
phpEditorFontDefiniton.label= Java Editor Text Font
phpEditorFontDefintion.description= The Java editor text font is used by Java editors.
+
+#--- folding
+foldingStructureProvidersExtensionPoint= Folding Structure Providers
+defaultFoldingStructureProviderName= Default PHP Folding
+Folding.label= F&olding
\ No newline at end of file
<import plugin="org.eclipse.help"/>
<import plugin="org.eclipse.swt"/>
<import plugin="org.eclipse.search"/>
- <import plugin="org.apache.xerces"/>
<import plugin="org.eclipse.update.ui"/>
<import plugin="net.sourceforge.phpeclipse.quantum.sql"/>
</requires>
<persistent value="true"/>
</extension>
- <extension-point name="%phpEditorTextHoversName" id="phpEditorTextHovers" schema="schema/phpEditorTextHovers.exsd"/>
-
+ <extension-point id="phpEditorTextHovers" name="%phpEditorTextHoversName" schema="schema/phpEditorTextHovers.exsd"/>
+ <extension-point id="foldingStructureProviders" name="%foldingStructureProvidersExtensionPoint" schema="schema/foldingStructureProviders.exsd"/>
<extension
point="org.eclipse.team.core.fileTypes">
<fileTypes
</action>
</viewerContribution>
</extension>
+ <extension
+ point="org.eclipse.ui.popupMenus">
+ <viewerContribution
+ targetID="#CompilationUnitRulerContext"
+ id="net.sourceforge.phpdt.ui.CompilationUnitEditorPopupActions">
+ <action
+ label="%AddTask.label"
+ helpContextId="org.eclipse.ui.AddTask_action_context"
+ tooltip="%AddTask.tooltip"
+ class="org.eclipse.ui.texteditor.TaskRulerAction"
+ menubarPath="add"
+ id="org.eclipse.ui.texteditor.TaskRulerAction">
+ </action>
+ <action
+ label="%AddBookmark.label"
+ helpContextId="org.eclipse.ui.bookmark_action_context"
+ tooltip="%AddBookmark.tooltip"
+ class="org.eclipse.ui.texteditor.BookmarkRulerAction"
+ menubarPath="add"
+ id="org.eclipse.ui.texteditor.BookmarkRulerAction">
+ </action>
+ <menu
+ id="projection"
+ label="%Folding.label"
+ path="rest">
+ </menu>
+ <action
+ label="%Dummy.label"
+ tooltip="%Dummy.label"
+ class="net.sourceforge.phpdt.internal.ui.actions.FoldingExpandAllRulerAction"
+ menubarPath="projection/additions"
+ definitionId="org.eclipse.ui.edit.text.folding.expand_all"
+ id="net.sourceforge.phpdt.ui.folding.expandAll">
+ </action>
+ <action
+ label="%Dummy.label"
+ tooltip="%Dummy.label"
+ class="net.sourceforge.phpdt.internal.ui.actions.FoldingToggleRulerAction"
+ menubarPath="projection/additions"
+ definitionId="org.eclipse.ui.edit.text.folding.toggle"
+ id="net.sourceforge.phpdt.ui.folding.toggle">
+ </action>
+ </viewerContribution>
+ </extension>
<!-- =========================================================================== -->
<!-- JDT/UI command definitions -->
<!-- =========================================================================== -->
</keyBinding>
</extension>
<extension
+ id="net.sourceforge.phpeclipse.JavaDocumentSetupParticipant"
+ name="%javaDocumentSetupParticipant"
+ point="org.eclipse.core.filebuffers.documentSetup">
+ <participant
+ extensions="php,php3,php4,inc"
+ class="net.sourceforge.phpeclipse.phpeditor.JavaDocumentSetupParticipant">
+ </participant>
+ <participant
+ extensions="html,xml"
+ class="net.sourceforge.phpeclipse.phpeditor.HTMLDocumentSetupParticipant">
+ </participant>
+ <participant
+ extensions="tpl"
+ class="net.sourceforge.phpeclipse.phpeditor.SmartyDocumentSetupParticipant">
+ </participant>
+ </extension>
+ <extension
+ id="net.sourceforge.phpeclipse.JavaDocumentFactory"
+ name="%javaDocumentFactory"
+ point="org.eclipse.core.filebuffers.documentCreation">
+ <factory
+ extensions="php"
+ class="net.sourceforge.phpeclipse.phpeditor.JavaDocumentFactory">
+ </factory>
+ </extension>
+
+ <extension
point="org.eclipse.ui.preferencePages">
<page
name="PHP"
expanderClass="net.sourceforge.phpdt.externaltools.variable.WorkingSetExpander">
</variable>
</extension>
+ <extension
+ point= "net.sourceforge.phpeclipse.foldingStructureProviders">
+ <provider
+ id="net.sourceforge.phpdt.ui.text.defaultFoldingProvider"
+ name= "%defaultFoldingStructureProviderName"
+ class="net.sourceforge.phpdt.internal.ui.text.folding.DefaultJavaFoldingStructureProvider"
+ preferencesClass="net.sourceforge.phpdt.internal.ui.text.folding.DefaultJavaFoldingPreferenceBlock">
+ </provider>
+ </extension>
</plugin>
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.core.dom;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import net.sourceforge.phpdt.core.compiler.IProblem;
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.text.edits.TextEdit;
+
+/**
+ * Java compilation unit AST node type. This is the type of the root of an AST.
+ * <p>
+ * The source range for this type of node is ordinarily the entire source file,
+ * including leading and trailing whitespace and comments.
+ * </p>
+ * For JLS2:
+ * <pre>
+ * CompilationUnit:
+ * [ PackageDeclaration ]
+ * { ImportDeclaration }
+ * { TypeDeclaration | <b>;</b> }
+ * </pre>
+ * For JLS3, the kinds of type declarations
+ * grew to include enum and annotation type declarations:
+ * <pre>
+ * CompilationUnit:
+ * [ PackageDeclaration ]
+ * { ImportDeclaration }
+ * { TypeDeclaration | EnumDeclaration | AnnotationTypeDeclaration | <b>;</b> }
+ * </pre>
+ *
+ * @since 2.0
+ */
+public class CompilationUnit {
+
+// /**
+// * The "package" structural property of this node type.
+// *
+// * @since 3.0
+// */
+// public static final ChildPropertyDescriptor PACKAGE_PROPERTY =
+// new ChildPropertyDescriptor(CompilationUnit.class, "package", PackageDeclaration.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
+//
+// /**
+// * The "imports" structural property of this node type.
+// *
+// * @since 3.0
+// */
+// public static final ChildListPropertyDescriptor IMPORTS_PROPERTY =
+// new ChildListPropertyDescriptor(CompilationUnit.class, "imports", ImportDeclaration.class, NO_CYCLE_RISK); //$NON-NLS-1$
+//
+// /**
+// * The "types" structural property of this node type.
+// *
+// * @since 3.0
+// */
+// public static final ChildListPropertyDescriptor TYPES_PROPERTY =
+// new ChildListPropertyDescriptor(CompilationUnit.class, "types", AbstractTypeDeclaration.class, CYCLE_RISK); //$NON-NLS-1$
+//
+// /**
+// * A list of property descriptors (element type:
+// * {@link StructuralPropertyDescriptor}),
+// * or null if uninitialized.
+// * @since 3.0
+// */
+// private static final List PROPERTY_DESCRIPTORS;
+//
+// static {
+// createPropertyList(CompilationUnit.class);
+// addProperty(PACKAGE_PROPERTY);
+// addProperty(IMPORTS_PROPERTY);
+// addProperty(TYPES_PROPERTY);
+// PROPERTY_DESCRIPTORS = reapPropertyList();
+// }
+//
+// /**
+// * Returns a list of structural property descriptors for this node type.
+// * Clients must not modify the result.
+// *
+// * @param apiLevel the API level; one of the
+// * <code>AST.JLS*</code> constants
+//
+// * @return a list of property descriptors (element type:
+// * {@link StructuralPropertyDescriptor})
+// * @since 3.0
+// */
+// public static List propertyDescriptors(int apiLevel) {
+// return PROPERTY_DESCRIPTORS;
+// }
+//
+// /**
+// * The comment table, or <code>null</code> if none; initially
+// * <code>null</code>. This array is the storage underlying
+// * the <code>optionalCommentList</code> ArrayList.
+// * @since 3.0
+// */
+// Comment[] optionalCommentTable = null;
+//
+// /**
+// * The comment list (element type: <code>Comment</code>,
+// * or <code>null</code> if none; initially <code>null</code>.
+// * @since 3.0
+// */
+// private List optionalCommentList = null;
+//
+// /**
+// * The package declaration, or <code>null</code> if none; initially
+// * <code>null</code>.
+// */
+// private PackageDeclaration optionalPackageDeclaration = null;
+//
+// /**
+// * The list of import declarations in textual order order;
+// * initially none (elementType: <code>ImportDeclaration</code>).
+// */
+// private ASTNode.NodeList imports =
+// new ASTNode.NodeList(IMPORTS_PROPERTY);
+//
+// /**
+// * The list of type declarations in textual order order;
+// * initially none (elementType: <code>AbstractTypeDeclaration</code>)
+// */
+// private ASTNode.NodeList types =
+// new ASTNode.NodeList(TYPES_PROPERTY);
+//
+// /**
+// * Line end table. If <code>lineEndTable[i] == p</code> then the
+// * line number <code>i+1</code> ends at character position
+// * <code>p</code>. Except for the last line, the positions are that
+// * of the last character of the line delimiter.
+// * For example, the source string <code>A\nB\nC</code> has
+// * line end table {1, 3} (if \n is one character).
+// */
+// private int[] lineEndTable = new int[0];
+//
+// /**
+// * Canonical empty list of messages.
+// */
+// private static final Message[] EMPTY_MESSAGES = new Message[0];
+//
+// /**
+// * Canonical empty list of problems.
+// */
+// private static final IProblem[] EMPTY_PROBLEMS = new IProblem[0];
+//
+// /**
+// * Messages reported by the compiler during parsing or name resolution.
+// */
+// private Message[] messages;
+//
+// /**
+// * Problems reported by the compiler during parsing or name resolution.
+// */
+// private IProblem[] problems = EMPTY_PROBLEMS;
+//
+// /**
+// * The comment mapper, or <code>null</code> in none;
+// * initially <code>null</code>.
+// * @since 3.0
+// */
+// private DefaultCommentMapper commentMapper = null;
+//
+// /**
+// * Sets the line end table for this compilation unit.
+// * If <code>lineEndTable[i] == p</code> then line number <code>i+1</code>
+// * ends at character position <code>p</code>. Except for the last line, the
+// * positions are that of (the last character of) the line delimiter.
+// * For example, the source string <code>A\nB\nC</code> has
+// * line end table {1, 3, 4}.
+// *
+// * @param lineEndtable the line end table
+// */
+// void setLineEndTable(int[] lineEndTable) {
+// if (lineEndTable == null) {
+// throw new NullPointerException();
+// }
+// // alternate root is *not* considered a structural property
+// // but we protect them nevertheless
+// checkModifiable();
+// this.lineEndTable = lineEndTable;
+// }
+//
+// /**
+// * Creates a new AST node for a compilation owned by the given AST.
+// * The compilation unit initially has no package declaration, no
+// * import declarations, and no type declarations.
+// * <p>
+// * N.B. This constructor is package-private; all subclasses must be
+// * declared in the same package; clients are unable to declare
+// * additional subclasses.
+// * </p>
+// *
+// * @param ast the AST that is to own this node
+// */
+// CompilationUnit(AST ast) {
+// super(ast);
+// }
+//
+// /* (omit javadoc for this method)
+// * Method declared on ASTNode.
+// * @since 3.0
+// */
+// final List internalStructuralPropertiesForType(int apiLevel) {
+// return propertyDescriptors(apiLevel);
+// }
+//
+// /* (omit javadoc for this method)
+// * Method declared on ASTNode.
+// */
+// final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+// if (property == PACKAGE_PROPERTY) {
+// if (get) {
+// return getPackage();
+// } else {
+// setPackage((PackageDeclaration) child);
+// return null;
+// }
+// }
+// // allow default implementation to flag the error
+// return super.internalGetSetChildProperty(property, get, child);
+// }
+//
+// /* (omit javadoc for this method)
+// * Method declared on ASTNode.
+// */
+// final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+// if (property == IMPORTS_PROPERTY) {
+// return imports();
+// }
+// if (property == TYPES_PROPERTY) {
+// return types();
+// }
+// // allow default implementation to flag the error
+// return super.internalGetChildListProperty(property);
+// }
+//
+// /* (omit javadoc for this method)
+// * Method declared on ASTNode.
+// */
+// final int getNodeType0() {
+// return COMPILATION_UNIT;
+// }
+//
+// /* (omit javadoc for this method)
+// * Method declared on ASTNode.
+// */
+// ASTNode clone0(AST target) {
+// CompilationUnit result = new CompilationUnit(target);
+// // n.b do not copy line number table or messages
+// result.setSourceRange(this.getStartPosition(), this.getLength());
+// result.setPackage(
+// (PackageDeclaration) ASTNode.copySubtree(target, getPackage()));
+// result.imports().addAll(ASTNode.copySubtrees(target, imports()));
+// result.types().addAll(ASTNode.copySubtrees(target, types()));
+// return result;
+// }
+//
+// /* (omit javadoc for this method)
+// * Method declared on ASTNode.
+// */
+// final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+// // dispatch to correct overloaded match method
+// return matcher.match(this, other);
+// }
+//
+// /* (omit javadoc for this method)
+// * Method declared on ASTNode.
+// */
+// void accept0(ASTVisitor visitor) {
+// boolean visitChildren = visitor.visit(this);
+// if (visitChildren) {
+// // visit children in normal left to right reading order
+// acceptChild(visitor, getPackage());
+// acceptChildren(visitor, this.imports);
+// acceptChildren(visitor, this.types);
+// }
+// visitor.endVisit(this);
+// }
+//
+// /**
+// * Returns the node for the package declaration of this compilation
+// * unit, or <code>null</code> if this compilation unit is in the
+// * default package.
+// *
+// * @return the package declaration node, or <code>null</code> if none
+// */
+// public PackageDeclaration getPackage() {
+// return this.optionalPackageDeclaration;
+// }
+//
+// /**
+// * Sets or clears the package declaration of this compilation unit
+// * node to the given package declaration node.
+// *
+// * @param pkgDecl the new package declaration node, or
+// * <code>null</code> if this compilation unit does not have a package
+// * declaration (that is in the default package)
+// * @exception IllegalArgumentException if:
+// * <ul>
+// * <li>the node belongs to a different AST</li>
+// * <li>the node already has a parent</li>
+// * </ul>
+// */
+// public void setPackage(PackageDeclaration pkgDecl) {
+// ASTNode oldChild = this.optionalPackageDeclaration;
+// preReplaceChild(oldChild, pkgDecl, PACKAGE_PROPERTY);
+// this.optionalPackageDeclaration = pkgDecl;
+// postReplaceChild(oldChild, pkgDecl, PACKAGE_PROPERTY);
+// }
+//
+// /**
+// * Returns the live list of nodes for the import declarations of this
+// * compilation unit, in order of appearance.
+// *
+// * @return the live list of import declaration nodes
+// * (elementType: <code>ImportDeclaration</code>)
+// */
+// public List imports() {
+// return this.imports;
+// }
+//
+// /**
+// * Returns the live list of nodes for the top-level type declarations of this
+// * compilation unit, in order of appearance.
+// * <p>
+// * Note that in JLS3, the types may include both enum declarations
+// * and annotation type declarations introduced in J2SE 1.5.
+// * For JLS2, the elements are always <code>TypeDeclaration</code>.
+// * </p>
+// *
+// * @return the live list of top-level type declaration
+// * nodes (elementType: <code>AbstractTypeDeclaration</code>)
+// */
+// public List types() {
+// return this.types;
+// }
+//
+// /**
+// * Finds the corresponding AST node in the given compilation unit from
+// * which the given binding originated. Returns <code>null</code> if the
+// * binding does not correspond to any node in this compilation unit.
+// * This method always returns <code>null</code> if bindings were not requested
+// * when this AST was built.
+// * <p>
+// * The following table indicates the expected node type for the various
+// * different kinds of bindings:
+// * <ul>
+// * <li></li>
+// * <li>package - a <code>PackageDeclaration</code></li>
+// * <li>class or interface - a <code>TypeDeclaration</code> or a
+// * <code>AnonymousClassDeclaration</code> (for anonymous classes)</li>
+// * <li>primitive type - none</li>
+// * <li>array type - none</li>
+// * <li>field - a <code>VariableDeclarationFragment</code> in a
+// * <code>FieldDeclaration</code> </li>
+// * <li>local variable - a <code>SingleVariableDeclaration</code>, or
+// * a <code>VariableDeclarationFragment</code> in a
+// * <code>VariableDeclarationStatement</code> or
+// * <code>VariableDeclarationExpression</code></li>
+// * <li>method - a <code>MethodDeclaration</code> </li>
+// * <li>constructor - a <code>MethodDeclaration</code> </li>
+// * <li>annotation type - an <code>AnnotationTypeDeclaration</code></li>
+// * <li>annotation type member - an <code>AnnotationTypeMemberDeclaration</code></li>
+// * <li>enum type - an <code>EnumDeclaration</code></li>
+// * <li>enum constant - an <code>EnumConstantDeclaration</code></li>
+// * </ul>
+// * </p>
+// * <p>
+// * Each call to {@link ASTParser#createAST(IProgressMonitor)} with a request for bindings
+// * gives rise to separate universe of binding objects. This method always returns
+// * <code>null</code> when the binding object comes from a different AST.
+// * Use <code>findDeclaringNode(binding.getKey())</code> when the binding comes
+// * from a different AST.
+// * </p>
+// *
+// * @param binding the binding
+// * @return the corresponding node where the given binding is declared,
+// * or <code>null</code> if the binding does not correspond to a node in this
+// * compilation unit or if bindings were not requested when this AST was built
+// * @see #findDeclaringNode(String)
+// */
+// public ASTNode findDeclaringNode(IBinding binding) {
+// return this.ast.getBindingResolver().findDeclaringNode(binding);
+// }
+//
+// /**
+// * Finds the corresponding AST node in the given compilation unit from
+// * which the binding with the given key originated. Returns
+// * <code>null</code> if the corresponding node cannot be determined.
+// * This method always returns <code>null</code> if bindings were not requested
+// * when this AST was built.
+// * <p>
+// * The following table indicates the expected node type for the various
+// * different kinds of binding keys:
+// * <ul>
+// * <li></li>
+// * <li>package - a <code>PackageDeclaration</code></li>
+// * <li>class or interface - a <code>TypeDeclaration</code> or a
+// * <code>AnonymousClassDeclaration</code> (for anonymous classes)</li>
+// * <li>primitive type - none</li>
+// * <li>array type - none</li>
+// * <li>field - a <code>VariableDeclarationFragment</code> in a
+// * <code>FieldDeclaration</code> </li>
+// * <li>local variable - a <code>SingleVariableDeclaration</code>, or
+// * a <code>VariableDeclarationFragment</code> in a
+// * <code>VariableDeclarationStatement</code> or
+// * <code>VariableDeclarationExpression</code></li>
+// * <li>method - a <code>MethodDeclaration</code> </li>
+// * <li>constructor - a <code>MethodDeclaration</code> </li>
+// * <li>annotation type - an <code>AnnotationTypeDeclaration</code></li>
+// * <li>annotation type member - an <code>AnnotationTypeMemberDeclaration</code></li>
+// * <li>enum type - an <code>EnumDeclaration</code></li>
+// * <li>enum constant - an <code>EnumConstantDeclaration</code></li>
+// * </ul>
+// * </p>
+// * <p>
+// * Note that as explained in {@link IBinding#getKey() IBinding.getkey}
+// * there may be no keys for finding the declaring node for local variables,
+// * local or anonymous classes, etc.
+// * </p>
+// *
+// * @param key the binding key, or <code>null</code>
+// * @return the corresponding node where a binding with the given
+// * key is declared, or <code>null</code> if the key is <code>null</code>
+// * or if the key does not correspond to a node in this compilation unit
+// * or if bindings were not requested when this AST was built
+// * @see IBinding#getKey()
+// * @since 2.1
+// */
+// public ASTNode findDeclaringNode(String key) {
+// return this.ast.getBindingResolver().findDeclaringNode(key);
+// }
+//
+// /**
+// * Returns the internal comment mapper.
+// *
+// * @return the comment mapper, or <code>null</code> if none.
+// * @since 3.0
+// */
+// DefaultCommentMapper getCommentMapper() {
+// return this.commentMapper;
+// }
+//
+// /**
+// * Initializes the internal comment mapper with the given
+// * scanner.
+// *
+// * @param scanner the scanner
+// * @since 3.0
+// */
+// void initCommentMapper(Scanner scanner) {
+// this.commentMapper = new DefaultCommentMapper(this.optionalCommentTable);
+// this.commentMapper.initialize(this, scanner);
+// }
+//
+// /**
+// * Returns the extended start position of the given node. Unlike
+// * {@link ASTNode#getStartPosition()} and {@link ASTNode#getLength()()},
+// * the extended source range may include comments and whitespace
+// * immediately before or after the normal source range for the node.
+// *
+// * @param node the node
+// * @return the 0-based character index, or <code>-1</code>
+// * if no source position information is recorded for this node
+// * @see #getExtendedLength(ASTNode)
+// * @since 3.0
+// */
+// public int getExtendedStartPosition(ASTNode node) {
+// if (this.commentMapper == null) {
+// return -1;
+// } else {
+// return this.commentMapper.getExtendedStartPosition(node);
+// }
+// }
+//
+// /**
+// * Returns the extended source length of the given node. Unlike
+// * {@link ASTNode#getStartPosition()} and {@link ASTNode#getLength()()},
+// * the extended source range may include comments and whitespace
+// * immediately before or after the normal source range for the node.
+// *
+// * @param node the node
+// * @return a (possibly 0) length, or <code>0</code>
+// * if no source position information is recorded for this node
+// * @see #getExtendedStartPosition(ASTNode)
+// * @since 3.0
+// */
+// public int getExtendedLength(ASTNode node) {
+// if (this.commentMapper == null) {
+// return 0;
+// } else {
+// return this.commentMapper.getExtendedLength(node);
+// }
+// }
+//
+// /**
+// * Returns the line number corresponding to the given source character
+// * position in the original source string. The initial line of the
+// * compilation unit is numbered 1, and each line extends through the
+// * last character of the end-of-line delimiter. The very last line extends
+// * through the end of the source string and has no line delimiter.
+// * For example, the source string <code>class A\n{\n}</code> has 3 lines
+// * corresponding to inclusive character ranges [0,7], [8,9], and [10,10].
+// * Returns 1 for a character position that does not correspond to any
+// * source line, or if no line number information is available for this
+// * compilation unit.
+// *
+// * @param position a 0-based character position, possibly
+// * negative or out of range
+// * @return the 1-based line number, or <code>1</code> if the character
+// * position does not correspond to a source line in the original
+// * source file or if line number information is not known for this
+// * compilation unit
+// * @see ASTParser
+// */
+// public int lineNumber(int position) {
+// int length = lineEndTable.length;
+// if (length == 0) {
+// // no line number info
+// return 1;
+// }
+// int low = 0;
+// if (position <= lineEndTable[low]) {
+// // position illegal or before the first line delimiter
+// return 1;
+// }
+// // assert position > lineEndTable[low+1] && low == 0
+// int hi = length - 1;
+// if (position > lineEndTable[hi]) {
+// // position beyond the last line separator
+// if (position >= getStartPosition() + getLength()) {
+// // this is beyond the end of the source length
+// return 1;
+// } else {
+// return length + 1;
+// }
+// }
+// // assert lineEndTable[low] < position <= lineEndTable[hi]
+// // && low == 0 && hi == length - 1 && low < hi
+//
+// // binary search line end table
+// while (true) {
+// // invariant lineEndTable[low] < position <= lineEndTable[hi]
+// // && 0 <= low < hi <= length - 1
+// // reducing measure hi - low
+// if (low + 1 == hi) {
+// // assert lineEndTable[low] < position <= lineEndTable[low+1]
+// // position is on line low+1 (line number is low+2)
+// return low + 2;
+// }
+// // assert hi - low >= 2, so average is truly in between
+// int mid = (low + hi) / 2;
+// // assert 0 <= low < mid < hi <= length - 1
+// if (position <= lineEndTable[mid]) {
+// // assert lineEndTable[low] < position <= lineEndTable[mid]
+// // && 0 <= low < mid < hi <= length - 1
+// hi = mid;
+// } else {
+// // position > lineEndTable[mid]
+// // assert lineEndTable[mid] < position <= lineEndTable[hi]
+// // && 0 <= low < mid < hi <= length - 1
+// low = mid;
+// }
+// // in both cases, invariant reachieved with reduced measure
+// }
+// }
+//
+// /**
+// * Returns the list of messages reported by the compiler during the parsing
+// * or the type checking of this compilation unit. This list might be a subset of
+// * errors detected and reported by a Java compiler.
+// * <p>
+// * This list of messages is suitable for simple clients that do little
+// * more than log the messages or display them to the user. Clients that
+// * need further details should call <code>getProblems</code> to get
+// * compiler problem objects.
+// * </p>
+// *
+// * @return the list of messages, possibly empty
+// * @see #getProblems()
+// * @see ASTParser
+// */
+// public Message[] getMessages() {
+// if (this.messages == null) {
+// int problemLength = this.problems.length;
+// if (problemLength == 0) {
+// this.messages = EMPTY_MESSAGES;
+// } else {
+// this.messages = new Message[problemLength];
+// for (int i = 0; i < problemLength; i++) {
+// IProblem problem = this.problems[i];
+// int start = problem.getSourceStart();
+// int end = problem.getSourceEnd();
+// messages[i] = new Message(problem.getMessage(), start, end - start + 1);
+// }
+// }
+// }
+// return this.messages;
+// }
+//
+// /**
+// * Returns the list of detailed problem reports noted by the compiler
+// * during the parsing or the type checking of this compilation unit. This
+// * list might be a subset of errors detected and reported by a Java
+// * compiler.
+// * <p>
+// * Simple clients that do little more than log the messages or display
+// * them to the user should probably call <code>getMessages</code> instead.
+// * </p>
+// *
+// * @return the list of detailed problem objects, possibly empty
+// * @see #getMessages()
+// * @see ASTParser
+// * @since 2.1
+// */
+// public IProblem[] getProblems() {
+// return this.problems;
+// }
+//
+// /**
+// * Sets the array of problems reported by the compiler during the parsing or
+// * name resolution of this compilation unit.
+// *
+// * @param problems the list of problems
+// */
+// void setProblems(IProblem[] problems) {
+// if (problems == null) {
+// throw new IllegalArgumentException();
+// }
+// this.problems = problems;
+// }
+//
+// /**
+// * Returns a list of the comments encountered while parsing
+// * this compilation unit.
+// * <p>
+// * Since the Java language allows comments to appear most anywhere
+// * in the source text, it is problematic to locate comments in relation
+// * to the structure of an AST. The one exception is doc comments
+// * which, by convention, immediately precede type, field, and
+// * method declarations; these comments are located in the AST
+// * by {@link BodyDeclaration#getJavadoc BodyDeclaration.getJavadoc}.
+// * Other comments do not show up in the AST. The table of comments
+// * is provided for clients that need to find the source ranges of
+// * all comments in the original source string. It includes entries
+// * for comments of all kinds (line, block, and doc), arranged in order
+// * of increasing source position.
+// * </p>
+// * Note on comment parenting: The {@link ASTNode#getParent() getParent()}
+// * of a doc comment associated with a body declaration is the body
+// * declaration node; for these comment nodes
+// * {@link ASTNode#getRoot() getRoot()} will return the compilation unit
+// * (assuming an unmodified AST) reflecting the fact that these nodes
+// * are property located in the AST for the compilation unit.
+// * However, for other comment nodes, {@link ASTNode#getParent() getParent()}
+// * will return <code>null</code>, and {@link ASTNode#getRoot() getRoot()}
+// * will return the comment node itself, indicating that these comment nodes
+// * are not directly connected to the AST for the compilation unit. The
+// * {@link Comment#getAlternateRoot Comment.getAlternateRoot}
+// * method provides a way to navigate from a comment to its compilation
+// * unit.
+// * </p>
+// * <p>
+// * A note on visitors: The only comment nodes that will be visited when
+// * visiting a compilation unit are the doc comments parented by body
+// * declarations. To visit all comments in normal reading order, iterate
+// * over the comment table and call {@link ASTNode#accept(ASTVisitor) accept}
+// * on each element.
+// * </p>
+// * <p>
+// * Clients cannot modify the resulting list.
+// * </p>
+// *
+// * @return an unmodifiable list of comments in increasing order of source
+// * start position, or <code>null</code> if comment information
+// * for this compilation unit is not available
+// * @see ASTParser
+// * @since 3.0
+// */
+// public List getCommentList() {
+// return this.optionalCommentList;
+// }
+//
+// /**
+// * Sets the list of the comments encountered while parsing
+// * this compilation unit.
+// *
+// * @param commentTable a list of comments in increasing order
+// * of source start position, or <code>null</code> if comment
+// * information for this compilation unit is not available
+// * @exception IllegalArgumentException if the comment table is
+// * not in increasing order of source position
+// * @see #getCommentList()
+// * @see ASTParser
+// * @since 3.0
+// */
+// void setCommentTable(Comment[] commentTable) {
+// // double check table to ensure that all comments have
+// // source positions and are in strictly increasing order
+// if (commentTable == null) {
+// this.optionalCommentList = null;
+// this.optionalCommentTable = null;
+// } else {
+// int nextAvailablePosition = 0;
+// for (int i = 0; i < commentTable.length; i++) {
+// Comment comment = commentTable[i];
+// if (comment == null) {
+// throw new IllegalArgumentException();
+// }
+// int start = comment.getStartPosition();
+// int length = comment.getLength();
+// if (start < 0 || length < 0 || start < nextAvailablePosition) {
+// throw new IllegalArgumentException();
+// }
+// nextAvailablePosition = comment.getStartPosition() + comment.getLength();
+// }
+// this.optionalCommentTable = commentTable;
+// List commentList = Arrays.asList(commentTable);
+// // protect the list from further modification
+// this.optionalCommentList = Collections.unmodifiableList(commentList);
+// }
+// }
+//
+//
+// /* (omit javadoc for this method)
+// * Method declared on ASTNode.
+// */
+// void appendDebugString(StringBuffer buffer) {
+// buffer.append("CompilationUnit"); //$NON-NLS-1$
+// // include the type names
+// buffer.append("["); //$NON-NLS-1$
+// for (Iterator it = types().iterator(); it.hasNext(); ) {
+// AbstractTypeDeclaration d = (AbstractTypeDeclaration) it.next();
+// buffer.append(d.getName().getIdentifier());
+// if (it.hasNext()) {
+// buffer.append(","); //$NON-NLS-1$
+// }
+// }
+// buffer.append("]"); //$NON-NLS-1$
+// }
+//
+// /* (omit javadoc for this method)
+// * Method declared on ASTNode.
+// */
+// int memSize() {
+// int size = BASE_NODE_SIZE + 8 * 4;
+// if (this.lineEndTable != null) {
+// size += HEADERS + 4 * this.lineEndTable.length;
+// }
+// if (this.optionalCommentTable != null) {
+// size += HEADERS + 4 * this.optionalCommentTable.length;
+// }
+// // ignore the space taken up by optionalCommentList
+// return size;
+// }
+//
+// /* (omit javadoc for this method)
+// * Method declared on ASTNode.
+// */
+// int treeSize() {
+// int size = memSize();
+// if (this.optionalPackageDeclaration != null) {
+// size += getPackage().treeSize();
+// }
+// size += this.imports.listSize();
+// size += this.types.listSize();
+// // include disconnected comments
+// if (this.optionalCommentList != null) {
+// for (int i = 0; i < this.optionalCommentList.size(); i++) {
+// Comment comment = (Comment) this.optionalCommentList.get(i);
+// if (comment != null && comment.getParent() == null) {
+// size += comment.treeSize();
+// }
+// }
+// }
+// return size;
+// }
+//
+// /**
+// * Enables the recording of changes to this compilation
+// * unit and its descendents. The compilation unit must have
+// * been created by <code>ASTParser</code> and still be in
+// * its original state. Once recording is on,
+// * arbitrary changes to the subtree rooted at this compilation
+// * unit are recorded internally. Once the modification has
+// * been completed, call <code>rewrite</code> to get an object
+// * representing the corresponding edits to the original
+// * source code string.
+// *
+// * @exception IllegalArgumentException if this compilation unit is
+// * marked as unmodifiable, or if this compilation unit has already
+// * been tampered with, or recording has already been enabled
+// * @since 3.0
+// */
+// public void recordModifications() {
+// getAST().recordModifications(this);
+// }
+//
+// /**
+// * Converts all modifications recorded for this compilation
+// * unit into an object representing the corresponding text
+// * edits to the given document containing the original source
+// * code for this compilation unit.
+// * <p>
+// * The compilation unit must have been created by
+// * <code>ASTParser</code> from the source code string in the
+// * given document, and recording must have been turned
+// * on with a prior call to <code>recordModifications</code>
+// * while the AST was still in its original state.
+// * </p>
+// * <p>
+// * Calling this methods does not discard the modifications
+// * on record. Subsequence modifications made to the AST
+// * are added to the ones already on record. If this method
+// * is called again later, the resulting text edit object will
+// * accurately reflect the net cumulative affect of all those
+// * changes.
+// * </p>
+// *
+// * @param document original document containing source code
+// * for this compilation unit
+// * @param options the table of formatter options
+// * (key type: <code>String</code>; value type: <code>String</code>);
+// * or <code>null</code> to use the standard global options
+// * {@link JavaCore#getOptions() JavaCore.getOptions()}.
+// * @return text edit object describing the changes to the
+// * document corresponding to the recorded AST modifications
+// * @exception IllegalArgumentException if the document passed is
+// * <code>null</code> or does not correspond to this AST
+// * @exception IllegalStateException if <code>recordModifications</code>
+// * was not called to enable recording
+// * @see #recordModifications()
+// * @since 3.0
+// */
+// public TextEdit rewrite(IDocument document, Map options) {
+// return getAST().rewrite(document, options);
+// }
+}
+
*******************************************************************************/
package net.sourceforge.phpdt.core.jdom;
-import net.sourceforge.phpdt.internal.core.Util;
import net.sourceforge.phpdt.internal.core.jdom.DOMBuilder;
import net.sourceforge.phpdt.internal.core.jdom.SimpleDOMBuilder;
+import net.sourceforge.phpdt.internal.core.util.Util;
/**
import org.eclipse.core.runtime.CoreException;
/**
- * @author jsurfer
- *
+ *
*
*/
public class UnitParser extends Parser {
new Integer(problem.getSourceStart()),
new Integer(problem.getSourceEnd() + 1),
new Integer(problem.getSourceLineNumber()),
- net.sourceforge.phpdt.internal.core.Util.getProblemArgumentsForMarker(problem.getArguments())});
+ net.sourceforge.phpdt.internal.core.util.Util.getProblemArgumentsForMarker(problem.getArguments())});
}
}
import java.util.zip.ZipFile;
import net.sourceforge.phpdt.core.compiler.CharOperation;
+import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil;
public class Util {
* implementation is not creating extra strings.
*/
public final static boolean isJavaFileName(String name) {
- int nameLength = name == null ? 0 : name.length();
- int suffixLength = SUFFIX_JAVA.length;
- if (nameLength < suffixLength) return false;
-
- for (int i = 0; i < suffixLength; i++) {
- char c = name.charAt(nameLength - i - 1);
- int suffixIndex = suffixLength - i - 1;
- if (c != SUFFIX_java[suffixIndex] && c != SUFFIX_JAVA[suffixIndex]) return false;
- }
- return true;
+ return PHPFileUtil.isPHPFileName(name);
+// int nameLength = name == null ? 0 : name.length();
+// int suffixLength = SUFFIX_JAVA.length;
+// if (nameLength < suffixLength) return false;
+//
+// for (int i = 0; i < suffixLength; i++) {
+// char c = name.charAt(nameLength - i - 1);
+// int suffixIndex = suffixLength - i - 1;
+// if (c != SUFFIX_java[suffixIndex] && c != SUFFIX_JAVA[suffixIndex]) return false;
+// }
+// return true;
}
}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.core.util;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.StringTokenizer;
+
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IJavaModelStatusConstants;
+import net.sourceforge.phpdt.core.IPackageFragment;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.core.Signature;
+import net.sourceforge.phpdt.core.compiler.CharOperation;
+import net.sourceforge.phpdt.internal.core.PackageFragmentRoot;
+import net.sourceforge.phpdt.internal.corext.Assert;
+import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+
+/**
+ * Provides convenient utility methods to other types in this package.
+ */
+public class Util {
+
+ private final static char[] DOUBLE_QUOTES = "''".toCharArray(); //$NON-NLS-1$
+ private final static char[] SINGLE_QUOTE = "'".toCharArray(); //$NON-NLS-1$
+ private static final String ARGUMENTS_DELIMITER = "#"; //$NON-NLS-1$
+ private static final String EMPTY_ARGUMENT = " "; //$NON-NLS-1$
+
+ public interface Comparable {
+ /**
+ * Returns 0 if this and c are equal, >0 if this is greater than c,
+ * or <0 if this is less than c.
+ */
+ int compareTo(Comparable c);
+ }
+
+ public interface Comparer {
+ /**
+ * Returns 0 if a and b are equal, >0 if a is greater than b,
+ * or <0 if a is less than b.
+ */
+ int compare(Object a, Object b);
+ }
+
+ public interface Displayable {
+ String displayString(Object o);
+ }
+
+ public static final String[] fgEmptyStringArray = new String[0];
+
+ /**
+ * Are we running JDK 1.1?
+ */
+ private static boolean JDK1_1 = false;
+
+ /* Bundle containing messages */
+ protected static ResourceBundle bundle;
+ private final static String bundleName = "net.sourceforge.phpdt.internal.core.messages"; //$NON-NLS-1$
+
+// public final static char[] SUFFIX_class = ".class".toCharArray(); //$NON-NLS-1$
+// public final static char[] SUFFIX_CLASS = ".CLASS".toCharArray(); //$NON-NLS-1$
+// public final static char[] SUFFIX_java = ".java".toCharArray(); //$NON-NLS-1$
+// public final static char[] SUFFIX_JAVA = ".JAVA".toCharArray(); //$NON-NLS-1$
+// public final static char[] SUFFIX_jar = ".jar".toCharArray(); //$NON-NLS-1$
+// public final static char[] SUFFIX_JAR = ".JAR".toCharArray(); //$NON-NLS-1$
+// public final static char[] SUFFIX_zip = ".zip".toCharArray(); //$NON-NLS-1$
+// public final static char[] SUFFIX_ZIP = ".ZIP".toCharArray(); //$NON-NLS-1$
+
+ static {
+ String ver = System.getProperty("java.version"); //$NON-NLS-1$
+ JDK1_1 = ((ver != null) && ver.startsWith("1.1")); //$NON-NLS-1$
+ relocalize();
+ }
+
+ /**
+ * Lookup the message with the given ID in this catalog
+ */
+ public static String bind(String id) {
+ return bind(id, (String[])null);
+ }
+
+ /**
+ * Lookup the message with the given ID in this catalog and bind its
+ * substitution locations with the given string values.
+ */
+ public static String bind(String id, String[] bindings) {
+ if (id == null)
+ return "No message available"; //$NON-NLS-1$
+ String message = null;
+ try {
+ message = bundle.getString(id);
+ } catch (MissingResourceException e) {
+ // If we got an exception looking for the message, fail gracefully by just returning
+ // the id we were looking for. In most cases this is semi-informative so is not too bad.
+ return "Missing message: " + id + " in: " + bundleName; //$NON-NLS-2$ //$NON-NLS-1$
+ }
+ // for compatibility with MessageFormat which eliminates double quotes in original message
+ char[] messageWithNoDoubleQuotes =
+ CharOperation.replace(message.toCharArray(), DOUBLE_QUOTES, SINGLE_QUOTE);
+ message = new String(messageWithNoDoubleQuotes);
+
+ if (bindings == null)
+ return message;
+
+ int length = message.length();
+ int start = -1;
+ int end = length;
+ StringBuffer output = new StringBuffer(80);
+ while (true) {
+ if ((end = message.indexOf('{', start)) > -1) {
+ output.append(message.substring(start + 1, end));
+ if ((start = message.indexOf('}', end)) > -1) {
+ int index = -1;
+ try {
+ index = Integer.parseInt(message.substring(end + 1, start));
+ output.append(bindings[index]);
+ } catch (NumberFormatException nfe) {
+ output.append(message.substring(end + 1, start + 1));
+ } catch (ArrayIndexOutOfBoundsException e) {
+ output.append("{missing " + Integer.toString(index) + "}"); //$NON-NLS-2$ //$NON-NLS-1$
+ }
+ } else {
+ output.append(message.substring(end, length));
+ break;
+ }
+ } else {
+ output.append(message.substring(start + 1, length));
+ break;
+ }
+ }
+ return output.toString();
+ }
+
+ /**
+ * Lookup the message with the given ID in this catalog and bind its
+ * substitution locations with the given string.
+ */
+ public static String bind(String id, String binding) {
+ return bind(id, new String[] {binding});
+ }
+
+ /**
+ * Lookup the message with the given ID in this catalog and bind its
+ * substitution locations with the given strings.
+ */
+ public static String bind(String id, String binding1, String binding2) {
+ return bind(id, new String[] {binding1, binding2});
+ }
+
+ /**
+ * Checks the type signature in String sig,
+ * starting at start and ending before end (end is not included).
+ * Returns the index of the character immediately after the signature if valid,
+ * or -1 if not valid.
+ */
+ private static int checkTypeSignature(String sig, int start, int end, boolean allowVoid) {
+ if (start >= end) return -1;
+ int i = start;
+ char c = sig.charAt(i++);
+ int nestingDepth = 0;
+ while (c == '[') {
+ ++nestingDepth;
+ if (i >= end) return -1;
+ c = sig.charAt(i++);
+ }
+ switch (c) {
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'F':
+ case 'I':
+ case 'J':
+ case 'S':
+ case 'Z':
+ break;
+ case 'V':
+ if (!allowVoid) return -1;
+ // array of void is not allowed
+ if (nestingDepth != 0) return -1;
+ break;
+ case 'L':
+ int semicolon = sig.indexOf(';', i);
+ // Must have at least one character between L and ;
+ if (semicolon <= i || semicolon >= end) return -1;
+ i = semicolon + 1;
+ break;
+ default:
+ return -1;
+ }
+ return i;
+ }
+
+ /**
+ * Combines two hash codes to make a new one.
+ */
+ public static int combineHashCodes(int hashCode1, int hashCode2) {
+ return hashCode1 * 17 + hashCode2;
+ }
+
+ /**
+ * Compares two byte arrays.
+ * Returns <0 if a byte in a is less than the corresponding byte in b, or if a is shorter, or if a is null.
+ * Returns >0 if a byte in a is greater than the corresponding byte in b, or if a is longer, or if b is null.
+ * Returns 0 if they are equal or both null.
+ */
+ public static int compare(byte[] a, byte[] b) {
+ if (a == b)
+ return 0;
+ if (a == null)
+ return -1;
+ if (b == null)
+ return 1;
+ int len = Math.min(a.length, b.length);
+ for (int i = 0; i < len; ++i) {
+ int diff = a[i] - b[i];
+ if (diff != 0)
+ return diff;
+ }
+ if (a.length > len)
+ return 1;
+ if (b.length > len)
+ return -1;
+ return 0;
+ }
+
+ /**
+ * Compares two char arrays lexicographically.
+ * The comparison is based on the Unicode value of each character in
+ * the char arrays.
+ * @return the value <code>0</code> if a is equal to
+ * b; a value less than <code>0</code> if a
+ * is lexicographically less than b; and a
+ * value greater than <code>0</code> if a is
+ * lexicographically greater than b.
+ */
+ public static int compare(char[] v1, char[] v2) {
+ int len1 = v1.length;
+ int len2 = v2.length;
+ int n = Math.min(len1, len2);
+ int i = 0;
+ while (n-- != 0) {
+ if (v1[i] != v2[i]) {
+ return v1[i] - v2[i];
+ }
+ ++i;
+ }
+ return len1 - len2;
+ }
+
+ /**
+ * Concatenate two strings with a char in between.
+ * @see #concat(String, String)
+ */
+ public static String concat(String s1, char c, String s2) {
+ if (s1 == null) s1 = "null"; //$NON-NLS-1$
+ if (s2 == null) s2 = "null"; //$NON-NLS-1$
+ int l1 = s1.length();
+ int l2 = s2.length();
+ char[] buf = new char[l1 + 1 + l2];
+ s1.getChars(0, l1, buf, 0);
+ buf[l1] = c;
+ s2.getChars(0, l2, buf, l1 + 1);
+ return new String(buf);
+ }
+
+ /**
+ * Concatenate two strings.
+ * Much faster than using +, which:
+ * - creates a StringBuffer,
+ * - which is synchronized,
+ * - of default size, so the resulting char array is
+ * often larger than needed.
+ * This implementation creates an extra char array, since the
+ * String constructor copies its argument, but there's no way around this.
+ */
+ public static String concat(String s1, String s2) {
+ if (s1 == null) s1 = "null"; //$NON-NLS-1$
+ if (s2 == null) s2 = "null"; //$NON-NLS-1$
+ int l1 = s1.length();
+ int l2 = s2.length();
+ char[] buf = new char[l1 + l2];
+ s1.getChars(0, l1, buf, 0);
+ s2.getChars(0, l2, buf, l1);
+ return new String(buf);
+ }
+
+ /**
+ * Concatenate three strings.
+ * @see #concat(String, String)
+ */
+ public static String concat(String s1, String s2, String s3) {
+ if (s1 == null) s1 = "null"; //$NON-NLS-1$
+ if (s2 == null) s2 = "null"; //$NON-NLS-1$
+ if (s3 == null) s3 = "null"; //$NON-NLS-1$
+ int l1 = s1.length();
+ int l2 = s2.length();
+ int l3 = s3.length();
+ char[] buf = new char[l1 + l2 + l3];
+ s1.getChars(0, l1, buf, 0);
+ s2.getChars(0, l2, buf, l1);
+ s3.getChars(0, l3, buf, l1 + l2);
+ return new String(buf);
+ }
+
+ /**
+ * Converts a type signature from the IBinaryType representation to the DC representation.
+ */
+ public static String convertTypeSignature(char[] sig) {
+ return new String(sig).replace('/', '.');
+ }
+
+ /**
+ * Returns true iff str.toLowerCase().endsWith(end.toLowerCase())
+ * implementation is not creating extra strings.
+ */
+ public final static boolean endsWithIgnoreCase(String str, String end) {
+
+ int strLength = str == null ? 0 : str.length();
+ int endLength = end == null ? 0 : end.length();
+
+ // return false if the string is smaller than the end.
+ if(endLength > strLength)
+ return false;
+
+ // return false if any character of the end are
+ // not the same in lower case.
+ for(int i = 1 ; i <= endLength; i++){
+ if(Character.toLowerCase(end.charAt(endLength - i)) != Character.toLowerCase(str.charAt(strLength - i)))
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Compares two arrays using equals() on the elements.
+ * Either or both arrays may be null.
+ * Returns true if both are null.
+ * Returns false if only one is null.
+ * If both are arrays, returns true iff they have the same length and
+ * all elements are equal.
+ */
+ public static boolean equalArraysOrNull(int[] a, int[] b) {
+ if (a == b)
+ return true;
+ if (a == null || b == null)
+ return false;
+ int len = a.length;
+ if (len != b.length)
+ return false;
+ for (int i = 0; i < len; ++i) {
+ if (a[i] != b[i])
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Compares two arrays using equals() on the elements.
+ * Either or both arrays may be null.
+ * Returns true if both are null.
+ * Returns false if only one is null.
+ * If both are arrays, returns true iff they have the same length and
+ * all elements compare true with equals.
+ */
+ public static boolean equalArraysOrNull(Object[] a, Object[] b) {
+ if (a == b) return true;
+ if (a == null || b == null) return false;
+
+ int len = a.length;
+ if (len != b.length) return false;
+ for (int i = 0; i < len; ++i) {
+ if (a[i] == null) {
+ if (b[i] != null) return false;
+ } else {
+ if (!a[i].equals(b[i])) return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Compares two String arrays using equals() on the elements.
+ * The arrays are first sorted.
+ * Either or both arrays may be null.
+ * Returns true if both are null.
+ * Returns false if only one is null.
+ * If both are arrays, returns true iff they have the same length and
+ * iff, after sorting both arrays, all elements compare true with equals.
+ * The original arrays are left untouched.
+ */
+ public static boolean equalArraysOrNullSortFirst(String[] a, String[] b) {
+ if (a == b) return true;
+ if (a == null || b == null) return false;
+ int len = a.length;
+ if (len != b.length) return false;
+ if (len >= 2) { // only need to sort if more than two items
+ a = sortCopy(a);
+ b = sortCopy(b);
+ }
+ for (int i = 0; i < len; ++i) {
+ if (!a[i].equals(b[i])) return false;
+ }
+ return true;
+ }
+
+ /**
+ * Compares two arrays using equals() on the elements.
+ * The arrays are first sorted.
+ * Either or both arrays may be null.
+ * Returns true if both are null.
+ * Returns false if only one is null.
+ * If both are arrays, returns true iff they have the same length and
+ * iff, after sorting both arrays, all elements compare true with equals.
+ * The original arrays are left untouched.
+ */
+ public static boolean equalArraysOrNullSortFirst(Comparable[] a, Comparable[] b) {
+ if (a == b) return true;
+ if (a == null || b == null) return false;
+ int len = a.length;
+ if (len != b.length) return false;
+ if (len >= 2) { // only need to sort if more than two items
+ a = sortCopy(a);
+ b = sortCopy(b);
+ }
+ for (int i = 0; i < len; ++i) {
+ if (!a[i].equals(b[i])) return false;
+ }
+ return true;
+ }
+
+ /**
+ * Compares two objects using equals().
+ * Either or both array may be null.
+ * Returns true if both are null.
+ * Returns false if only one is null.
+ * Otherwise, return the result of comparing with equals().
+ */
+ public static boolean equalOrNull(Object a, Object b) {
+ if (a == b) {
+ return true;
+ }
+ if (a == null || b == null) {
+ return false;
+ }
+ return a.equals(b);
+ }
+
+ /**
+ * Given a qualified name, extract the last component.
+ * If the input is not qualified, the same string is answered.
+ */
+ public static String extractLastName(String qualifiedName) {
+ int i = qualifiedName.lastIndexOf('.');
+ if (i == -1) return qualifiedName;
+ return qualifiedName.substring(i+1);
+ }
+
+ /**
+ * Extracts the parameter types from a method signature.
+ */
+ public static String[] extractParameterTypes(char[] sig) {
+ int count = getParameterCount(sig);
+ String[] result = new String[count];
+ if (count == 0)
+ return result;
+ int i = CharOperation.indexOf('(', sig) + 1;
+ count = 0;
+ int len = sig.length;
+ int start = i;
+ for (;;) {
+ if (i == len)
+ break;
+ char c = sig[i];
+ if (c == ')')
+ break;
+ if (c == '[') {
+ ++i;
+ } else
+ if (c == 'L') {
+ i = CharOperation.indexOf(';', sig, i + 1) + 1;
+ Assert.isTrue(i != 0);
+ result[count++] = convertTypeSignature(CharOperation.subarray(sig, start, i));
+ start = i;
+ } else {
+ ++i;
+ result[count++] = convertTypeSignature(CharOperation.subarray(sig, start, i));
+ start = i;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Extracts the return type from a method signature.
+ */
+ public static String extractReturnType(String sig) {
+ int i = sig.lastIndexOf(')');
+ Assert.isTrue(i != -1);
+ return sig.substring(i+1);
+ }
+
+ /**
+ * Finds the first line separator used by the given text.
+ *
+ * @return </code>"\n"</code> or </code>"\r"</code> or </code>"\r\n"</code>,
+ * or <code>null</code> if none found
+ */
+ public static String findLineSeparator(char[] text) {
+ // find the first line separator
+ int length = text.length;
+ if (length > 0) {
+ char nextChar = text[0];
+ for (int i = 0; i < length; i++) {
+ char currentChar = nextChar;
+ nextChar = i < length-1 ? text[i+1] : ' ';
+ switch (currentChar) {
+ case '\n': return "\n"; //$NON-NLS-1$
+ case '\r': return nextChar == '\n' ? "\r\n" : "\r"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+ }
+ // not found
+ return null;
+ }
+
+ /**
+ * Returns the line separator used by the given buffer.
+ * Uses the given text if none found.
+ *
+ * @return </code>"\n"</code> or </code>"\r"</code> or </code>"\r\n"</code>
+ */
+ private static String getLineSeparator(char[] text, char[] buffer) {
+ // search in this buffer's contents first
+ String lineSeparator = findLineSeparator(buffer);
+ if (lineSeparator == null) {
+ // search in the given text
+ lineSeparator = findLineSeparator(text);
+ if (lineSeparator == null) {
+ // default to system line separator
+ return System.getProperty("line.separator");
+ }
+ }
+ return lineSeparator;
+ }
+
+ /**
+ * Returns the number of parameter types in a method signature.
+ */
+ public static int getParameterCount(char[] sig) {
+ int i = CharOperation.indexOf('(', sig) + 1;
+ Assert.isTrue(i != 0);
+ int count = 0;
+ int len = sig.length;
+ for (;;) {
+ if (i == len)
+ break;
+ char c = sig[i];
+ if (c == ')')
+ break;
+ if (c == '[') {
+ ++i;
+ } else
+ if (c == 'L') {
+ ++count;
+ i = CharOperation.indexOf(';', sig, i + 1) + 1;
+ Assert.isTrue(i != 0);
+ } else {
+ ++count;
+ ++i;
+ }
+ }
+ return count;
+ }
+
+ /**
+ * Returns the given file's contents as a byte array.
+ */
+ public static byte[] getResourceContentsAsByteArray(IFile file) throws JavaModelException {
+ InputStream stream= null;
+ try {
+ stream = new BufferedInputStream(file.getContents(true));
+ } catch (CoreException e) {
+ throw new JavaModelException(e);
+ }
+ try {
+ return net.sourceforge.phpdt.internal.compiler.util.Util.getInputStreamAsByteArray(stream, -1);
+ } catch (IOException e) {
+ throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION);
+ } finally {
+ try {
+ stream.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ /**
+ * Returns the given file's contents as a character array.
+ */
+ public static char[] getResourceContentsAsCharArray(IFile file) throws JavaModelException {
+ String encoding = JavaCore.create(file.getProject()).getOption(JavaCore.CORE_ENCODING, true);
+ return getResourceContentsAsCharArray(file, encoding);
+ }
+
+ public static char[] getResourceContentsAsCharArray(IFile file, String encoding) throws JavaModelException {
+ InputStream stream= null;
+ try {
+ stream = new BufferedInputStream(file.getContents(true));
+ } catch (CoreException e) {
+ throw new JavaModelException(e, IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST);
+ }
+ try {
+ return net.sourceforge.phpdt.internal.compiler.util.Util.getInputStreamAsCharArray(stream, -1, encoding);
+ } catch (IOException e) {
+ throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION);
+ } finally {
+ try {
+ stream.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ /**
+ * Returns a trimmed version the simples names returned by Signature.
+ */
+ public static String[] getTrimmedSimpleNames(String name) {
+ String[] result = Signature.getSimpleNames(name);
+ if (result == null) return null;
+ for (int i = 0, length = result.length; i < length; i++) {
+ result[i] = result[i].trim();
+ }
+ return result;
+ }
+
+ /**
+ * Returns true iff str.toLowerCase().endsWith(".class")
+ * implementation is not creating extra strings.
+ */
+// public final static boolean isClassFileName(String name) {
+// int nameLength = name == null ? 0 : name.length();
+// int suffixLength = SUFFIX_CLASS.length;
+// if (nameLength < suffixLength) return false;
+//
+// for (int i = 0, offset = nameLength - suffixLength; i < suffixLength; i++) {
+// char c = name.charAt(offset + i);
+// if (c != SUFFIX_class[i] && c != SUFFIX_CLASS[i]) return false;
+// }
+// return true;
+// }
+
+ /*
+ * Returns whether the given java element is exluded from its root's classpath.
+ */
+ public static final boolean isExcluded(IJavaElement element) {
+ int elementType = element.getElementType();
+ PackageFragmentRoot root = null;
+ IResource resource = null;
+ switch (elementType) {
+// case IJavaElement.PACKAGE_FRAGMENT:
+// PackageFragmentRoot root = (PackageFragmentRoot)element.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
+// IResource resource = element.getResource();
+// return resource != null && Util.isExcluded(resource, root.fullExclusionPatternChars());
+ case IJavaElement.COMPILATION_UNIT:
+ root = (PackageFragmentRoot)element.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
+ resource = element.getResource();
+// if (resource != null && Util.isExcluded(resource, root.fullExclusionPatternChars()))
+// return true;
+ return isExcluded(element.getParent());
+ default:
+ IJavaElement cu = element.getAncestor(IJavaElement.COMPILATION_UNIT);
+ return cu != null && isExcluded(cu);
+ }
+ }
+ /*
+ * Returns whether the given resource path matches one of the exclusion
+ * patterns.
+ *
+ * @see IClasspathEntry#getExclusionPatterns
+ */
+ public final static boolean isExcluded(IPath resourcePath, char[][] exclusionPatterns) {
+ if (exclusionPatterns == null) return false;
+ char[] path = resourcePath.toString().toCharArray();
+ for (int i = 0, length = exclusionPatterns.length; i < length; i++)
+ if (CharOperation.pathMatch(exclusionPatterns[i], path, true, '/'))
+ return true;
+ return false;
+ }
+
+ /*
+ * Returns whether the given resource matches one of the exclusion patterns.
+ *
+ * @see IClasspathEntry#getExclusionPatterns
+ */
+ public final static boolean isExcluded(IResource resource, char[][] exclusionPatterns) {
+ IPath path = resource.getFullPath();
+ // ensure that folders are only excluded if all of their children are excluded
+ if (resource.getType() == IResource.FOLDER)
+ path = path.append("*"); //$NON-NLS-1$
+ return isExcluded(path, exclusionPatterns);
+ }
+
+ /**
+ * Returns true iff str.toLowerCase().endsWith(".jar" or ".zip")
+ * implementation is not creating extra strings.
+ */
+// public final static boolean isArchiveFileName(String name) {
+// int nameLength = name == null ? 0 : name.length();
+// int suffixLength = SUFFIX_JAR.length;
+// if (nameLength < suffixLength) return false;
+//
+// int i, offset;
+// for ( i = 0, offset = nameLength - suffixLength; i < suffixLength; i++) {
+// char c = name.charAt(offset + i);
+// if (c != SUFFIX_jar[i] && c != SUFFIX_JAR[i]) break;
+// }
+// if (i == suffixLength) return true;
+// for ( i = 0, offset = nameLength - suffixLength; i < suffixLength; i++) {
+// char c = name.charAt(offset + i);
+// if (c != SUFFIX_zip[i] && c != SUFFIX_ZIP[i]) return false;
+// }
+// return true;
+// }
+
+ /**
+ * Validate the given compilation unit name.
+ * A compilation unit name must obey the following rules:
+ * <ul>
+ * <li> it must not be null
+ * <li> it must include the <code>".java"</code> suffix
+ * <li> its prefix must be a valid identifier
+ * </ul>
+ * </p>
+ * @param name the name of a compilation unit
+ * @return a status object with code <code>IStatus.OK</code> if
+ * the given name is valid as a compilation unit name, otherwise a status
+ * object indicating what is wrong with the name
+ */
+ public static boolean isValidCompilationUnitName(String name) {
+ return PHPFileUtil.isPHPFileName(name);
+// return JavaConventions.validateCompilationUnitName(name).getSeverity() != IStatus.ERROR;
+ }
+
+ /**
+ * Validate the given .class file name.
+ * A .class file name must obey the following rules:
+ * <ul>
+ * <li> it must not be null
+ * <li> it must include the <code>".class"</code> suffix
+ * <li> its prefix must be a valid identifier
+ * </ul>
+ * </p>
+ * @param name the name of a .class file
+ * @return a status object with code <code>IStatus.OK</code> if
+ * the given name is valid as a .class file name, otherwise a status
+ * object indicating what is wrong with the name
+ */
+// public static boolean isValidClassFileName(String name) {
+// return JavaConventions.validateClassFileName(name).getSeverity() != IStatus.ERROR;
+// }
+
+ /**
+ * Returns true if the given method signature is valid,
+ * false if it is not.
+ */
+ public static boolean isValidMethodSignature(String sig) {
+ int len = sig.length();
+ if (len == 0) return false;
+ int i = 0;
+ char c = sig.charAt(i++);
+ if (c != '(') return false;
+ if (i >= len) return false;
+ while (sig.charAt(i) != ')') {
+ // Void is not allowed as a parameter type.
+ i = checkTypeSignature(sig, i, len, false);
+ if (i == -1) return false;
+ if (i >= len) return false;
+ }
+ ++i;
+ i = checkTypeSignature(sig, i, len, true);
+ return i == len;
+ }
+
+ /**
+ * Returns true if the given type signature is valid,
+ * false if it is not.
+ */
+ public static boolean isValidTypeSignature(String sig, boolean allowVoid) {
+ int len = sig.length();
+ return checkTypeSignature(sig, 0, len, allowVoid) == len;
+ }
+
+ /**
+ * Returns true if the given folder name is valid for a package,
+ * false if it is not.
+ */
+ public static boolean isValidFolderNameForPackage(String folderName) {
+// return JavaConventions.validateIdentifier(folderName).getSeverity() != IStatus.ERROR;
+ return true;
+ }
+
+ /*
+ * Add a log entry
+ */
+ public static void log(Throwable e, String message) {
+ Throwable nestedException;
+ if (e instanceof JavaModelException
+ && (nestedException = ((JavaModelException)e).getException()) != null) {
+ e = nestedException;
+ }
+ IStatus status= new Status(
+ IStatus.ERROR,
+ JavaCore.getPlugin().getDescriptor().getUniqueIdentifier(),
+ IStatus.ERROR,
+ message,
+ e);
+ JavaCore.getPlugin().getLog().log(status);
+ }
+
+ /**
+ * Normalizes the cariage returns in the given text.
+ * They are all changed to use the given buffer's line separator.
+ */
+ public static char[] normalizeCRs(char[] text, char[] buffer) {
+ CharArrayBuffer result = new CharArrayBuffer();
+ int lineStart = 0;
+ int length = text.length;
+ if (length == 0) return text;
+ String lineSeparator = getLineSeparator(text, buffer);
+ char nextChar = text[0];
+ for (int i = 0; i < length; i++) {
+ char currentChar = nextChar;
+ nextChar = i < length-1 ? text[i+1] : ' ';
+ switch (currentChar) {
+ case '\n':
+ int lineLength = i-lineStart;
+ char[] line = new char[lineLength];
+ System.arraycopy(text, lineStart, line, 0, lineLength);
+ result.append(line);
+ result.append(lineSeparator);
+ lineStart = i+1;
+ break;
+ case '\r':
+ lineLength = i-lineStart;
+ if (lineLength >= 0) {
+ line = new char[lineLength];
+ System.arraycopy(text, lineStart, line, 0, lineLength);
+ result.append(line);
+ result.append(lineSeparator);
+ if (nextChar == '\n') {
+ nextChar = ' ';
+ lineStart = i+2;
+ } else {
+ // when line separator are mixed in the same file
+ // \r might not be followed by a \n. If not, we should increment
+ // lineStart by one and not by two.
+ lineStart = i+1;
+ }
+ } else {
+ // when line separator are mixed in the same file
+ // we need to prevent NegativeArraySizeException
+ lineStart = i+1;
+ }
+ break;
+ }
+ }
+ char[] lastLine;
+ if (lineStart > 0) {
+ int lastLineLength = length-lineStart;
+ if (lastLineLength > 0) {
+ lastLine = new char[lastLineLength];
+ System.arraycopy(text, lineStart, lastLine, 0, lastLineLength);
+ result.append(lastLine);
+ }
+ return result.getContents();
+ } else {
+ return text;
+ }
+ }
+
+ /**
+ * Normalizes the cariage returns in the given text.
+ * They are all changed to use given buffer's line sepatator.
+ */
+ public static String normalizeCRs(String text, String buffer) {
+ return new String(normalizeCRs(text.toCharArray(), buffer.toCharArray()));
+ }
+
+ /**
+ * Sort the objects in the given collection using the given sort order.
+ */
+ private static void quickSort(Object[] sortedCollection, int left, int right, int[] sortOrder) {
+ int original_left = left;
+ int original_right = right;
+ int mid = sortOrder[ (left + right) / 2];
+ do {
+ while (sortOrder[left] < mid) {
+ left++;
+ }
+ while (mid < sortOrder[right]) {
+ right--;
+ }
+ if (left <= right) {
+ Object tmp = sortedCollection[left];
+ sortedCollection[left] = sortedCollection[right];
+ sortedCollection[right] = tmp;
+ int tmp2 = sortOrder[left];
+ sortOrder[left] = sortOrder[right];
+ sortOrder[right] = tmp2;
+ left++;
+ right--;
+ }
+ } while (left <= right);
+ if (original_left < right) {
+ quickSort(sortedCollection, original_left, right, sortOrder);
+ }
+ if (left < original_right) {
+ quickSort(sortedCollection, left, original_right, sortOrder);
+ }
+ }
+
+ /**
+ * Sort the objects in the given collection using the given comparer.
+ */
+ private static void quickSort(Object[] sortedCollection, int left, int right, Comparer comparer) {
+ int original_left = left;
+ int original_right = right;
+ Object mid = sortedCollection[ (left + right) / 2];
+ do {
+ while (comparer.compare(sortedCollection[left], mid) < 0) {
+ left++;
+ }
+ while (comparer.compare(mid, sortedCollection[right]) < 0) {
+ right--;
+ }
+ if (left <= right) {
+ Object tmp = sortedCollection[left];
+ sortedCollection[left] = sortedCollection[right];
+ sortedCollection[right] = tmp;
+ left++;
+ right--;
+ }
+ } while (left <= right);
+ if (original_left < right) {
+ quickSort(sortedCollection, original_left, right, comparer);
+ }
+ if (left < original_right) {
+ quickSort(sortedCollection, left, original_right, comparer);
+ }
+ }
+
+ /**
+ * Sort the strings in the given collection.
+ */
+ private static void quickSort(String[] sortedCollection, int left, int right) {
+ int original_left = left;
+ int original_right = right;
+ String mid = sortedCollection[ (left + right) / 2];
+ do {
+ while (sortedCollection[left].compareTo(mid) < 0) {
+ left++;
+ }
+ while (mid.compareTo(sortedCollection[right]) < 0) {
+ right--;
+ }
+ if (left <= right) {
+ String tmp = sortedCollection[left];
+ sortedCollection[left] = sortedCollection[right];
+ sortedCollection[right] = tmp;
+ left++;
+ right--;
+ }
+ } while (left <= right);
+ if (original_left < right) {
+ quickSort(sortedCollection, original_left, right);
+ }
+ if (left < original_right) {
+ quickSort(sortedCollection, left, original_right);
+ }
+ }
+
+ /**
+ * Converts the given relative path into a package name.
+ * Returns null if the path is not a valid package name.
+ */
+ public static String packageName(IPath pkgPath) {
+ StringBuffer pkgName = new StringBuffer(IPackageFragment.DEFAULT_PACKAGE_NAME);
+ for (int j = 0, max = pkgPath.segmentCount(); j < max; j++) {
+ String segment = pkgPath.segment(j);
+ if (!isValidFolderNameForPackage(segment)) {
+ return null;
+ }
+ pkgName.append(segment);
+ if (j < pkgPath.segmentCount() - 1) {
+ pkgName.append("." ); //$NON-NLS-1$
+ }
+ }
+ return pkgName.toString();
+ }
+
+ /**
+ * Sort the comparable objects in the given collection.
+ */
+ private static void quickSort(Comparable[] sortedCollection, int left, int right) {
+ int original_left = left;
+ int original_right = right;
+ Comparable mid = sortedCollection[ (left + right) / 2];
+ do {
+ while (sortedCollection[left].compareTo(mid) < 0) {
+ left++;
+ }
+ while (mid.compareTo(sortedCollection[right]) < 0) {
+ right--;
+ }
+ if (left <= right) {
+ Comparable tmp = sortedCollection[left];
+ sortedCollection[left] = sortedCollection[right];
+ sortedCollection[right] = tmp;
+ left++;
+ right--;
+ }
+ } while (left <= right);
+ if (original_left < right) {
+ quickSort(sortedCollection, original_left, right);
+ }
+ if (left < original_right) {
+ quickSort(sortedCollection, left, original_right);
+ }
+ }
+
+ /**
+ * Sort the strings in the given collection in reverse alphabetical order.
+ */
+ private static void quickSortReverse(String[] sortedCollection, int left, int right) {
+ int original_left = left;
+ int original_right = right;
+ String mid = sortedCollection[ (left + right) / 2];
+ do {
+ while (sortedCollection[left].compareTo(mid) > 0) {
+ left++;
+ }
+ while (mid.compareTo(sortedCollection[right]) > 0) {
+ right--;
+ }
+ if (left <= right) {
+ String tmp = sortedCollection[left];
+ sortedCollection[left] = sortedCollection[right];
+ sortedCollection[right] = tmp;
+ left++;
+ right--;
+ }
+ } while (left <= right);
+ if (original_left < right) {
+ quickSortReverse(sortedCollection, original_left, right);
+ }
+ if (left < original_right) {
+ quickSortReverse(sortedCollection, left, original_right);
+ }
+ }
+
+ /**
+ * Sorts an array of objects in place, using the sort order given for each item.
+ */
+ public static void sort(Object[] objects, int[] sortOrder) {
+ if (objects.length > 1)
+ quickSort(objects, 0, objects.length - 1, sortOrder);
+ }
+
+ /**
+ * Sorts an array of objects in place.
+ * The given comparer compares pairs of items.
+ */
+ public static void sort(Object[] objects, Comparer comparer) {
+ if (objects.length > 1)
+ quickSort(objects, 0, objects.length - 1, comparer);
+ }
+
+ /**
+ * Sorts an array of strings in place using quicksort.
+ */
+ public static void sort(String[] strings) {
+ if (strings.length > 1)
+ quickSort(strings, 0, strings.length - 1);
+ }
+
+ /**
+ * Sorts an array of Comparable objects in place.
+ */
+ public static void sort(Comparable[] objects) {
+ if (objects.length > 1)
+ quickSort(objects, 0, objects.length - 1);
+ }
+
+ /**
+ * Sorts an array of Strings, returning a new array
+ * with the sorted items. The original array is left untouched.
+ */
+ public static Object[] sortCopy(Object[] objects, Comparer comparer) {
+ int len = objects.length;
+ Object[] copy = new Object[len];
+ System.arraycopy(objects, 0, copy, 0, len);
+ sort(copy, comparer);
+ return copy;
+ }
+
+ /**
+ * Sorts an array of Strings, returning a new array
+ * with the sorted items. The original array is left untouched.
+ */
+ public static String[] sortCopy(String[] objects) {
+ int len = objects.length;
+ String[] copy = new String[len];
+ System.arraycopy(objects, 0, copy, 0, len);
+ sort(copy);
+ return copy;
+ }
+
+ /**
+ * Sorts an array of Comparable objects, returning a new array
+ * with the sorted items. The original array is left untouched.
+ */
+ public static Comparable[] sortCopy(Comparable[] objects) {
+ int len = objects.length;
+ Comparable[] copy = new Comparable[len];
+ System.arraycopy(objects, 0, copy, 0, len);
+ sort(copy);
+ return copy;
+ }
+
+ /**
+ * Sorts an array of strings in place using quicksort
+ * in reverse alphabetical order.
+ */
+ public static void sortReverseOrder(String[] strings) {
+ if (strings.length > 1)
+ quickSortReverse(strings, 0, strings.length - 1);
+ }
+
+ /**
+ * Converts a String[] to char[][].
+ */
+ public static char[][] toCharArrays(String[] a) {
+ int len = a.length;
+ char[][] result = new char[len][];
+ for (int i = 0; i < len; ++i) {
+ result[i] = toChars(a[i]);
+ }
+ return result;
+ }
+
+ /**
+ * Converts a String to char[].
+ */
+ public static char[] toChars(String s) {
+ int len = s.length();
+ char[] chars = new char[len];
+ s.getChars(0, len, chars, 0);
+ return chars;
+ }
+
+ /**
+ * Converts a String to char[][], where segments are separate by '.'.
+ */
+ public static char[][] toCompoundChars(String s) {
+ int len = s.length();
+ if (len == 0) {
+ return CharOperation.NO_CHAR_CHAR;
+ }
+ int segCount = 1;
+ for (int off = s.indexOf('.'); off != -1; off = s.indexOf('.', off + 1)) {
+ ++segCount;
+ }
+ char[][] segs = new char[segCount][];
+ int start = 0;
+ for (int i = 0; i < segCount; ++i) {
+ int dot = s.indexOf('.', start);
+ int end = (dot == -1 ? s.length() : dot);
+ segs[i] = new char[end - start];
+ s.getChars(start, end, segs[i], 0);
+ start = end + 1;
+ }
+ return segs;
+ }
+
+ /**
+ * Converts a char[][] to String, where segments are separated by '.'.
+ */
+ public static String toString(char[][] c) {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0, max = c.length; i < max; ++i) {
+ if (i != 0) sb.append('.');
+ sb.append(c[i]);
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Converts a char[][] and a char[] to String, where segments are separated by '.'.
+ */
+ public static String toString(char[][] c, char[] d) {
+ if (c == null) return new String(d);
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0, max = c.length; i < max; ++i) {
+ sb.append(c[i]);
+ sb.append('.');
+ }
+ sb.append(d);
+ return sb.toString();
+ }
+
+ /**
+ * Converts a char[] to String.
+ */
+ public static String toString(char[] c) {
+ return new String(c);
+ }
+
+ /**
+ * Converts an array of Objects into String.
+ */
+ public static String toString(Object[] objects) {
+ return toString(objects,
+ new Displayable(){
+ public String displayString(Object o) {
+ if (o == null) return "null"; //$NON-NLS-1$
+ return o.toString();
+ }
+ });
+ }
+
+ /**
+ * Converts an array of Objects into String.
+ */
+ public static String toString(Object[] objects, Displayable renderer) {
+ if (objects == null) return ""; //$NON-NLS-1$
+ StringBuffer buffer = new StringBuffer(10);
+ for (int i = 0; i < objects.length; i++){
+ if (i > 0) buffer.append(", "); //$NON-NLS-1$
+ buffer.append(renderer.displayString(objects[i]));
+ }
+ return buffer.toString();
+ }
+
+ /**
+ * Asserts that the given method signature is valid.
+ */
+ public static void validateMethodSignature(String sig) {
+ Assert.isTrue(isValidMethodSignature(sig));
+ }
+
+ /**
+ * Asserts that the given type signature is valid.
+ */
+ public static void validateTypeSignature(String sig, boolean allowVoid) {
+ Assert.isTrue(isValidTypeSignature(sig, allowVoid));
+ }
+ public static void verbose(String log) {
+ verbose(log, System.out);
+ }
+ public static synchronized void verbose(String log, PrintStream printStream) {
+ int start = 0;
+ do {
+ int end = log.indexOf('\n', start);
+ printStream.print(Thread.currentThread());
+ printStream.print(" "); //$NON-NLS-1$
+ printStream.print(log.substring(start, end == -1 ? log.length() : end+1));
+ start = end+1;
+ } while (start != 0);
+ printStream.println();
+ }
+ /**
+ * Creates a NLS catalog for the given locale.
+ */
+ public static void relocalize() {
+ try {
+ bundle = ResourceBundle.getBundle(bundleName, Locale.getDefault());
+ } catch(MissingResourceException e) {
+ System.out.println("Missing resource : " + bundleName.replace('.', '/') + ".properties for locale " + Locale.getDefault()); //$NON-NLS-1$//$NON-NLS-2$
+ throw e;
+ }
+ }
+
+ /**
+ * Put all the arguments in one String.
+ */
+ public static String getProblemArgumentsForMarker(String[] arguments){
+ StringBuffer args = new StringBuffer(10);
+
+ args.append(arguments.length);
+ args.append(':');
+
+
+ for (int j = 0; j < arguments.length; j++) {
+ if(j != 0)
+ args.append(ARGUMENTS_DELIMITER);
+
+ if(arguments[j].length() == 0) {
+ args.append(EMPTY_ARGUMENT);
+ } else {
+ args.append(arguments[j]);
+ }
+ }
+
+ return args.toString();
+ }
+
+ /**
+ * Separate all the arguments of a String made by getProblemArgumentsForMarker
+ */
+ public static String[] getProblemArgumentsFromMarker(String argumentsString){
+ if (argumentsString == null) return null;
+ int index = argumentsString.indexOf(':');
+ if(index == -1)
+ return null;
+
+ int length = argumentsString.length();
+ int numberOfArg;
+ try{
+ numberOfArg = Integer.parseInt(argumentsString.substring(0 , index));
+ } catch (NumberFormatException e) {
+ return null;
+ }
+ argumentsString = argumentsString.substring(index + 1, length);
+
+ String[] args = new String[length];
+ int count = 0;
+
+ StringTokenizer tokenizer = new StringTokenizer(argumentsString, ARGUMENTS_DELIMITER);
+ while(tokenizer.hasMoreTokens()) {
+ String argument = tokenizer.nextToken();
+ if(argument.equals(EMPTY_ARGUMENT))
+ argument = ""; //$NON-NLS-1$
+ args[count++] = argument;
+ }
+
+ if(count != numberOfArg)
+ return null;
+
+ System.arraycopy(args, 0, args = new String[count], 0, count);
+ return args;
+ }
+
+}
import net.sourceforge.phpeclipse.PHPeclipsePlugin;
-import org.apache.xml.serialize.OutputFormat;
-import org.apache.xml.serialize.Serializer;
-import org.apache.xml.serialize.SerializerFactory;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IStatus;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
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);
+ Transformer transformer=TransformerFactory.newInstance().newTransformer();
+ transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
+ transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
+ DOMSource source = new DOMSource(document);
+ StreamResult result = new StreamResult(stream);
+
+ transformer.transform(source, result);
+
+// 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);
- }
+ } catch (TransformerException e) {
+ throwWriteException(e);
+ }
+// } catch (IOException e) {
+// throwWriteException(e);
+// }
}
private static void throwReadException(Throwable t) throws CoreException {
return '!' + key + '!';
}
}
-
+ /**
+ * Returns the resource bundle managed by the receiver.
+ *
+ * @return the resource bundle
+ * @since 3.0
+ */
+ public static ResourceBundle getResourceBundle() {
+ return RESOURCE_BUNDLE;
+ }
/**
* Returns the formatted resource string associated with the given key in the resource bundle.
* <code>MessageFormat</code> is used to format the message. If there isn't any value
int selectionOffset= selection.getOffset();
int selectionEndOffset= selectionOffset + selection.getLength();
List edits= new LinkedList();
- ITypedRegion partition= docExtension.getPartition(IPHPPartitions.PHP_PARTITIONING, selectionOffset);
+ ITypedRegion partition= docExtension.getPartition(IPHPPartitions.PHP_PARTITIONING, selectionOffset, false);
handleFirstPartition(partition, edits, factory, selectionOffset);
}
// advance to next partition
- partition= docExtension.getPartition(IPHPPartitions.PHP_PARTITIONING, partEndOffset);
+ partition= docExtension.getPartition(IPHPPartitions.PHP_PARTITIONING, partEndOffset, false);
partType= partition.getType();
// start of next partition
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.actions;
+
+import org.eclipse.jface.action.IMenuManager;
+
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.source.projection.IProjectionListener;
+import org.eclipse.jface.text.source.projection.ProjectionViewer;
+
+import org.eclipse.ui.actions.ActionGroup;
+import org.eclipse.ui.editors.text.IFoldingCommandIds;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.TextOperationAction;
+
+
+/**
+ * Groups the JDT folding actions.
+ *
+ * @since 3.0
+ */
+public class FoldingActionGroup extends ActionGroup {
+ private ProjectionViewer fViewer;
+
+ private TextOperationAction fToggle;
+ private TextOperationAction fExpand;
+ private TextOperationAction fCollapse;
+ private TextOperationAction fExpandAll;
+
+ private IProjectionListener fProjectionListener;
+
+ /**
+ * Creates a new projection action group for <code>editor</code>. If the
+ * supplied viewer is not an instance of <code>ProjectionViewer</code>, the
+ * action group is disabled.
+ *
+ * @param editor the text editor to operate on
+ * @param viewer the viewer of the editor
+ */
+ public FoldingActionGroup(ITextEditor editor, ITextViewer viewer) {
+ if (viewer instanceof ProjectionViewer) {
+ fViewer= (ProjectionViewer) viewer;
+
+ fProjectionListener= new IProjectionListener() {
+
+ public void projectionEnabled() {
+ update();
+ }
+
+ public void projectionDisabled() {
+ update();
+ }
+ };
+
+ fViewer.addProjectionListener(fProjectionListener);
+
+ fToggle= new TextOperationAction(ActionMessages.getResourceBundle(), "Projection.Toggle.", editor, ProjectionViewer.TOGGLE, true); //$NON-NLS-1$
+ fToggle.setChecked(true);
+ fToggle.setActionDefinitionId(IFoldingCommandIds.FOLDING_TOGGLE);
+ editor.setAction("FoldingToggle", fToggle); //$NON-NLS-1$
+
+ fExpandAll= new TextOperationAction(ActionMessages.getResourceBundle(), "Projection.ExpandAll.", editor, ProjectionViewer.EXPAND_ALL, true); //$NON-NLS-1$
+ fExpandAll.setActionDefinitionId(IFoldingCommandIds.FOLDING_EXPAND_ALL);
+ editor.setAction("FoldingExpandAll", fExpandAll); //$NON-NLS-1$
+
+ fExpand= new TextOperationAction(ActionMessages.getResourceBundle(), "Projection.Expand.", editor, ProjectionViewer.EXPAND, true); //$NON-NLS-1$
+ fExpand.setActionDefinitionId(IFoldingCommandIds.FOLDING_EXPAND);
+ editor.setAction("FoldingExpand", fExpand); //$NON-NLS-1$
+
+ fCollapse= new TextOperationAction(ActionMessages.getResourceBundle(), "Projection.Collapse.", editor, ProjectionViewer.COLLAPSE, true); //$NON-NLS-1$
+ fCollapse.setActionDefinitionId(IFoldingCommandIds.FOLDING_COLLAPSE);
+ editor.setAction("FoldingCollapse", fCollapse); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Returns <code>true</code> if the group is enabled.
+ * <pre>
+ * Invariant: isEnabled() <=> fViewer and all actions are != null.
+ * </pre>
+ *
+ * @return <code>true</code> if the group is enabled
+ */
+ protected boolean isEnabled() {
+ return fViewer != null;
+ }
+
+ /*
+ * @see org.eclipse.ui.actions.ActionGroup#dispose()
+ */
+ public void dispose() {
+ if (isEnabled()) {
+ fViewer.removeProjectionListener(fProjectionListener);
+ fViewer= null;
+ }
+ super.dispose();
+ }
+
+ /**
+ * Updates the actions.
+ */
+ protected void update() {
+ if (isEnabled()) {
+ fToggle.update();
+ fToggle.setChecked(fViewer.getProjectionAnnotationModel() != null);
+ fExpand.update();
+ fExpandAll.update();
+ fCollapse.update();
+ }
+ }
+
+ /**
+ * Fills the menu with all folding actions.
+ *
+ * @param manager the menu manager for the folding submenu
+ */
+ public void fillMenu(IMenuManager manager) {
+ if (isEnabled()) {
+ update();
+ manager.add(fToggle);
+ manager.add(fExpandAll);
+ manager.add(fExpand);
+ manager.add(fCollapse);
+ }
+ }
+
+ /*
+ * @see org.eclipse.ui.actions.ActionGroup#updateActionBars()
+ */
+ public void updateActionBars() {
+ update();
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.actions;
+
+import org.eclipse.jface.action.IAction;
+
+import org.eclipse.jface.text.source.IVerticalRulerInfo;
+import org.eclipse.jface.text.source.projection.ProjectionViewer;
+
+import org.eclipse.ui.editors.text.IFoldingCommandIds;
+import org.eclipse.ui.texteditor.AbstractRulerActionDelegate;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.TextOperationAction;
+
+
+/**
+ * Groups the JDT folding actions.
+ *
+ * @since 3.0
+ */
+public class FoldingExpandAllRulerAction extends AbstractRulerActionDelegate {
+
+ /*
+ * @see org.eclipse.ui.texteditor.AbstractRulerActionDelegate#createAction(org.eclipse.ui.texteditor.ITextEditor, org.eclipse.jface.text.source.IVerticalRulerInfo)
+ */
+ protected IAction createAction(ITextEditor editor, IVerticalRulerInfo rulerInfo) {
+ TextOperationAction action= new TextOperationAction(ActionMessages.getResourceBundle(), "Projection.ExpandAll.", editor, ProjectionViewer.EXPAND_ALL, true); //$NON-NLS-1$
+ action.setActionDefinitionId(IFoldingCommandIds.FOLDING_EXPAND_ALL);
+ return action;
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.actions;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.IVerticalRulerInfo;
+import org.eclipse.jface.text.source.projection.ProjectionViewer;
+
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.editors.text.IFoldingCommandIds;
+import org.eclipse.ui.texteditor.AbstractRulerActionDelegate;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.TextOperationAction;
+
+import net.sourceforge.phpeclipse.phpeditor.PHPEditor;
+
+
+/**
+ * Groups the JDT folding actions.
+ *
+ * @since 3.0
+ */
+public class FoldingToggleRulerAction extends AbstractRulerActionDelegate {
+
+ private IAction fUIAction;
+ private TextOperationAction fAction;
+ private ITextEditor fTextEditor;
+
+ /*
+ * @see org.eclipse.ui.texteditor.AbstractRulerActionDelegate#createAction(org.eclipse.ui.texteditor.ITextEditor, org.eclipse.jface.text.source.IVerticalRulerInfo)
+ */
+ protected IAction createAction(ITextEditor editor, IVerticalRulerInfo rulerInfo) {
+ fTextEditor= editor;
+ fAction= new TextOperationAction(ActionMessages.getResourceBundle(), "Projection.Toggle.", editor, ProjectionViewer.TOGGLE, true); //$NON-NLS-1$
+ fAction.setActionDefinitionId(IFoldingCommandIds.FOLDING_TOGGLE);
+
+ return fAction;
+ }
+
+ /*
+ * @see org.eclipse.ui.texteditor.AbstractRulerActionDelegate#setActiveEditor(org.eclipse.jface.action.IAction, org.eclipse.ui.IEditorPart)
+ */
+ public void setActiveEditor(IAction callerAction, IEditorPart targetEditor) {
+ fUIAction= callerAction;
+ super.setActiveEditor(callerAction, targetEditor);
+ }
+
+ /*
+ * @see org.eclipse.ui.texteditor.AbstractRulerActionDelegate#menuAboutToShow(org.eclipse.jface.action.IMenuManager)
+ */
+ public void menuAboutToShow(IMenuManager manager) {
+ update();
+ super.menuAboutToShow(manager);
+ }
+
+ private void update() {
+ if (fTextEditor instanceof PHPEditor) {
+ ISourceViewer viewer= ((PHPEditor) fTextEditor).getViewer();
+ if (viewer instanceof ProjectionViewer) {
+ boolean enabled= ((ProjectionViewer) viewer).getProjectionAnnotationModel() != null;
+ fUIAction.setChecked(enabled);
+ }
+ }
+ }
+}
int offset= selection.getOffset();
int endOffset= offset + selection.getLength();
- ITypedRegion partition= docExtension.getPartition(IPHPPartitions.PHP_PARTITIONING, offset);
+ ITypedRegion partition= docExtension.getPartition(IPHPPartitions.PHP_PARTITIONING, offset, false);
int partOffset= partition.getOffset();
int partEndOffset= partOffset + partition.getLength();
edits.add(factory.createEdit(partEndOffset - tokenLength, tokenLength, "")); //$NON-NLS-1$
}
- partition= docExtension.getPartition(IPHPPartitions.PHP_PARTITIONING, partEndOffset);
+ partition= docExtension.getPartition(IPHPPartitions.PHP_PARTITIONING, partEndOffset, false);
partOffset= partition.getOffset();
partEndOffset= partOffset + partition.getLength();
}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text;
+
+import net.sourceforge.phpdt.internal.ui.text.TypingRun.ChangeType;
+
+
+/**
+ * Listener for <code>TypingRun</code> events.
+ *
+ * @since 3.0
+ */
+public interface ITypingRunListener {
+ /**
+ * Called when a new <code>TypingRun</code> is started.
+ *
+ * @param run the newly started run
+ */
+ void typingRunStarted(TypingRun run);
+
+ /**
+ * Called whenever a <code>TypingRun</code> is ended.
+ *
+ * @param run the ended run
+ * @param reason the type of change that caused the end of the run
+ */
+ void typingRunEnded(TypingRun run, ChangeType reason);
+}
\ No newline at end of file
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+
+
+/**
+ * Presentation reconciler, adding functionality for operation without a viewer.
+ *
+ * @since 3.0
+ */
+public class JavaPresentationReconciler extends PresentationReconciler {
+
+ /** Last used document */
+ private IDocument fLastDocument;
+
+ /**
+ * Constructs a "repair description" for the given damage and returns
+ * this description as a text presentation.
+ * <p>
+ * NOTE: Should not be used if this reconciler is installed on a viewer.
+ * </p>
+ *
+ * @param damage the damage to be repaired
+ * @param document the document whose presentation must be repaired
+ * @return the presentation repair description as text presentation
+ */
+ public TextPresentation createRepairDescription(IRegion damage, IDocument document) {
+ if (document != fLastDocument) {
+ setDocumentToDamagers(document);
+ setDocumentToRepairers(document);
+ }
+ return createPresentation(damage, document);
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text;
+
+import org.eclipse.core.runtime.Preferences;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.ListenerList;
+import org.eclipse.jface.util.PropertyChangeEvent;
+
+/**
+ * Adapts {@link org.eclipse.core.runtime.Preferences} to
+ * {@link org.eclipse.jface.preference.IPreferenceStore}
+ *
+ * @since 3.0
+ */
+public class PreferencesAdapter implements IPreferenceStore {
+
+ /**
+ * Property change listener. Listens for events of type
+ * {@link org.eclipse.core.runtime.Preferences.PropertyChangeEvent} and fires
+ * a {@link org.eclipse.jface.util.PropertyChangeEvent} on the
+ * adapter with arguments from the received event.
+ */
+ private class PropertyChangeListener implements Preferences.IPropertyChangeListener {
+
+ /*
+ * @see org.eclipse.core.runtime.Preferences.IPropertyChangeListener#propertyChange(org.eclipse.core.runtime.Preferences.PropertyChangeEvent)
+ */
+ public void propertyChange(Preferences.PropertyChangeEvent event) {
+ firePropertyChangeEvent(event.getProperty(), event.getOldValue(), event.getNewValue());
+ }
+ }
+
+ /** Listeners on the adapter */
+ private ListenerList fListeners= new ListenerList();
+
+ /** Listener on the adapted Preferences */
+ private PropertyChangeListener fListener= new PropertyChangeListener();
+
+ /** Adapted Preferences */
+ private Preferences fPreferences;
+
+ /** True iff no events should be forwarded */
+ private boolean fSilent;
+
+ /**
+ * Initialize with empty Preferences.
+ */
+ public PreferencesAdapter() {
+ this(new Preferences());
+ }
+ /**
+ * Initialize with the given Preferences.
+ *
+ * @param preferences The preferences to wrap.
+ */
+ public PreferencesAdapter(Preferences preferences) {
+ fPreferences= preferences;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addPropertyChangeListener(IPropertyChangeListener listener) {
+ if (fListeners.size() == 0)
+ fPreferences.addPropertyChangeListener(fListener);
+ fListeners.add(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void removePropertyChangeListener(IPropertyChangeListener listener) {
+ fListeners.remove(listener);
+ if (fListeners.size() == 0)
+ fPreferences.removePropertyChangeListener(fListener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean contains(String name) {
+ return fPreferences.contains(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void firePropertyChangeEvent(String name, Object oldValue, Object newValue) {
+ if (!fSilent) {
+ PropertyChangeEvent event= new PropertyChangeEvent(this, name, oldValue, newValue);
+ Object[] listeners= fListeners.getListeners();
+ for (int i= 0; i < listeners.length; i++)
+ ((IPropertyChangeListener) listeners[i]).propertyChange(event);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean getBoolean(String name) {
+ return fPreferences.getBoolean(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean getDefaultBoolean(String name) {
+ return fPreferences.getDefaultBoolean(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public double getDefaultDouble(String name) {
+ return fPreferences.getDefaultDouble(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public float getDefaultFloat(String name) {
+ return fPreferences.getDefaultFloat(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getDefaultInt(String name) {
+ return fPreferences.getDefaultInt(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public long getDefaultLong(String name) {
+ return fPreferences.getDefaultLong(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getDefaultString(String name) {
+ return fPreferences.getDefaultString(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public double getDouble(String name) {
+ return fPreferences.getDouble(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public float getFloat(String name) {
+ return fPreferences.getFloat(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getInt(String name) {
+ return fPreferences.getInt(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public long getLong(String name) {
+ return fPreferences.getLong(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getString(String name) {
+ return fPreferences.getString(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isDefault(String name) {
+ return fPreferences.isDefault(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean needsSaving() {
+ return fPreferences.needsSaving();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void putValue(String name, String value) {
+ try {
+ fSilent= true;
+ fPreferences.setValue(name, value);
+ } finally {
+ fSilent= false;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setDefault(String name, double value) {
+ fPreferences.setDefault(name, value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setDefault(String name, float value) {
+ fPreferences.setDefault(name, value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setDefault(String name, int value) {
+ fPreferences.setDefault(name, value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setDefault(String name, long value) {
+ fPreferences.setDefault(name, value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setDefault(String name, String defaultObject) {
+ fPreferences.setDefault(name, defaultObject);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setDefault(String name, boolean value) {
+ fPreferences.setDefault(name, value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setToDefault(String name) {
+ fPreferences.setToDefault(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setValue(String name, double value) {
+ fPreferences.setValue(name, value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setValue(String name, float value) {
+ fPreferences.setValue(name, value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setValue(String name, int value) {
+ fPreferences.setValue(name, value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setValue(String name, long value) {
+ fPreferences.setValue(name, value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setValue(String name, String value) {
+ fPreferences.setValue(name, value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setValue(String name, boolean value) {
+ fPreferences.setValue(name, value);
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.text.edits.MalformedTreeException;
+import org.eclipse.text.edits.TextEdit;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.VerifyKeyListener;
+import org.eclipse.swt.events.VerifyEvent;
+import org.eclipse.swt.graphics.Point;
+
+import org.eclipse.jface.text.Assert;
+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.ITextViewerExtension;
+import org.eclipse.jface.text.TextViewer;
+
+import net.sourceforge.phpdt.internal.ui.text.TypingRun.ChangeType;
+
+
+
+/**
+ * Installs as a verify key listener on a viewer and overwrites the behaviour
+ * of the backspace key. Clients may register undo specifications for certain
+ * offsets in a document. The <code>SmartBackspaceManager</code> will manage the
+ * specfications and execute the contained <code>TextEdit</code>s when backspace
+ * is pressed at the given offset and the specification is still valid.
+ * <p>
+ * Undo specifications are removed after a number of typing runs.
+ * </p>
+ *
+ * @since 3.0
+ */
+public class SmartBackspaceManager {
+ /* independent of JDT - may be moved to jface.text */
+
+ /**
+ * An undo specification describes the change that should be executed if
+ * backspace is pressed at its trigger offset.
+ *
+ * @since 3.0
+ */
+ public static final class UndoSpec {
+ private final int triggerOffset;
+ private final IRegion selection;
+ private final TextEdit[] undoEdits;
+ private final UndoSpec child;
+ int lives;
+
+ /**
+ * Creates a new spec. A specification consists of a number of
+ * <code>TextEdit</code> s that will be executed when backspace is
+ * pressed at <code>triggerOffset</code>. The spec will be removed
+ * when it is executed, or if more than <code>lives</code>
+ * <code>TypingRun</code>s have ended after registering the spec.
+ * <p>
+ * Optionally, a child specification can be registered. After executing
+ * the spec, the child spec will be registered with the manager. This allows
+ * to create chains of <code>UndoSpec</code>s that will be executed upon
+ * repeated pressing of backspace.
+ * </p>
+ *
+ * @param triggerOffset the offset where this spec is active
+ * @param selection the selection after executing the undo spec
+ * @param edits the <code>TextEdit</code> s to perform when executing
+ * the spec
+ * @param lives the number of <code>TypingRun</code> s before removing
+ * the spec
+ * @param child a child specification that will be registered after
+ * executing this spec, or <code>null</code>
+ */
+ public UndoSpec(int triggerOffset, IRegion selection, TextEdit[] edits, int lives, UndoSpec child) {
+ Assert.isLegal(triggerOffset >= 0);
+ Assert.isLegal(selection != null);
+ Assert.isLegal(lives >= 0);
+ Assert.isLegal(edits != null);
+ Assert.isLegal(edits.length > 0);
+ for (int i= 0; i < edits.length; i++) {
+ Assert.isLegal(edits[i] != null);
+ }
+
+ this.triggerOffset= triggerOffset;
+ this.selection= selection;
+ this.undoEdits= edits;
+ this.lives= lives;
+ this.child= child;
+ }
+ }
+
+
+ private class BackspaceListener implements VerifyKeyListener {
+
+ /*
+ * @see org.eclipse.swt.custom.VerifyKeyListener#verifyKey(org.eclipse.swt.events.VerifyEvent)
+ */
+ public void verifyKey(VerifyEvent event) {
+ if (fViewer != null && isBackspace(event)) {
+ int offset= getCaretOffset();
+ UndoSpec spec= removeEdit(offset);
+ if (spec != null) {
+ try {
+ beginChange();
+ for (int i= 0; i < spec.undoEdits.length; i++) {
+ spec.undoEdits[i].apply(getDocument(), TextEdit.UPDATE_REGIONS);
+ }
+ fViewer.setSelectedRange(spec.selection.getOffset(), spec.selection.getLength());
+ if (spec.child != null)
+ register(spec.child);
+ } catch (MalformedTreeException e) {
+ // fall back to standard bs
+ return;
+ } catch (BadLocationException e) {
+ // fall back to standard bs
+ return;
+ } finally {
+ endChange();
+ }
+ event.doit= false;
+ }
+
+ }
+ }
+
+ private void beginChange() {
+ ITextViewer viewer= fViewer;
+ if (viewer instanceof TextViewer) {
+ TextViewer v= (TextViewer) viewer;
+ v.getRewriteTarget().beginCompoundChange();
+ v.setRedraw(false);
+ }
+ }
+
+ private void endChange() {
+ ITextViewer viewer= fViewer;
+ if (viewer instanceof TextViewer) {
+ TextViewer v= (TextViewer) viewer;
+ v.getRewriteTarget().endCompoundChange();
+ v.setRedraw(true);
+ }
+ }
+
+ private boolean isBackspace(VerifyEvent event) {
+ return event.doit == true && event.character == SWT.BS && event.stateMask == 0;
+ }
+
+ private int getCaretOffset() {
+ ITextViewer viewer= fViewer;
+ Point point= viewer.getSelectedRange();
+ return point.x;
+ }
+
+ }
+
+ private ITextViewer fViewer;
+ private BackspaceListener fBackspaceListener;
+ private Map fSpecs;
+ private TypingRunDetector fRunDetector;
+ private ITypingRunListener fRunListener;
+
+ /**
+ * Registers an undo specification with this manager.
+ *
+ * @param spec the specification to register
+ * @throws IllegalStateException if the manager is not installed
+ */
+ public void register(UndoSpec spec) {
+ if (fViewer == null)
+ throw new IllegalStateException();
+
+ ensureListenerInstalled();
+ addEdit(spec);
+ }
+
+ private void addEdit(UndoSpec spec) {
+ Integer i= new Integer(spec.triggerOffset);
+ fSpecs.put(i, spec);
+ }
+
+ private UndoSpec removeEdit(int offset) {
+ Integer i= new Integer(offset);
+ UndoSpec spec= (UndoSpec) fSpecs.remove(i);
+ return spec;
+ }
+
+ private void ensureListenerInstalled() {
+ if (fBackspaceListener == null) {
+ fBackspaceListener= new BackspaceListener();
+ ITextViewer viewer= fViewer;
+ if (viewer instanceof ITextViewerExtension)
+ ((ITextViewerExtension) viewer).prependVerifyKeyListener(fBackspaceListener);
+ else
+ viewer.getTextWidget().addVerifyKeyListener(fBackspaceListener);
+ }
+ }
+
+ private void ensureListenerRemoved() {
+ if (fBackspaceListener != null) {
+ ITextViewer viewer= fViewer;
+ if (viewer instanceof ITextViewerExtension)
+ ((ITextViewerExtension) viewer).removeVerifyKeyListener(fBackspaceListener);
+ else
+ viewer.getTextWidget().removeVerifyKeyListener(fBackspaceListener);
+ fBackspaceListener= null;
+ }
+ }
+
+ private IDocument getDocument() {
+ return fViewer.getDocument();
+ }
+
+ /**
+ * Installs the receiver on a text viewer.
+ *
+ * @param viewer
+ */
+ public void install(ITextViewer viewer) {
+ Assert.isLegal(viewer != null);
+
+ fViewer= viewer;
+ fSpecs= new HashMap();
+ fRunDetector= new TypingRunDetector();
+ fRunDetector.install(viewer);
+ fRunListener= new ITypingRunListener() {
+
+ /*
+ * @see org.eclipse.jface.text.TypingRunDetector.ITypingRunListener#typingRunStarted(org.eclipse.jface.text.TypingRunDetector.TypingRun)
+ */
+ public void typingRunStarted(TypingRun run) {
+ }
+
+ /*
+ * @see org.eclipse.jface.text.TypingRunDetector.ITypingRunListener#typingRunEnded(org.eclipse.jface.text.TypingRunDetector.TypingRun)
+ */
+ public void typingRunEnded(TypingRun run, ChangeType reason) {
+ if (reason == TypingRun.SELECTION)
+ fSpecs.clear();
+ else
+ prune();
+ }
+ };
+ fRunDetector.addTypingRunListener(fRunListener);
+ }
+
+ private void prune() {
+ for (Iterator it= fSpecs.values().iterator(); it.hasNext();) {
+ UndoSpec spec= (UndoSpec) it.next();
+ if (--spec.lives < 0)
+ it.remove();
+ }
+ }
+
+ /**
+ * Uninstalls the receiver. No undo specifications may be registered on an
+ * uninstalled manager.
+ */
+ public void uninstall() {
+ if (fViewer != null) {
+ fRunDetector.removeTypingRunListener(fRunListener);
+ fRunDetector.uninstall();
+ fRunDetector= null;
+ ensureListenerRemoved();
+ fViewer= null;
+ }
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text;
+
+
+
+/**
+ * Describes a run of similar typing changes.
+ * <p>
+ * XXX to be extended with further information, e.g. offset, length, and
+ * content of the run.
+ * </p>
+ *
+ * @since 3.0
+ */
+public final class TypingRun {
+ /**
+ * A change of type <code>DELETE</code> deletes one single character (through delete or
+ * backspace or empty paste).
+ */
+ public static final ChangeType DELETE= new ChangeType(true, "DELETE"); //$NON-NLS-1$
+ /**
+ * A change of type <code>INSERT</code> inserts one single character
+ * (normal typing).
+ */
+ public static final ChangeType INSERT= new ChangeType(true, "INSERT"); //$NON-NLS-1$
+ /**
+ * A change of type <code>NO_CHANGE</code> does not change anything.
+ */
+ public static final ChangeType NO_CHANGE= new ChangeType(false, "NO_CHANGE"); //$NON-NLS-1$
+ /**
+ * A change of type <code>OVERTYPE</code> replaces one single character
+ * (overwrite mode, pasting a single character).
+ */
+ public static final ChangeType OVERTYPE= new ChangeType(true, "OVERTYPE"); //$NON-NLS-1$
+ /**
+ * A change of type <code>SELECTION</code> does not change text, but
+ * changes the focus, or selection. Such a change ends all typing runs.
+ */
+ public static final ChangeType SELECTION= new ChangeType(false, "SELECTION"); //$NON-NLS-1$
+ /**
+ * A change of type <code>UNKNOWN</code> modifies text in an
+ * unspecified way. An example is pasting more than one character, or
+ * deleting an entire selection, or reverting a file. Such a change ends
+ * all typing runs and cannot form a typing run with any other change,
+ * including a change of type <code>UNKNOWN</code>.
+ */
+ public static final ChangeType UNKNOWN= new ChangeType(true, "UNKNOWN"); //$NON-NLS-1$
+
+
+ /**
+ * Enumeration of change types.
+ *
+ * @since 3.0
+ */
+ public static final class ChangeType {
+ private final boolean fIsModification;
+ private final String fName;
+
+ /** Private ctor for type safe enumeration. */
+ private ChangeType(boolean isRunPart, String name) {
+ fIsModification= isRunPart;
+ fName= name;
+ }
+
+ /**
+ * Returns <code>true</code> if changes of this type modify text.
+ *
+ * @return <code>true</code> if changes of this type modify text,
+ * <code>false</code> otherwise
+ */
+ boolean isModification() {
+ return fIsModification;
+ }
+
+ /*
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return fName;
+ }
+ }
+
+ /**
+ * Creates a new run.
+ *
+ * @param type the type of the run
+ */
+ TypingRun(ChangeType type) {
+ this.type= type;
+ }
+
+ /** The change type of this run. */
+ public final ChangeType type;
+}
\ No newline at end of file
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.ITextListener;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.TextEvent;
+
+import net.sourceforge.phpdt.internal.ui.text.TypingRun.ChangeType;
+
+
+/**
+ * When connected to a text viewer, a <code>TypingRunDetector</code> observes
+ * <code>TypingRun</code> events. A typing run is a sequence of similar text
+ * modifications, such as inserting or deleting single characters.
+ * <p>
+ * Listeners are informed about the start and end of a <code>TypingRun</code>.
+ * </p>
+ *
+ * @since 3.0
+ */
+public class TypingRunDetector {
+ /*
+ * Implementation note: This class is independent of JDT and may be pulled
+ * up to jface.text if needed.
+ */
+
+ /** Debug flag. */
+ private static final boolean DEBUG= false;
+
+ /**
+ * Instances of this class abstract a text modification into a simple
+ * description. Typing runs consists of a sequence of one or more modifying
+ * changes of the same type. Every change records the type of change
+ * described by a text modification, and an offset it can be followed by
+ * another change of the same run.
+ */
+ private static final class Change {
+ private ChangeType fType;
+ private int fNextOffset;
+
+ /**
+ * Creates a new change of type <code>type</code>.
+ *
+ * @param type the <code>ChangeType</code> of the new change
+ * @param nextOffset the offset of the next change in a typing run
+ */
+ public Change(ChangeType type, int nextOffset) {
+ fType= type;
+ fNextOffset= nextOffset;
+ }
+
+ /**
+ * Returns <code>true</code> if the receiver can extend the typing
+ * range the last change of which is described by <code>change</code>.
+ *
+ * @param change the last change in a typing run
+ * @return <code>true</code> if the receiver is a valid extension to
+ * <code>change</code>,<code>false</code> otherwise
+ */
+ public boolean canFollow(Change change) {
+ if (fType == TypingRun.NO_CHANGE)
+ return true;
+ else if (fType.equals(TypingRun.UNKNOWN))
+ return false;
+ if (fType.equals(change.fType)) {
+ if (fType == TypingRun.DELETE)
+ return fNextOffset == change.fNextOffset - 1;
+ else if (fType == TypingRun.INSERT)
+ return fNextOffset == change.fNextOffset + 1;
+ else if (fType == TypingRun.OVERTYPE)
+ return fNextOffset == change.fNextOffset + 1;
+ else if (fType == TypingRun.SELECTION)
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns <code>true</code> if the receiver describes a text
+ * modification, <code>false</code> if it describes a focus /
+ * selection change.
+ *
+ * @return <code>true</code> if the receiver is a text modification
+ */
+ public boolean isModification() {
+ return fType.isModification();
+ }
+
+ /*
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return fType.toString() + "@" + fNextOffset; //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the change type of this change.
+ *
+ * @return the change type of this change
+ */
+ public ChangeType getType() {
+ return fType;
+ }
+ }
+
+ /**
+ * Observes any events that modify the content of the document displayed in
+ * the editor. Since text events may start a new run, this listener is
+ * always registered if the detector is connected.
+ */
+ private class TextListener implements ITextListener {
+
+ /*
+ * @see org.eclipse.jface.text.ITextListener#textChanged(org.eclipse.jface.text.TextEvent)
+ */
+ public void textChanged(TextEvent event) {
+ handleTextChanged(event);
+ }
+ }
+
+ /**
+ * Observes non-modifying events that will end a run, such as clicking into
+ * the editor, moving the caret, and the editor losing focus. These events
+ * can never start a run, therefore this listener is only registered if
+ * there is an ongoing run.
+ */
+ private class SelectionListener implements MouseListener, KeyListener, FocusListener {
+
+ /*
+ * @see org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.swt.events.FocusEvent)
+ */
+ public void focusGained(FocusEvent e) {
+ handleSelectionChanged();
+ }
+
+ /*
+ * @see org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt.events.FocusEvent)
+ */
+ public void focusLost(FocusEvent e) {
+ }
+
+ /*
+ * @see MouseListener#mouseDoubleClick
+ */
+ public void mouseDoubleClick(MouseEvent e) {
+ }
+
+ /*
+ * If the right mouse button is pressed, the current editing command is closed
+ * @see MouseListener#mouseDown
+ */
+ public void mouseDown(MouseEvent e) {
+ if (e.button == 1)
+ handleSelectionChanged();
+ }
+
+ /*
+ * @see MouseListener#mouseUp
+ */
+ public void mouseUp(MouseEvent e) {
+ }
+
+ /*
+ * @see KeyListener#keyPressed
+ */
+ public void keyReleased(KeyEvent e) {
+ }
+
+ /*
+ * On cursor keys, the current editing command is closed
+ * @see KeyListener#keyPressed
+ */
+ public void keyPressed(KeyEvent e) {
+ switch (e.keyCode) {
+ case SWT.ARROW_UP:
+ case SWT.ARROW_DOWN:
+ case SWT.ARROW_LEFT:
+ case SWT.ARROW_RIGHT:
+ case SWT.END:
+ case SWT.HOME:
+ case SWT.PAGE_DOWN:
+ case SWT.PAGE_UP:
+ handleSelectionChanged();
+ break;
+ }
+ }
+ }
+
+ /** The listeners. */
+ private final Set fListeners= new HashSet();
+ /**
+ * The viewer we work upon. Set to <code>null</code> in
+ * <code>uninstall</code>.
+ */
+ private ITextViewer fViewer;
+ /** The text event listener. */
+ private final TextListener fTextListener= new TextListener();
+ /**
+ * The selection listener. Set to <code>null</code> when no run is active.
+ */
+ private SelectionListener fSelectionListener;
+
+ /* state variables */
+
+ /** The most recently observed change. Never <code>null</code>. */
+ private Change fLastChange;
+ /** The current run, or <code>null</code> if there is none. */
+ private TypingRun fRun;
+
+ /**
+ * Installs the receiver with a text viewer.
+ *
+ * @param viewer the viewer to install on
+ */
+ public void install(ITextViewer viewer) {
+ Assert.isLegal(viewer != null);
+ fViewer= viewer;
+ connect();
+ }
+
+ /**
+ * Initializes the state variables and registers any permanent listeners.
+ */
+ private void connect() {
+ if (fViewer != null) {
+ fLastChange= new Change(TypingRun.UNKNOWN, -1);
+ fRun= null;
+ fSelectionListener= null;
+ fViewer.addTextListener(fTextListener);
+ }
+ }
+
+ /**
+ * Uninstalls the receiver and removes all listeners. <code>install()</code>
+ * must be called for events to be generated.
+ */
+ public void uninstall() {
+ if (fViewer != null) {
+ fListeners.clear();
+ disconnect();
+ fViewer= null;
+ }
+ }
+
+ /**
+ * Disconnects any registered listeners.
+ */
+ private void disconnect() {
+ fViewer.removeTextListener(fTextListener);
+ ensureSelectionListenerRemoved();
+ }
+
+ /**
+ * Adds a listener for <code>TypingRun</code> events. Repeatedly adding
+ * the same listener instance has no effect. Listeners may be added even
+ * if the receiver is neither connected nor installed.
+ *
+ * @param listener the listener add
+ */
+ public void addTypingRunListener(ITypingRunListener listener) {
+ Assert.isLegal(listener != null);
+ fListeners.add(listener);
+ if (fListeners.size() == 1)
+ connect();
+ }
+
+ /**
+ * Removes the listener from this manager. If <code>listener</code> is not
+ * registered with the receiver, nothing happens.
+ *
+ * @param listener the listener to remove, or <code>null</code>
+ */
+ public void removeTypingRunListener(ITypingRunListener listener) {
+ fListeners.remove(listener);
+ if (fListeners.size() == 0)
+ disconnect();
+ }
+
+ /**
+ * Handles an incoming text event.
+ *
+ * @param event the text event that describes the text modification
+ */
+ void handleTextChanged(TextEvent event) {
+ Change type= computeChange(event);
+ handleChange(type);
+ }
+
+ /**
+ * Computes the change abstraction given a text event.
+ *
+ * @param event the text event to analyze
+ * @return a change object describing the event
+ */
+ private Change computeChange(TextEvent event) {
+ DocumentEvent e= event.getDocumentEvent();
+ if (e == null)
+ return new Change(TypingRun.NO_CHANGE, -1);
+
+ int start= e.getOffset();
+ int end= e.getOffset() + e.getLength();
+ String newText= e.getText();
+ if (newText == null)
+ newText= new String();
+
+ if (start == end) {
+ // no replace / delete / overwrite
+ if (newText.length() == 1)
+ return new Change(TypingRun.INSERT, end + 1);
+ } else if (start == end - 1) {
+ if (newText.length() == 1)
+ return new Change(TypingRun.OVERTYPE, end);
+ if (newText.length() == 0)
+ return new Change(TypingRun.DELETE, start);
+ }
+
+ return new Change(TypingRun.UNKNOWN, -1);
+ }
+
+ /**
+ * Handles an incoming selection event.
+ */
+ void handleSelectionChanged() {
+ handleChange(new Change(TypingRun.SELECTION, -1));
+ }
+
+ /**
+ * State machine. Changes state given the current state and the incoming
+ * change.
+ *
+ * @param change the incoming change
+ */
+ private void handleChange(Change change) {
+ if (change.getType() == TypingRun.NO_CHANGE)
+ return;
+
+ if (DEBUG)
+ System.err.println("Last change: " + fLastChange); //$NON-NLS-1$
+
+ if (!change.canFollow(fLastChange))
+ endIfStarted(change);
+ fLastChange= change;
+ if (change.isModification())
+ startOrContinue();
+
+ if (DEBUG)
+ System.err.println("New change: " + change); //$NON-NLS-1$
+ }
+
+ /**
+ * Starts a new run if there is none and informs all listeners. If there
+ * already is a run, nothing happens.
+ */
+ private void startOrContinue() {
+ if (!hasRun()) {
+ if (DEBUG)
+ System.err.println("+Start run"); //$NON-NLS-1$
+ fRun= new TypingRun(fLastChange.getType());
+ ensureSelectionListenerAdded();
+ fireRunBegun(fRun);
+ }
+ }
+
+ /**
+ * Returns <code>true</code> if there is an active run, <code>false</code>
+ * otherwise.
+ *
+ * @return <code>true</code> if there is an active run, <code>false</code>
+ * otherwise
+ */
+ private boolean hasRun() {
+ return fRun != null;
+ }
+
+ /**
+ * Ends any active run and informs all listeners. If there is none, nothing
+ * happens.
+ *
+ * @param change the change that triggered ending the active run
+ */
+ private void endIfStarted(Change change) {
+ if (hasRun()) {
+ ensureSelectionListenerRemoved();
+ if (DEBUG)
+ System.err.println("-End run"); //$NON-NLS-1$
+ fireRunEnded(fRun, change.getType());
+ fRun= null;
+ }
+ }
+
+ /**
+ * Adds the selection listener to the text widget underlying the viewer, if
+ * not already done.
+ */
+ private void ensureSelectionListenerAdded() {
+ if (fSelectionListener == null) {
+ fSelectionListener= new SelectionListener();
+ StyledText textWidget= fViewer.getTextWidget();
+ textWidget.addFocusListener(fSelectionListener);
+ textWidget.addKeyListener(fSelectionListener);
+ textWidget.addMouseListener(fSelectionListener);
+ }
+ }
+
+ /**
+ * If there is a selection listener, it is removed from the text widget
+ * underlying the viewer.
+ */
+ private void ensureSelectionListenerRemoved() {
+ if (fSelectionListener != null) {
+ StyledText textWidget= fViewer.getTextWidget();
+ textWidget.removeFocusListener(fSelectionListener);
+ textWidget.removeKeyListener(fSelectionListener);
+ textWidget.removeMouseListener(fSelectionListener);
+ fSelectionListener= null;
+ }
+ }
+
+ /**
+ * Informs all listeners about a newly started <code>TypingRun</code>.
+ *
+ * @param run the new run
+ */
+ private void fireRunBegun(TypingRun run) {
+ List listeners= new ArrayList(fListeners);
+ for (Iterator it= listeners.iterator(); it.hasNext();) {
+ ITypingRunListener listener= (ITypingRunListener) it.next();
+ listener.typingRunStarted(fRun);
+ }
+ }
+
+ /**
+ * Informs all listeners about an ended <code>TypingRun</code>.
+ *
+ * @param run the previously active run
+ * @param reason the type of change that caused the run to be ended
+ */
+ private void fireRunEnded(TypingRun run, ChangeType reason) {
+ List listeners= new ArrayList(fListeners);
+ for (Iterator it= listeners.iterator(); it.hasNext();) {
+ ITypingRunListener listener= (ITypingRunListener) it.next();
+ listener.typingRunEnded(fRun, reason);
+ }
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.java;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+import net.sourceforge.phpdt.core.dom.CompilationUnit;
+
+
+/**
+ * Interface of an object listening to Java reconciling.
+ *
+ * @since 3.0
+ */
+public interface IJavaReconcilingListener {
+
+ /**
+ * Called before reconciling is started.
+ */
+ void aboutToBeReconciled();
+
+ /**
+ * Called after reconciling has been finished.
+ * @param ast the compilation unit AST or <code>null</code> if
+ * the working copy was consistent or reconciliation has been cancelled
+ * @param forced <code>true</code> iff this reconciliation was forced
+ * @param progressMonitor the progress monitor
+ */
+ void reconciled(CompilationUnit ast, boolean forced, IProgressMonitor progressMonitor);
+}
private void javaStringIndentAfterNewLine(IDocument document, DocumentCommand command) throws BadLocationException {
- ITypedRegion partition= TextUtilities.getPartition(document, fPartitioning, command.offset);
+ ITypedRegion partition= TextUtilities.getPartition(document, fPartitioning, command.offset, false);
int offset= partition.getOffset();
int length= partition.getLength();
* IBM Corporation - initial API and implementation
*******************************************************************************/
package net.sourceforge.phpdt.internal.ui.text.java.hover;
-
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
}
/*
- * @see org.eclipse.jface.text.ITextHoverExtension#getInformationControlCreator()
+ * @see org.eclipse.jface.text.ITextHoverExtension#getHoverControlCreator()
* @since 3.0
*/
- public IInformationControlCreator getInformationControlCreator() {
+ public IInformationControlCreator getHoverControlCreator() {
if (fBestHover instanceof ITextHoverExtension)
- return ((ITextHoverExtension)fBestHover).getInformationControlCreator();
+ return ((ITextHoverExtension)fBestHover).getHoverControlCreator();
return null;
}
return null;
}
-}
+}
\ No newline at end of file
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.java.hover;
+
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.JavaSourceViewer;
+import net.sourceforge.phpeclipse.phpeditor.PHPSourceViewerConfiguration;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IInformationControl;
+import org.eclipse.jface.text.IInformationControlExtension;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * Source viewer based implementation of <code>IInformationControl</code>.
+ * Displays information in a source viewer.
+ *
+ * @since 3.0
+ */
+public class SourceViewerInformationControl implements IInformationControl, IInformationControlExtension, DisposeListener {
+
+ /** Border thickness in pixels. */
+ private static final int BORDER= 1;
+ /** The control's shell */
+ private Shell fShell;
+ /** The control's text widget */
+ private StyledText fText;
+ /** The control's source viewer */
+ private SourceViewer fViewer;
+ /**
+ * The optional status field.
+ *
+ * @since 3.0
+ */
+ private Label fStatusField;
+ /**
+ * The separator for the optional status field.
+ *
+ * @since 3.0
+ */
+ private Label fSeparator;
+ /**
+ * The font of the optional status text label.
+ *
+ * @since 3.0
+ */
+ private Font fStatusTextFont;
+
+ /**
+ * Creates a default information control with the given shell as parent. The given
+ * information presenter is used to process the information to be displayed. The given
+ * styles are applied to the created styled text widget.
+ *
+ * @param parent the parent shell
+ * @param shellStyle the additional styles for the shell
+ * @param style the additional styles for the styled text widget
+ */
+ public SourceViewerInformationControl(Shell parent, int shellStyle, int style) {
+ this(parent, shellStyle, style, null);
+ }
+
+ /**
+ * Creates a default information control with the given shell as parent. The given
+ * information presenter is used to process the information to be displayed. The given
+ * styles are applied to the created styled text widget.
+ *
+ * @param parent the parent shell
+ * @param shellStyle the additional styles for the shell
+ * @param style the additional styles for the styled text widget
+ * @param statusFieldText the text to be used in the optional status field
+ * or <code>null</code> if the status field should be hidden
+ * @since 3.0
+ */
+ public SourceViewerInformationControl(Shell parent, int shellStyle, int style, String statusFieldText) {
+ GridLayout layout;
+ GridData gd;
+
+ fShell= new Shell(parent, SWT.NO_FOCUS | SWT.ON_TOP | shellStyle);
+ Display display= fShell.getDisplay();
+ fShell.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
+
+ Composite composite= fShell;
+ layout= new GridLayout(1, false);
+ int border= ((shellStyle & SWT.NO_TRIM) == 0) ? 0 : BORDER;
+ layout.marginHeight= border;
+ layout.marginWidth= border;
+ composite.setLayout(layout);
+ gd= new GridData(GridData.FILL_HORIZONTAL);
+ composite.setLayoutData(gd);
+
+ if (statusFieldText != null) {
+ composite= new Composite(composite, SWT.NONE);
+ layout= new GridLayout(1, false);
+ layout.marginHeight= 0;
+ layout.marginWidth= 0;
+ composite.setLayout(layout);
+ gd= new GridData(GridData.FILL_BOTH);
+ composite.setLayoutData(gd);
+ composite.setForeground(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
+ composite.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
+ }
+
+ // Source viewer
+ IPreferenceStore store= PHPeclipsePlugin.getDefault().getCombinedPreferenceStore();
+ fViewer= new JavaSourceViewer(composite, null, null, false, style, store);
+ fViewer.configure(new PHPSourceViewerConfiguration(PHPeclipsePlugin.getDefault().getJavaTextTools().getColorManager(), store, null, null));
+ fViewer.setEditable(false);
+
+ fText= fViewer.getTextWidget();
+ gd= new GridData(GridData.BEGINNING | GridData.FILL_BOTH);
+ fText.setLayoutData(gd);
+ fText.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
+ fText.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
+
+ fText.addKeyListener(new KeyListener() {
+
+ public void keyPressed(KeyEvent e) {
+ if (e.character == 0x1B) // ESC
+ fShell.dispose();
+ }
+
+ public void keyReleased(KeyEvent e) {}
+ });
+
+ // Status field
+ if (statusFieldText != null) {
+
+ // Horizontal separator line
+ fSeparator= new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL | SWT.LINE_DOT);
+ fSeparator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ // Status field label
+ fStatusField= new Label(composite, SWT.RIGHT);
+ fStatusField.setText(statusFieldText);
+ Font font= fStatusField.getFont();
+ FontData[] fontDatas= font.getFontData();
+ for (int i= 0; i < fontDatas.length; i++)
+ fontDatas[i].setHeight(fontDatas[i].getHeight() * 9 / 10);
+ fStatusTextFont= new Font(fStatusField.getDisplay(), fontDatas);
+ fStatusField.setFont(fStatusTextFont);
+ GridData gd2= new GridData(GridData.FILL_VERTICAL | GridData.FILL_HORIZONTAL | GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING);
+ fStatusField.setLayoutData(gd2);
+
+ // Regarding the color see bug 41128
+ fStatusField.setForeground(display.getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW));
+
+ fStatusField.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
+ }
+
+ addDisposeListener(this);
+ }
+
+ /**
+ * Creates a default information control with the given shell as parent. The given
+ * information presenter is used to process the information to be displayed. The given
+ * styles are applied to the created styled text widget.
+ *
+ * @param parent the parent shell
+ * @param style the additional styles for the styled text widget
+ */
+ public SourceViewerInformationControl(Shell parent,int style) {
+ this(parent, SWT.NO_TRIM, style);
+ }
+
+ /**
+ * Creates a default information control with the given shell as parent. The given
+ * information presenter is used to process the information to be displayed. The given
+ * styles are applied to the created styled text widget.
+ *
+ * @param parent the parent shell
+ * @param style the additional styles for the styled text widget
+ * @param statusFieldText the text to be used in the optional status field
+ * or <code>null</code> if the status field should be hidden
+ * @since 3.0
+ */
+ public SourceViewerInformationControl(Shell parent,int style, String statusFieldText) {
+ this(parent, SWT.NO_TRIM, style, statusFieldText);
+ }
+
+ /**
+ * Creates a default information control with the given shell as parent.
+ * No information presenter is used to process the information
+ * to be displayed. No additional styles are applied to the styled text widget.
+ *
+ * @param parent the parent shell
+ */
+ public SourceViewerInformationControl(Shell parent) {
+ this(parent, SWT.NONE);
+ }
+
+ /**
+ * Creates a default information control with the given shell as parent.
+ * No information presenter is used to process the information
+ * to be displayed. No additional styles are applied to the styled text widget.
+ *
+ * @param parent the parent shell
+ * @param statusFieldText the text to be used in the optional status field
+ * or <code>null</code> if the status field should be hidden
+ * @since 3.0
+ */
+ public SourceViewerInformationControl(Shell parent, String statusFieldText) {
+ this(parent, SWT.NONE, statusFieldText);
+ }
+
+ /*
+ * @see org.eclipse.jface.text.IInformationControlExtension2#setInput(java.lang.Object)
+ */
+ public void setInput(Object input) {
+ if (input instanceof String)
+ setInformation((String)input);
+ else
+ setInformation(null);
+ }
+
+ /*
+ * @see IInformationControl#setInformation(String)
+ */
+ public void setInformation(String content) {
+ if (content == null) {
+ fViewer.setInput(null);
+ return;
+ }
+
+ IDocument doc= new Document(content);
+ PHPeclipsePlugin.getDefault().getJavaTextTools().setupJavaDocumentPartitioner(doc);
+
+ fViewer.setInput(doc);
+ }
+
+ /*
+ * @see IInformationControl#setVisible(boolean)
+ */
+ public void setVisible(boolean visible) {
+ fShell.setVisible(visible);
+ }
+
+ /**
+ * {@inheritDoc}
+ * @since 3.0
+ */
+ public void widgetDisposed(DisposeEvent event) {
+ if (fStatusTextFont != null && !fStatusTextFont.isDisposed())
+ fStatusTextFont.dispose();
+
+ fStatusTextFont= null;
+ fShell= null;
+ fText= null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void dispose() {
+ if (fShell != null && !fShell.isDisposed())
+ fShell.dispose();
+ else
+ widgetDisposed(null);
+ }
+
+ /*
+ * @see IInformationControl#setSize(int, int)
+ */
+ public void setSize(int width, int height) {
+
+ if (fStatusField != null) {
+ GridData gd= (GridData)fViewer.getTextWidget().getLayoutData();
+ Point statusSize= fStatusField.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
+ Point separatorSize= fSeparator.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
+ gd.heightHint= height - statusSize.y - separatorSize.y;
+ }
+ fShell.setSize(width, height);
+
+ if (fStatusField != null)
+ fShell.pack(true);
+ }
+
+ /*
+ * @see IInformationControl#setLocation(Point)
+ */
+ public void setLocation(Point location) {
+ Rectangle trim= fShell.computeTrim(0, 0, 0, 0);
+ Point textLocation= fText.getLocation();
+ location.x += trim.x - textLocation.x;
+ location.y += trim.y - textLocation.y;
+ fShell.setLocation(location);
+ }
+
+ /*
+ * @see IInformationControl#setSizeConstraints(int, int)
+ */
+ public void setSizeConstraints(int maxWidth, int maxHeight) {
+ maxWidth= maxHeight;
+ }
+
+ /*
+ * @see IInformationControl#computeSizeHint()
+ */
+ public Point computeSizeHint() {
+ return fShell.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+ }
+
+ /*
+ * @see IInformationControl#addDisposeListener(DisposeListener)
+ */
+ public void addDisposeListener(DisposeListener listener) {
+ fShell.addDisposeListener(listener);
+ }
+
+ /*
+ * @see IInformationControl#removeDisposeListener(DisposeListener)
+ */
+ public void removeDisposeListener(DisposeListener listener) {
+ fShell.removeDisposeListener(listener);
+ }
+
+ /*
+ * @see IInformationControl#setForegroundColor(Color)
+ */
+ public void setForegroundColor(Color foreground) {
+ fText.setForeground(foreground);
+ }
+
+ /*
+ * @see IInformationControl#setBackgroundColor(Color)
+ */
+ public void setBackgroundColor(Color background) {
+ fText.setBackground(background);
+ }
+
+ /*
+ * @see IInformationControl#isFocusControl()
+ */
+ public boolean isFocusControl() {
+ return fText.isFocusControl();
+ }
+
+ /*
+ * @see IInformationControl#setFocus()
+ */
+ public void setFocus() {
+ fShell.forceFocus();
+ fText.setFocus();
+ }
+
+ /*
+ * @see IInformationControl#addFocusListener(FocusListener)
+ */
+ public void addFocusListener(FocusListener listener) {
+ fText.addFocusListener(listener);
+ }
+
+ /*
+ * @see IInformationControl#removeFocusListener(FocusListener)
+ */
+ public void removeFocusListener(FocusListener listener) {
+ fText.removeFocusListener(listener);
+ }
+
+ /*
+ * @see IInformationControlExtension#hasContents()
+ */
+ public boolean hasContents() {
+ return fText.getCharCount() > 0;
+ }
+
+ protected ISourceViewer getViewer() {
+ return fViewer;
+ }
+}
try {
if (position.getType().equals(currentPosition.getType()) && !position.equals(currentPosition))
- command.addCommand(position.getOffset() + deltaOffset, command.length, command.text, true, this);
+ command.addCommand(position.getOffset() + deltaOffset, command.length, command.text, this);
} catch (BadLocationException e) {
PHPeclipsePlugin.log(e);
}
fireChanges(changes, true);
}
}
-
/* (non-Javadoc)
* @see IAnnotationModelListener#modelChanged(IAnnotationModel)
*/
public void modelChanged(AnnotationModelEvent event) {
if (event instanceof CompilationUnitAnnotationModelEvent) {
CompilationUnitAnnotationModelEvent cuEvent= (CompilationUnitAnnotationModelEvent) event;
- if (cuEvent.includesMarkerAnnotationChanges()) {
+ if (cuEvent.includesProblemMarkerAnnotationChanges()) {
IResource[] changes= new IResource[] { cuEvent.getUnderlyingResource() };
fireChanges(changes, false);
}
}
}
-
/**
* Adds a listener for problem marker changes.
*/
* All Rights Reserved.
*/
-import net.sourceforge.phpdt.internal.ui.text.FastJavaPartitionScanner;
import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
import net.sourceforge.phpdt.internal.ui.text.JavaColorManager;
import net.sourceforge.phpdt.internal.ui.text.phpdoc.PHPDocCodeScanner;
import net.sourceforge.phpeclipse.phpeditor.php.SmartyCodeScanner;
import net.sourceforge.phpeclipse.phpeditor.php.SmartyDocCodeScanner;
+import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.rules.RuleBasedScanner;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.ui.part.FileEditorInput;
//
//import org.phpeclipse.phpdt.internal.ui.text.FastJavaPartitionScanner;
//import org.phpeclipse.phpdt.internal.ui.text.JavaColorManager;
return partitioner;
}
-
/**
- * Sets up the Java document partitioner for the given document for the given partitioning.
+ * Sets up the Java document partitioner for the given document for the default partitioning.
*
* @param document the document to be set up
+ * @since 3.0
+ */
+ public void setupJavaDocumentPartitioner(IDocument document) {
+ setupJavaDocumentPartitioner(document, IDocumentExtension3.DEFAULT_PARTITIONING,null);
+ }
+ /**
+ * Sets up the Java document partitioner for the given document for the given partitioning.
+ * @param document the document to be set up
* @param partitioning the document partitioning
+ * @param element TODO
+ *
* @since 3.0
*/
- public void setupJavaDocumentPartitioner(IDocument document, String partitioning) {
- IDocumentPartitioner partitioner= createDocumentPartitioner();
- if (document instanceof IDocumentExtension3) {
- IDocumentExtension3 extension3= (IDocumentExtension3) document;
- extension3.setDocumentPartitioner(partitioning, partitioner);
- } else {
+ public void setupJavaDocumentPartitioner(IDocument document, String partitioning, Object element) {
+ IDocumentPartitioner partitioner = createDocumentPartitioner(".php");
+
+// if (document instanceof IDocumentExtension3) {
+// IDocumentExtension3 extension3= (IDocumentExtension3) document;
+// extension3.setDocumentPartitioner(partitioning, partitioner);
+// } else {
+ document.setDocumentPartitioner(partitioner);
+// }
+ partitioner.connect(document);
+ }
+ public void setupHTMLDocumentPartitioner(IDocument document, String partitioning, Object element) {
+ IDocumentPartitioner partitioner = createDocumentPartitioner(".html");
+
+// if (document instanceof IDocumentExtension3) {
+// IDocumentExtension3 extension3= (IDocumentExtension3) document;
+// extension3.setDocumentPartitioner(partitioning, partitioner);
+// } else {
+ document.setDocumentPartitioner(partitioner);
+// }
+ partitioner.connect(document);
+ }
+ public void setupSmartyDocumentPartitioner(IDocument document, String partitioning, Object element) {
+ IDocumentPartitioner partitioner = createDocumentPartitioner(".tpl");
+
+// if (document instanceof IDocumentExtension3) {
+// IDocumentExtension3 extension3= (IDocumentExtension3) document;
+// extension3.setDocumentPartitioner(partitioning, partitioner);
+// } else {
document.setDocumentPartitioner(partitioner);
- }
+// }
partitioner.connect(document);
}
-
/**
* Returns the names of the document position categories used by the document
* partitioners created by this object to manage their partition information.
import java.util.Set;
import net.sourceforge.phpeclipse.PHPeclipsePlugin;
-import net.sourceforge.phpeclipse.phpeditor.PHPEditor;
import net.sourceforge.phpeclipse.phpeditor.PHPSourceViewerConfiguration;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.ui.texteditor.ITextEditor;
/**
* Modified from the XMLFormatter. Some tags in HTML do not indent.
private PHPSourceViewerConfiguration fConfig;
private SourceViewer fViewer;
//
- private PHPEditor fEditor;
+ private ITextEditor fEditor;
private String fFilename;
////////////////////////////////////////////////////////////////////////
package net.sourceforge.phpeclipse.phpeditor.html;
-import net.sourceforge.phpeclipse.phpeditor.PHPEditor;
import net.sourceforge.phpeclipse.phpeditor.PHPSourceViewerConfiguration;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.formatter.IFormattingStrategy;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.ui.texteditor.ITextEditor;
/**
* @author chrisl
private PHPSourceViewerConfiguration fConfig;
private ISourceViewer fViewer;
//
- private PHPEditor fEditor;
+ private ITextEditor fEditor;
private int fTabWidth;
////////////////////////////////////////////////////////////////////////