--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>net.sourceforge.phpeclipse.32.compatibility</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+#Thu Jun 26 21:18:27 CDT 2008
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
+org.eclipse.jdt.core.compiler.compliance=1.4
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
+org.eclipse.jdt.core.compiler.source=1.3
--- /dev/null
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Compatability Fragment
+Bundle-SymbolicName: net.sourceforge.phpeclipse.32.compatibility
+Bundle-Version: 1.0.0
+Fragment-Host: net.sourceforge.phpeclipse;bundle-version="0.0.0"
+Bundle-RequiredExecutionEnvironment: J2SE-1.4
+Bundle-ClassPath: compatability.jar,
+ .
+Eclipse-PatchFragment: true
+Require-Bundle: net.sourceforge.phpeclipse.launching,
+ net.sourceforge.phpeclipse.core;bundle-version="0.0.0"
--- /dev/null
+bin.includes = META-INF/,\
+ fragment.xml,\
+ compatability.jar
+source.compatability.jar = src/
+jars.compile.order = compatability.jar
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<fragment>
+
+</fragment>
--- /dev/null
+package net.sourceforge.phpdt.externaltools.actions;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.MessageFormat;
+import java.util.Hashtable;
+
+import net.sourceforge.phpdt.externaltools.util.StringUtil;
+import net.sourceforge.phpeclipse.externaltools.ExternalToolsPlugin;
+import net.sourceforge.phpeclipse.externaltools.PHPConsole;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.ui.texteditor.MarkerUtilities;
+
+/**
+ * Calls the external parser and generates problem markers if necessary
+ */
+public class ExternalPHPParser {
+ private final static String PROBLEM_ID = "net.sourceforge.phpeclipse.problem";
+
+ // strings for external parser call
+ private static final String PARSE_ERROR_STRING = "Parse error"; //$NON-NLS-1$
+
+ private static final String PARSE_WARNING_STRING = "Warning"; //$NON-NLS-1$
+
+ public static final int ERROR = 2;
+
+ public static final int WARNING = 1;
+
+ public static final int INFO = 0;
+
+ public static final int TASK = 3;
+
+ // TODO design error? Analyze why fileToParse must be static ???
+ final protected IFile fFileToParse;
+
+ public ExternalPHPParser(IFile file) {
+ fFileToParse = file;
+ }
+
+ /**
+ * Call the php parse command ( php -l -f <filename> ) and create
+ * markers according to the external parser output.
+ *
+ * @param file
+ * the file that will be parsed
+ */
+ public void phpExternalParse() {
+ // IFile file = (IFile) resource;
+ // final IPath path = file.getFullPath();
+ final IPreferenceStore store = ExternalToolsPlugin.getDefault()
+ .getPreferenceStore();
+ final String filename = fFileToParse.getLocation().toString();
+
+ final String[] arguments = { filename };
+ final MessageFormat form = new MessageFormat(store
+ .getString(ExternalToolsPlugin.EXTERNAL_PARSER_PREF));
+ final String command = form.format(arguments);
+
+ final String parserResult = getParserOutput(command,
+ "External parser: ");
+
+ try {
+ // parse the buffer to find the errors and warnings
+ createMarkers(parserResult, fFileToParse);
+ } catch (CoreException e) {
+ }
+ }
+
+ /**
+ * Create markers according to the external parser output.
+ *
+ * @param output
+ * the external parser output
+ * @param file
+ * the file that was parsed.
+ */
+ protected void createMarkers(final String output, final IFile file)
+ throws CoreException {
+ // delete all markers
+ file.deleteMarkers(PROBLEM_ID, false, 0);
+
+ int indx = 0;
+ int brIndx;
+ boolean flag = true;
+ while ((brIndx = output.indexOf("<br />", indx)) != -1) {
+ // newer php error output (tested with 4.2.3)
+ scanLine(output, file, indx, brIndx);
+ indx = brIndx + 6;
+ flag = false;
+ }
+ if (flag) {
+ while ((brIndx = output.indexOf("<br>", indx)) != -1) {
+ // older php error output (tested with 4.2.3)
+ scanLine(output, file, indx, brIndx);
+ indx = brIndx + 4;
+ }
+ }
+ }
+
+ private void scanLine(final String output, final IFile file,
+ final int indx, final int brIndx) throws CoreException {
+ String current;
+ // String outLineNumberString; never used
+ final StringBuffer lineNumberBuffer = new StringBuffer(10);
+ char ch;
+ current = output.substring(indx, brIndx);
+
+ if (current.indexOf(PARSE_WARNING_STRING) != -1
+ || current.indexOf(PARSE_ERROR_STRING) != -1) {
+ final int onLine = current.indexOf("on line <b>");
+ if (onLine != -1) {
+ lineNumberBuffer.delete(0, lineNumberBuffer.length());
+ for (int i = onLine; i < current.length(); i++) {
+ ch = current.charAt(i);
+ if ('0' <= ch && '9' >= ch) {
+ lineNumberBuffer.append(ch);
+ }
+ }
+
+ final int lineNumber = Integer.parseInt(lineNumberBuffer
+ .toString());
+
+ final Hashtable attributes = new Hashtable();
+
+ current = StringUtil.replaceAll(current, "\n", "");
+ current = StringUtil.replaceAll(current, "<b>", "");
+ current = StringUtil.replaceAll(current, "</b>", "");
+ MarkerUtilities.setMessage(attributes, current);
+
+ if (current.indexOf(PARSE_ERROR_STRING) != -1)
+ attributes.put(IMarker.SEVERITY, new Integer(
+ IMarker.SEVERITY_ERROR));
+ else if (current.indexOf(PARSE_WARNING_STRING) != -1)
+ attributes.put(IMarker.SEVERITY, new Integer(
+ IMarker.SEVERITY_WARNING));
+ else
+ attributes.put(IMarker.SEVERITY, new Integer(
+ IMarker.SEVERITY_INFO));
+ MarkerUtilities.setLineNumber(attributes, lineNumber);
+ MarkerUtilities.createMarker(file, attributes, PROBLEM_ID);
+ }
+ }
+ }
+
+ /**
+ * This will set a marker.
+ *
+ * @param file
+ * the file that generated the marker
+ * @param message
+ * the message
+ * @param charStart
+ * the starting character
+ * @param charEnd
+ * the end character
+ * @param errorLevel
+ * the error level ({@link ExternalPHPParser#ERROR},{@link ExternalPHPParser#INFO},{@link ExternalPHPParser#WARNING}),
+ * {@link ExternalPHPParser#TASK})
+ * @throws CoreException
+ * an exception throwed by the MarkerUtilities
+ */
+ private void setMarker(final IFile file, final String message,
+ final int charStart, final int charEnd, final int errorLevel)
+ throws CoreException {
+ if (file != null) {
+ final Hashtable attributes = new Hashtable();
+ MarkerUtilities.setMessage(attributes, message);
+ switch (errorLevel) {
+ case ERROR:
+ attributes.put(IMarker.SEVERITY, new Integer(
+ IMarker.SEVERITY_ERROR));
+ break;
+ case WARNING:
+ attributes.put(IMarker.SEVERITY, new Integer(
+ IMarker.SEVERITY_WARNING));
+ break;
+ case INFO:
+ attributes.put(IMarker.SEVERITY, new Integer(
+ IMarker.SEVERITY_INFO));
+ break;
+ case TASK:
+ attributes.put(IMarker.SEVERITY, new Integer(IMarker.TASK));
+ break;
+ }
+ MarkerUtilities.setCharStart(attributes, charStart);
+ MarkerUtilities.setCharEnd(attributes, charEnd);
+ MarkerUtilities.createMarker(file, attributes, PROBLEM_ID);
+ }
+ }
+
+ /**
+ * This will set a marker.
+ *
+ * @param file
+ * the file that generated the marker
+ * @param message
+ * the message
+ * @param line
+ * the line number
+ * @param errorLevel
+ * the error level ({@link ExternalPHPParser#ERROR},{@link ExternalPHPParser#INFO},{@link ExternalPHPParser#WARNING})
+ * @throws CoreException
+ * an exception throwed by the MarkerUtilities
+ */
+ private void setMarker(final IFile file, final String message,
+ final int line, final int errorLevel, final String location)
+ throws CoreException {
+ if (file != null) {
+ String markerKind = PROBLEM_ID;
+ final Hashtable attributes = new Hashtable();
+ MarkerUtilities.setMessage(attributes, message);
+ switch (errorLevel) {
+ case ERROR:
+ attributes.put(IMarker.SEVERITY, new Integer(
+ IMarker.SEVERITY_ERROR));
+ break;
+ case WARNING:
+ attributes.put(IMarker.SEVERITY, new Integer(
+ IMarker.SEVERITY_WARNING));
+ break;
+ case INFO:
+ attributes.put(IMarker.SEVERITY, new Integer(
+ IMarker.SEVERITY_INFO));
+ break;
+ case TASK:
+ attributes.put(IMarker.SEVERITY, new Integer(
+ IMarker.SEVERITY_INFO));
+ markerKind = IMarker.TASK;
+ break;
+ }
+ attributes.put(IMarker.LOCATION, location);
+ MarkerUtilities.setLineNumber(attributes, line);
+ MarkerUtilities.createMarker(file, attributes, markerKind);
+ }
+ }
+
+ /**
+ * This will set a marker.
+ *
+ * @param message
+ * the message
+ * @param charStart
+ * the starting character
+ * @param charEnd
+ * the end character
+ * @param errorLevel
+ * the error level ({@link ExternalPHPParser#ERROR},{@link ExternalPHPParser#INFO},{@link ExternalPHPParser#WARNING})
+ * @throws CoreException
+ * an exception throwed by the MarkerUtilities
+ */
+ private void setMarker(final String message, final int charStart,
+ final int charEnd, final int errorLevel, final String location)
+ throws CoreException {
+ if (fFileToParse != null) {
+ setMarker(fFileToParse, message, charStart, charEnd, errorLevel,
+ location);
+ }
+ }
+
+ /**
+ * This will set a marker.
+ *
+ * @param file
+ * the file that generated the marker
+ * @param message
+ * the message
+ * @param charStart
+ * the starting character
+ * @param charEnd
+ * the end character
+ * @param errorLevel
+ * the error level ({@link ExternalPHPParser#ERROR},{@link ExternalPHPParser#INFO},{@link ExternalPHPParser#WARNING})
+ * @param location
+ * the location of the error
+ * @throws CoreException
+ * an exception throwed by the MarkerUtilities
+ */
+ private void setMarker(final IFile file, final String message,
+ final int charStart, final int charEnd, final int errorLevel,
+ final String location) throws CoreException {
+ if (file != null) {
+ final Hashtable attributes = new Hashtable();
+ MarkerUtilities.setMessage(attributes, message);
+ switch (errorLevel) {
+ case ERROR:
+ attributes.put(IMarker.SEVERITY, new Integer(
+ IMarker.SEVERITY_ERROR));
+ break;
+ case WARNING:
+ attributes.put(IMarker.SEVERITY, new Integer(
+ IMarker.SEVERITY_WARNING));
+ break;
+ case INFO:
+ attributes.put(IMarker.SEVERITY, new Integer(
+ IMarker.SEVERITY_INFO));
+ break;
+ case TASK:
+ attributes.put(IMarker.SEVERITY, new Integer(IMarker.TASK));
+ break;
+ }
+ attributes.put(IMarker.LOCATION, location);
+ MarkerUtilities.setCharStart(attributes, charStart);
+ MarkerUtilities.setCharEnd(attributes, charEnd);
+ MarkerUtilities.createMarker(file, attributes, PROBLEM_ID); // IMarker.PROBLEM);
+ }
+ }
+
+ private String getParserOutput(String command, String consoleMessage) {
+ try {
+ PHPConsole console = new PHPConsole();
+ try {
+ console.println(consoleMessage + command);
+ } catch (Throwable th) {
+
+ }
+
+ Runtime runtime = Runtime.getRuntime();
+
+ // runs the command
+ Process p = runtime.exec(command);
+
+ // gets the input stream to have the post-compile-time information
+ InputStream stream = p.getInputStream();
+
+ // get the string from Stream
+ String consoleOutput = PHPConsole.getStringFromStream(stream);
+
+ // prints out the information
+ if (console != null) {
+ console.print(consoleOutput);
+ }
+ return consoleOutput;
+
+ } catch (IOException e) {
+ MessageDialog
+ .openInformation(null, "IOException: ", e.getMessage());
+ }
+ return "";
+ }
+}
\ 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.compiler.lookup;
+
+import java.util.ArrayList;
+
+import net.sourceforge.phpdt.core.compiler.CharOperation;
+import net.sourceforge.phpdt.internal.compiler.ast.CompilationUnitDeclaration;
+import net.sourceforge.phpdt.internal.compiler.ast.ImportReference;
+import net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration;
+import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
+import net.sourceforge.phpdt.internal.compiler.util.CompoundNameVector;
+import net.sourceforge.phpdt.internal.compiler.util.HashtableOfObject;
+import net.sourceforge.phpdt.internal.compiler.util.HashtableOfType;
+import net.sourceforge.phpdt.internal.compiler.util.ObjectVector;
+import net.sourceforge.phpdt.internal.compiler.util.SimpleNameVector;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IPath;
+
+public class CompilationUnitScope extends Scope {
+
+ public LookupEnvironment environment;
+
+ public CompilationUnitDeclaration referenceContext;
+
+ public char[][] currentPackageName;
+
+ public PackageBinding fPackage;
+
+ public ImportBinding[] imports;
+
+ public SourceTypeBinding[] topLevelTypes;
+
+ private CompoundNameVector qualifiedReferences;
+
+ private SimpleNameVector simpleNameReferences;
+
+ private ObjectVector referencedTypes;
+
+ HashtableOfType constantPoolNameUsage;
+
+ public HashtableOfObject resolvedSingeTypeImports;
+
+ public CompilationUnitScope(CompilationUnitDeclaration unit,
+ LookupEnvironment environment) {
+ super(COMPILATION_UNIT_SCOPE, null);
+ this.environment = environment;
+ this.referenceContext = unit;
+ unit.scope = this;
+ // this.currentPackageName = unit.currentPackage == null ?
+ // CharOperation.NO_CHAR_CHAR : unit.currentPackage.tokens;
+ this.currentPackageName = null;
+ // if (environment.options.produceReferenceInfo) {
+ // this.qualifiedReferences = new CompoundNameVector();
+ // this.simpleNameReferences = new SimpleNameVector();
+ // this.referencedTypes = new ObjectVector();
+ // } else {
+ this.qualifiedReferences = null; // used to test if dependencies
+ // should be recorded
+ this.simpleNameReferences = null;
+ this.referencedTypes = null;
+ // }
+ }
+
+ void buildFieldsAndMethods() {
+ for (int i = 0, length = topLevelTypes.length; i < length; i++)
+ topLevelTypes[i].scope.buildFieldsAndMethods();
+ }
+
+ void buildTypeBindings() {
+ if (referenceContext.compilationResult.compilationUnit != null) {
+ char[][] expectedPackageName = referenceContext.compilationResult.compilationUnit
+ .getPackageName();
+ if (expectedPackageName != null
+ && !CharOperation.equals(currentPackageName,
+ expectedPackageName)) {
+
+ // only report if the unit isn't structurally empty
+ // if (referenceContext.currentPackage != null
+ // || referenceContext.types != null
+ // || referenceContext.imports != null) {
+ // problemReporter().packageIsNotExpectedPackage(referenceContext);
+ // }
+ currentPackageName = expectedPackageName.length == 0 ? CharOperation.NO_CHAR_CHAR
+ : expectedPackageName;
+ }
+ }
+ if (currentPackageName == CharOperation.NO_CHAR_CHAR) {
+ if ((fPackage = environment.defaultPackage) == null) {
+ problemReporter().mustSpecifyPackage(referenceContext);
+ return;
+ }
+ } else {
+ if ((fPackage = environment.createPackage(currentPackageName)) == null) {
+ // problemReporter().packageCollidesWithType(referenceContext);
+ return;
+ }
+ recordQualifiedReference(currentPackageName); // always dependent
+ // on your own
+ // package
+ }
+
+ // Skip typeDeclarations which know of previously reported errors
+ ArrayList types = referenceContext.types;
+ int typeLength = (types == null) ? 0 : types.size();
+ topLevelTypes = new SourceTypeBinding[typeLength];
+ int count = 0;
+ nextType: for (int i = 0; i < typeLength; i++) {
+ if (types.get(i) instanceof TypeDeclaration) {
+ TypeDeclaration typeDecl = (TypeDeclaration) types.get(i);
+ ReferenceBinding typeBinding = fPackage.getType0(typeDecl.name);
+ recordSimpleReference(typeDecl.name); // needed to detect
+ // collision cases
+ if (typeBinding != null
+ && !(typeBinding instanceof UnresolvedReferenceBinding)) {
+ // if a type exists, it must be a valid type - cannot be a
+ // NotFound problem type
+ // unless its an unresolved type which is now being defined
+ problemReporter()
+ .duplicateTypes(referenceContext, typeDecl);
+ continue nextType;
+ }
+ if (fPackage != environment.defaultPackage
+ && fPackage.getPackage(typeDecl.name) != null) {
+ // if a package exists, it must be a valid package - cannot
+ // be a NotFound problem package
+ problemReporter().typeCollidesWithPackage(referenceContext,
+ typeDecl);
+ continue nextType;
+ }
+
+ if ((typeDecl.modifiers & AccPublic) != 0) {
+ char[] mainTypeName;
+ if ((mainTypeName = referenceContext.getMainTypeName()) != null
+ // mainTypeName == null means that implementor of
+ // ICompilationUnit decided to return null
+ && !CharOperation.equals(mainTypeName,
+ typeDecl.name)) {
+ problemReporter().publicClassMustMatchFileName(
+ referenceContext, typeDecl);
+ continue nextType;
+ }
+ }
+
+ ClassScope child = new ClassScope(this, typeDecl);
+ SourceTypeBinding type = child.buildType(null, fPackage);
+ if (type != null) {
+ topLevelTypes[count++] = type;
+ }
+ }
+ }
+
+ // shrink topLevelTypes... only happens if an error was reported
+ if (count != topLevelTypes.length)
+ System.arraycopy(topLevelTypes, 0,
+ topLevelTypes = new SourceTypeBinding[count], 0, count);
+ }
+
+ void checkAndSetImports() {
+ // initialize the default imports if necessary... share the default
+ // java.lang.* import
+ if (environment.defaultImports == null) {
+ Binding importBinding = environment.getTopLevelPackage(JAVA);
+ if (importBinding != null)
+ importBinding = ((PackageBinding) importBinding)
+ .getTypeOrPackage(JAVA_LANG[1]);
+
+ // abort if java.lang cannot be found...
+ if (importBinding == null || !importBinding.isValidBinding())
+ problemReporter().isClassPathCorrect(JAVA_LANG_OBJECT,
+ referenceCompilationUnit());
+
+ environment.defaultImports = new ImportBinding[] { new ImportBinding(
+ JAVA_LANG, true, importBinding, null) };
+ }
+ if (referenceContext.imports == null) {
+ imports = environment.defaultImports;
+ return;
+ }
+
+ // allocate the import array, add java.lang.* by default
+ int numberOfStatements = referenceContext.imports.length;
+ // int numberOfImports = numberOfStatements + 1;
+ int numberOfImports = numberOfStatements;
+ // for (int i = 0; i < numberOfStatements; i++) {
+ // ImportReference importReference = referenceContext.imports[i];
+ // if (importReference.onDemand && CharOperation.equals(JAVA_LANG,
+ // importReference.tokens)) {
+ // numberOfImports--;
+ // break;
+ // }
+ // }
+ ImportBinding[] resolvedImports = new ImportBinding[numberOfImports];
+ resolvedImports[0] = environment.defaultImports[0];
+ int index = 1;
+
+ nextImport: for (int i = 0; i < numberOfStatements; i++) {
+ ImportReference importReference = referenceContext.imports[i];
+ IFile file = importReference.getFile();
+ SourceTypeBinding typeBinding;
+ // char[][] compoundName = importReference.tokens;
+ char[][] compoundName = null;
+ if (file != null) {
+ IPath path = file.getProjectRelativePath();
+ String[] segs = path.segments();
+ compoundName = new char[segs.length][];
+ for (int j = 0; j < segs.length; j++) {
+ compoundName[j] = segs[j].toCharArray();
+ }
+ }
+ if (compoundName == null) {
+ continue nextImport;
+ }
+
+ // skip duplicates or imports of the current package
+ for (int j = 0; j < index; j++)
+ if (resolvedImports[j].onDemand == importReference.onDemand)
+ if (CharOperation.equals(compoundName,
+ resolvedImports[j].compoundName))
+ continue nextImport;
+ if (importReference.onDemand == true)
+ if (CharOperation.equals(compoundName, currentPackageName))
+ continue nextImport;
+
+ if (importReference.onDemand) {
+ Binding importBinding = findOnDemandImport(compoundName);
+ if (!importBinding.isValidBinding())
+ continue nextImport; // we report all problems in
+ // faultInImports()
+ resolvedImports[index++] = new ImportBinding(compoundName,
+ true, importBinding, importReference);
+ } else {
+ resolvedImports[index++] = new ImportBinding(compoundName,
+ false, null, importReference);
+ }
+ }
+
+ // shrink resolvedImports... only happens if an error was reported
+ if (resolvedImports.length > index)
+ System.arraycopy(resolvedImports, 0,
+ resolvedImports = new ImportBinding[index], 0, index);
+ imports = resolvedImports;
+ }
+
+ /*
+ * INTERNAL USE-ONLY Innerclasses get their name computed as they are
+ * generated, since some may not be actually outputed if sitting inside
+ * unreachable code.
+ */
+ public char[] computeConstantPoolName(LocalTypeBinding localType) {
+ if (localType.constantPoolName() != null) {
+ return localType.constantPoolName();
+ }
+ // delegates to the outermost enclosing classfile, since it is the only
+ // one with a global vision of its innertypes.
+
+ if (constantPoolNameUsage == null)
+ constantPoolNameUsage = new HashtableOfType();
+
+ ReferenceBinding outerMostEnclosingType = localType.scope
+ .outerMostClassScope().enclosingSourceType();
+
+ // ensure there is not already such a local type name defined by the
+ // user
+ int index = 0;
+ char[] candidateName;
+ while (true) {
+ if (localType.isMemberType()) {
+ if (index == 0) {
+ candidateName = CharOperation.concat(localType
+ .enclosingType().constantPoolName(),
+ localType.sourceName, '$');
+ } else {
+ // in case of collision, then member name gets extra $1
+ // inserted
+ // e.g. class X { { class L{} new X(){ class L{} } } }
+ candidateName = CharOperation.concat(localType
+ .enclosingType().constantPoolName(), '$', String
+ .valueOf(index).toCharArray(), '$',
+ localType.sourceName);
+ }
+ } else if (localType.isAnonymousType()) {
+ candidateName = CharOperation.concat(outerMostEnclosingType
+ .constantPoolName(), String.valueOf(index + 1)
+ .toCharArray(), '$');
+ } else {
+ candidateName = CharOperation.concat(outerMostEnclosingType
+ .constantPoolName(), '$', String.valueOf(index + 1)
+ .toCharArray(), '$', localType.sourceName);
+ }
+ if (constantPoolNameUsage.get(candidateName) != null) {
+ index++;
+ } else {
+ constantPoolNameUsage.put(candidateName, localType);
+ break;
+ }
+ }
+ return candidateName;
+ }
+
+ void connectTypeHierarchy() {
+ for (int i = 0, length = topLevelTypes.length; i < length; i++)
+ topLevelTypes[i].scope.connectTypeHierarchy();
+ }
+
+ void faultInImports() {
+ if (referenceContext.imports == null)
+ return;
+ //
+ // // collect the top level type names if a single type import exists
+ int numberOfStatements = referenceContext.imports.length;
+ // HashtableOfType typesBySimpleNames = null;
+ // for (int i = 0; i < numberOfStatements; i++) {
+ // if (!referenceContext.imports[i].onDemand) {
+ // typesBySimpleNames = new HashtableOfType(topLevelTypes.length +
+ // numberOfStatements);
+ // for (int j = 0, length = topLevelTypes.length; j < length; j++)
+ // typesBySimpleNames.put(topLevelTypes[j].sourceName,
+ // topLevelTypes[j]);
+ // break;
+ // }
+ // }
+ //
+ // // allocate the import array, add java.lang.* by default
+ // int numberOfImports = numberOfStatements + 1;
+ // for (int i = 0; i < numberOfStatements; i++) {
+ // ImportReference importReference = referenceContext.imports[i];
+ // if (importReference.onDemand && CharOperation.equals(JAVA_LANG,
+ // importReference.tokens)) {
+ // numberOfImports--;
+ // break;
+ // }
+ // }
+ ImportBinding[] resolvedImports = new ImportBinding[numberOfStatements];
+ // resolvedImports[0] = environment.defaultImports[0];
+ // int index = 1;
+ int index = 0;
+ nextImport: for (int i = 0; i < numberOfStatements; i++) {
+ ImportReference importReference = referenceContext.imports[i];
+ // create the file name segments here:
+ // char[][] compoundName = importReference.tokens;
+ //
+ // // skip duplicates or imports of the current package
+ // for (int j = 0; j < index; j++)
+ // if (resolvedImports[j].onDemand == importReference.onDemand)
+ // if (CharOperation.equals(compoundName,
+ // resolvedImports[j].compoundName)) {
+ // problemReporter().unusedImport(importReference); // since
+ // skipped, must be reported now
+ // continue nextImport;
+ // }
+ // if (importReference.onDemand == true)
+ // if (CharOperation.equals(compoundName, currentPackageName)) {
+ // problemReporter().unusedImport(importReference); // since
+ // skipped, must be reported now
+ // continue nextImport;
+ // }
+ // if (importReference.onDemand) {
+ // Binding importBinding = findOnDemandImport(compoundName);
+ // if (!importBinding.isValidBinding()) {
+ // problemReporter().importProblem(importReference, importBinding);
+ // continue nextImport;
+ // }
+ // resolvedImports[index++] = new ImportBinding(compoundName, true,
+ // importBinding, importReference);
+ // } else {
+ IFile file = importReference.getFile();
+ SourceTypeBinding typeBinding;
+ char[][] compoundName;
+ if (file != null) {
+ typeBinding = new SourceTypeBinding();
+ // findSingleTypeImport(compoundName);
+ IPath path = file.getProjectRelativePath();
+ String[] segs = path.segments();
+ compoundName = new char[segs.length][];
+ for (int j = 0; j < segs.length; j++) {
+ compoundName[j] = segs[j].toCharArray();
+ }
+ typeBinding.compoundName = compoundName; // compoundName;
+ // this.fPackage = fPackage;
+ typeBinding.fileName = file.getLocation().toString()
+ .toCharArray();
+ // typeBinding.modifiers = scope.referenceContext.modifiers;
+ // typeBinding.sourceName = scope.referenceContext.name;
+ typeBinding.sourceName = path.lastSegment().toCharArray();
+ // this.scope = scope;
+ } else {
+ // if (!typeBinding.isValidBinding()) {
+ // problemReporter().importProblem(importReference,
+ // typeBinding);
+ continue nextImport;
+ // }
+ }
+ // if (typeBinding instanceof PackageBinding) {
+ // problemReporter().cannotImportPackage(importReference);
+ // continue nextImport;
+ // }
+ // if (typeBinding instanceof ReferenceBinding) {
+ // ReferenceBinding referenceBinding = (ReferenceBinding)
+ // typeBinding;
+ // if (importReference.isTypeUseDeprecated(referenceBinding, this))
+ // {
+ // problemReporter().deprecatedType((TypeBinding) typeBinding,
+ // importReference);
+ // }
+ // }
+ // ReferenceBinding existingType =
+ // typesBySimpleNames.get(compoundName[compoundName.length - 1]);
+ // if (existingType != null) {
+ // // duplicate test above should have caught this case, but make
+ // sure
+ // if (existingType == typeBinding) {
+ // continue nextImport;
+ // }
+ // // either the type collides with a top level type or another
+ // imported type
+ // for (int j = 0, length = topLevelTypes.length; j < length; j++) {
+ // if (CharOperation.equals(topLevelTypes[j].sourceName,
+ // existingType.sourceName)) {
+ // problemReporter().conflictingImport(importReference);
+ // continue nextImport;
+ // }
+ // }
+ // problemReporter().duplicateImport(importReference);
+ // continue nextImport;
+ // }
+ resolvedImports[index++] = new ImportBinding(compoundName, false,
+ typeBinding, importReference);
+ imports = resolvedImports;
+ // typesBySimpleNames.put(compoundName[compoundName.length - 1],
+ // (ReferenceBinding) typeBinding);
+ // }
+ }
+ //
+ // // shrink resolvedImports... only happens if an error was reported
+ if (resolvedImports.length > index)
+ System.arraycopy(resolvedImports, 0,
+ resolvedImports = new ImportBinding[index], 0, index);
+ imports = resolvedImports;
+
+ int length = imports.length;
+ resolvedSingeTypeImports = new HashtableOfObject(length);
+ for (int i = 0; i < length; i++) {
+ ImportBinding binding = imports[i];
+ if (!binding.onDemand)
+ resolvedSingeTypeImports.put(
+ binding.compoundName[binding.compoundName.length - 1],
+ binding);
+ }
+ }
+
+ public void faultInTypes() {
+ faultInImports();
+ if (topLevelTypes == null) {
+ topLevelTypes = new SourceTypeBinding[0];
+ }
+ for (int i = 0, length = topLevelTypes.length; i < length; i++)
+ topLevelTypes[i].faultInTypesForFieldsAndMethods();
+ }
+
+ private Binding findOnDemandImport(char[][] compoundName) {
+ recordQualifiedReference(compoundName);
+
+ Binding binding = environment.getTopLevelPackage(compoundName[0]);
+ int i = 1;
+ int length = compoundName.length;
+ foundNothingOrType: if (binding != null) {
+ PackageBinding packageBinding = (PackageBinding) binding;
+ while (i < length) {
+ binding = packageBinding.getTypeOrPackage(compoundName[i++]);
+ if (binding == null || !binding.isValidBinding()) {
+ binding = null;
+ break foundNothingOrType;
+ }
+ if (!(binding instanceof PackageBinding))
+ break foundNothingOrType;
+
+ packageBinding = (PackageBinding) binding;
+ }
+ return packageBinding;
+ }
+
+ ReferenceBinding type;
+ if (binding == null) {
+ // if (environment.defaultPackage == null
+ // || environment.options.complianceLevel >=
+ // CompilerOptions.JDK1_4){
+ // return new ProblemReferenceBinding(
+ // CharOperation.subarray(compoundName, 0, i),
+ // NotFound);
+ // }
+ type = findType(compoundName[0], environment.defaultPackage,
+ environment.defaultPackage);
+ if (type == null || !type.isValidBinding())
+ return new ProblemReferenceBinding(CharOperation.subarray(
+ compoundName, 0, i), NotFound);
+ i = 1; // reset to look for member types inside the default package
+ // type
+ } else {
+ type = (ReferenceBinding) binding;
+ }
+
+ for (; i < length; i++) {
+ if (!type.canBeSeenBy(fPackage)) {
+ return new ProblemReferenceBinding(CharOperation.subarray(
+ compoundName, 0, i), type, NotVisible);
+ }
+ // does not look for inherited member types on purpose
+ if ((type = type.getMemberType(compoundName[i])) == null) {
+ return new ProblemReferenceBinding(CharOperation.subarray(
+ compoundName, 0, i + 1), NotFound);
+ }
+ }
+ if (!type.canBeSeenBy(fPackage))
+ return new ProblemReferenceBinding(compoundName, type, NotVisible);
+ return type;
+ }
+
+ private Binding findSingleTypeImport(char[][] compoundName) {
+ // if (compoundName.length == 1) {
+ // findType records the reference
+ // the name cannot be a package
+ // if (environment.defaultPackage == null
+ // || environment.options.complianceLevel >= CompilerOptions.JDK1_4)
+ // return new ProblemReferenceBinding(compoundName, NotFound);
+ ReferenceBinding typeBinding = findType(compoundName[0],
+ environment.defaultPackage, fPackage);
+ if (typeBinding == null)
+ return new ProblemReferenceBinding(compoundName, NotFound);
+ else
+ return typeBinding;
+ // }
+ // return findOnDemandImport(compoundName);
+ }
+
+ /*
+ * Answer the problem reporter to use for raising new problems.
+ *
+ * Note that as a side-effect, this updates the current reference context
+ * (unit, type or method) in case the problem handler decides it is
+ * necessary to abort.
+ */
+
+ public ProblemReporter problemReporter() {
+ ProblemReporter problemReporter = referenceContext.problemReporter;
+ problemReporter.referenceContext = referenceContext;
+ return problemReporter;
+ }
+
+ /*
+ * What do we hold onto:
+ *
+ * 1. when we resolve 'a.b.c', say we keep only 'a.b.c' & when we fail to
+ * resolve 'c' in 'a.b', lets keep 'a.b.c' THEN when we come across a
+ * new/changed/removed item named 'a.b.c', we would find all references to
+ * 'a.b.c' -> This approach fails because every type is resolved in every
+ * onDemand import to detect collision cases... so the references could be
+ * 10 times bigger than necessary.
+ *
+ * 2. when we resolve 'a.b.c', lets keep 'a.b' & 'c' & when we fail to
+ * resolve 'c' in 'a.b', lets keep 'a.b' & 'c' THEN when we come across a
+ * new/changed/removed item named 'a.b.c', we would find all references to
+ * 'a.b' & 'c' -> This approach does not have a space problem but fails to
+ * handle collision cases. What happens if a type is added named 'a.b'? We
+ * would search for 'a' & 'b' but would not find a match.
+ *
+ * 3. when we resolve 'a.b.c', lets keep 'a', 'a.b' & 'a', 'b', 'c' & when
+ * we fail to resolve 'c' in 'a.b', lets keep 'a', 'a.b' & 'a', 'b', 'c'
+ * THEN when we come across a new/changed/removed item named 'a.b.c', we
+ * would find all references to 'a.b' & 'c' OR 'a.b' -> 'a' & 'b' OR 'a' -> '' &
+ * 'a' -> As long as each single char[] is interned, we should not have a
+ * space problem and can handle collision cases.
+ *
+ * 4. when we resolve 'a.b.c', lets keep 'a.b' & 'a', 'b', 'c' & when we
+ * fail to resolve 'c' in 'a.b', lets keep 'a.b' & 'a', 'b', 'c' THEN when
+ * we come across a new/changed/removed item named 'a.b.c', we would find
+ * all references to 'a.b' & 'c' OR 'a.b' -> 'a' & 'b' in the simple name
+ * collection OR 'a' -> 'a' in the simple name collection -> As long as each
+ * single char[] is interned, we should not have a space problem and can
+ * handle collision cases.
+ */
+ void recordQualifiedReference(char[][] qualifiedName) {
+ if (qualifiedReferences == null)
+ return; // not recording dependencies
+
+ int length = qualifiedName.length;
+ if (length > 1) {
+ while (!qualifiedReferences.contains(qualifiedName)) {
+ qualifiedReferences.add(qualifiedName);
+ if (length == 2) {
+ recordSimpleReference(qualifiedName[0]);
+ recordSimpleReference(qualifiedName[1]);
+ return;
+ }
+ length--;
+ recordSimpleReference(qualifiedName[length]);
+ System.arraycopy(qualifiedName, 0,
+ qualifiedName = new char[length][], 0, length);
+ }
+ } else if (length == 1) {
+ recordSimpleReference(qualifiedName[0]);
+ }
+ }
+
+ void recordReference(char[][] qualifiedEnclosingName, char[] simpleName) {
+ recordQualifiedReference(qualifiedEnclosingName);
+ recordSimpleReference(simpleName);
+ }
+
+ void recordSimpleReference(char[] simpleName) {
+ if (simpleNameReferences == null)
+ return; // not recording dependencies
+
+ if (!simpleNameReferences.contains(simpleName))
+ simpleNameReferences.add(simpleName);
+ }
+
+ void recordTypeReference(TypeBinding type) {
+ if (referencedTypes == null)
+ return; // not recording dependencies
+
+ if (type.isArrayType())
+ type = ((ArrayBinding) type).leafComponentType;
+ if (!type.isBaseType() && !referencedTypes.containsIdentical(type))
+ referencedTypes.add(type);
+ }
+
+ void recordTypeReferences(TypeBinding[] types) {
+ if (qualifiedReferences == null)
+ return; // not recording dependencies
+ if (types == null || types.length == 0)
+ return;
+
+ for (int i = 0, max = types.length; i < max; i++) {
+ // No need to record supertypes of method arguments & thrown
+ // exceptions, just the compoundName
+ // If a field/method is retrieved from such a type then a separate
+ // call does the job
+ TypeBinding type = types[i];
+ if (type.isArrayType())
+ type = ((ArrayBinding) type).leafComponentType;
+ if (!type.isBaseType()) {
+ ReferenceBinding actualType = (ReferenceBinding) type;
+ if (!actualType.isLocalType())
+ recordQualifiedReference(actualType.isMemberType() ? CharOperation
+ .splitOn('.', actualType.readableName())
+ : actualType.compoundName);
+ }
+ }
+ }
+
+ Binding resolveSingleTypeImport(ImportBinding importBinding) {
+ if (importBinding.resolvedImport == null) {
+ importBinding.resolvedImport = findSingleTypeImport(importBinding.compoundName);
+ if (!importBinding.resolvedImport.isValidBinding()
+ || importBinding.resolvedImport instanceof PackageBinding) {
+ if (this.imports != null) {
+ ImportBinding[] newImports = new ImportBinding[imports.length - 1];
+ for (int i = 0, n = 0, max = this.imports.length; i < max; i++)
+ if (this.imports[i] != importBinding) {
+ newImports[n++] = this.imports[i];
+ }
+ this.imports = newImports;
+ }
+ return null;
+ }
+ }
+ return importBinding.resolvedImport;
+ }
+
+ public void storeDependencyInfo() {
+ // add the type hierarchy of each referenced type
+ // cannot do early since the hierarchy may not be fully resolved
+ for (int i = 0; i < referencedTypes.size; i++) { // grows as more
+ // types are added
+ ReferenceBinding type = (ReferenceBinding) referencedTypes
+ .elementAt(i);
+ if (!type.isLocalType()) {
+ recordQualifiedReference(type.isMemberType() ? CharOperation
+ .splitOn('.', type.readableName()) : type.compoundName);
+ ReferenceBinding enclosing = type.enclosingType();
+ if (enclosing != null
+ && !referencedTypes.containsIdentical(enclosing))
+ referencedTypes.add(enclosing); // to record its supertypes
+ }
+ ReferenceBinding superclass = type.superclass();
+ if (superclass != null
+ && !referencedTypes.containsIdentical(superclass))
+ referencedTypes.add(superclass); // to record its supertypes
+ ReferenceBinding[] interfaces = type.superInterfaces();
+ if (interfaces != null && interfaces.length > 0)
+ for (int j = 0, length = interfaces.length; j < length; j++)
+ if (!referencedTypes.containsIdentical(interfaces[j]))
+ referencedTypes.add(interfaces[j]); // to record its
+ // supertypes
+ }
+
+ int size = qualifiedReferences.size;
+ char[][][] qualifiedRefs = new char[size][][];
+ for (int i = 0; i < size; i++)
+ qualifiedRefs[i] = qualifiedReferences.elementAt(i);
+ referenceContext.compilationResult.qualifiedReferences = qualifiedRefs;
+
+ size = simpleNameReferences.size;
+ char[][] simpleRefs = new char[size][];
+ for (int i = 0; i < size; i++)
+ simpleRefs[i] = simpleNameReferences.elementAt(i);
+ referenceContext.compilationResult.simpleNameReferences = simpleRefs;
+ }
+
+ public String toString() {
+ return "--- CompilationUnit Scope : " + new String(referenceContext.getFileName()); //$NON-NLS-1$
+ }
+
+ public void verifyMethods(MethodVerifier verifier) {
+ for (int i = 0, length = topLevelTypes.length; i < length; i++)
+ topLevelTypes[i].verifyMethods(verifier);
+ }
+}
--- /dev/null
+/***********************************************************************************************************************************
+ * Copyright (c) 2002 www.phpeclipse.de All rights reserved. This program and the accompanying material 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: www.phpeclipse.de
+ **********************************************************************************************************************************/
+package net.sourceforge.phpdt.internal.compiler.parser;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+
+import net.sourceforge.phpdt.core.compiler.CharOperation;
+import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
+import net.sourceforge.phpdt.core.compiler.InvalidInputException;
+import net.sourceforge.phpdt.internal.compiler.ast.AND_AND_Expression;
+import net.sourceforge.phpdt.internal.compiler.ast.ASTNode;
+import net.sourceforge.phpdt.internal.compiler.ast.AbstractMethodDeclaration;
+import net.sourceforge.phpdt.internal.compiler.ast.BinaryExpression;
+import net.sourceforge.phpdt.internal.compiler.ast.Block;
+import net.sourceforge.phpdt.internal.compiler.ast.BreakStatement;
+import net.sourceforge.phpdt.internal.compiler.ast.CompilationUnitDeclaration;
+import net.sourceforge.phpdt.internal.compiler.ast.ConditionalExpression;
+import net.sourceforge.phpdt.internal.compiler.ast.ContinueStatement;
+import net.sourceforge.phpdt.internal.compiler.ast.EqualExpression;
+import net.sourceforge.phpdt.internal.compiler.ast.Expression;
+import net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration;
+import net.sourceforge.phpdt.internal.compiler.ast.FieldReference;
+import net.sourceforge.phpdt.internal.compiler.ast.IfStatement;
+import net.sourceforge.phpdt.internal.compiler.ast.ImportReference;
+import net.sourceforge.phpdt.internal.compiler.ast.InstanceOfExpression;
+import net.sourceforge.phpdt.internal.compiler.ast.MethodDeclaration;
+import net.sourceforge.phpdt.internal.compiler.ast.OR_OR_Expression;
+import net.sourceforge.phpdt.internal.compiler.ast.OperatorIds;
+import net.sourceforge.phpdt.internal.compiler.ast.ReturnStatement;
+import net.sourceforge.phpdt.internal.compiler.ast.SingleTypeReference;
+import net.sourceforge.phpdt.internal.compiler.ast.Statement;
+import net.sourceforge.phpdt.internal.compiler.ast.StringLiteral;
+import net.sourceforge.phpdt.internal.compiler.ast.StringLiteralDQ;
+import net.sourceforge.phpdt.internal.compiler.ast.StringLiteralSQ;
+import net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration;
+import net.sourceforge.phpdt.internal.compiler.ast.TypeReference;
+import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions;
+import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext;
+import net.sourceforge.phpdt.internal.compiler.lookup.CompilerModifiers;
+import net.sourceforge.phpdt.internal.compiler.lookup.TypeConstants;
+import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
+import net.sourceforge.phpdt.internal.compiler.problem.ProblemSeverities;
+import net.sourceforge.phpdt.internal.compiler.util.Util;
+import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil;
+import net.sourceforge.phpeclipse.builder.IdentifierIndexManager;
+import net.sourceforge.phpeclipse.ui.overlaypages.ProjectPrefUtil;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+
+public class Parser implements ITerminalSymbols, CompilerModifiers,
+ ParserBasicInformation {
+ protected final static int StackIncrement = 255;
+
+ protected int stateStackTop;
+
+ // protected int[] stack = new int[StackIncrement];
+
+ public int firstToken; // handle for multiple parsing goals
+
+ public int lastAct; // handle for multiple parsing goals
+
+ // protected RecoveredElement currentElement;
+
+ public static boolean VERBOSE_RECOVERY = false;
+
+ protected boolean diet = false; // tells the scanner to jump over some
+
+ /**
+ * the PHP token scanner
+ */
+ public Scanner scanner;
+
+ int token;
+
+ protected int modifiers;
+
+ protected int modifiersSourceStart;
+
+ protected Parser(ProblemReporter problemReporter) {
+ this.problemReporter = problemReporter;
+ this.options = problemReporter.options;
+ this.token = TokenNameEOF;
+ this.initializeScanner();
+ }
+
+ public void setFileToParse(IFile fileToParse) {
+ this.token = TokenNameEOF;
+ this.initializeScanner();
+ }
+
+ /**
+ * ClassDeclaration Constructor.
+ *
+ * @param s
+ * @param sess
+ * Description of Parameter
+ * @see
+ */
+ public Parser(IFile fileToParse) {
+ // if (keywordMap == null) {
+ // keywordMap = new HashMap();
+ // for (int i = 0; i < PHP_KEYWORS.length; i++) {
+ // keywordMap.put(PHP_KEYWORS[i], new Integer(PHP_KEYWORD_TOKEN[i]));
+ // }
+ // }
+ // this.currentPHPString = 0;
+ // PHPParserSuperclass.fileToParse = fileToParse;
+ // this.phpList = null;
+ this.includesList = null;
+ // this.str = "";
+ this.token = TokenNameEOF;
+ // this.chIndx = 0;
+ // this.rowCount = 1;
+ // this.columnCount = 0;
+ // this.phpEnd = false;
+ // getNextToken();
+ this.initializeScanner();
+ }
+
+ public void initializeScanner() {
+ this.scanner = new Scanner(
+ false /* comment */,
+ false /* whitespace */,
+ this.options.getSeverity(CompilerOptions.NonExternalizedString) != ProblemSeverities.Ignore /* nls */,
+ false, false, this.options.taskTags/* taskTags */,
+ this.options.taskPriorites/* taskPriorities */, true/* isTaskCaseSensitive */);
+ }
+
+ /**
+ * Create marker for the parse error
+ */
+ // private void setMarker(String message, int charStart, int charEnd, int
+ // errorLevel) {
+ // setMarker(fileToParse, message, charStart, charEnd, errorLevel);
+ // }
+ /**
+ * This method will throw the SyntaxError. It will add the good lines and
+ * columns to the Error
+ *
+ * @param error
+ * the error message
+ * @throws SyntaxError
+ * the error raised
+ */
+ private void throwSyntaxError(String error) {
+ int problemStartPosition = scanner.getCurrentTokenStartPosition();
+ int problemEndPosition = scanner.getCurrentTokenEndPosition() + 1;
+ if (scanner.source.length <= problemEndPosition
+ && problemEndPosition > 0) {
+ problemEndPosition = scanner.source.length - 1;
+ if (problemStartPosition > 0
+ && problemStartPosition >= problemEndPosition
+ && problemEndPosition > 0) {
+ problemStartPosition = problemEndPosition - 1;
+ }
+ }
+ throwSyntaxError(error, problemStartPosition, problemEndPosition);
+ }
+
+ /**
+ * This method will throw the SyntaxError. It will add the good lines and
+ * columns to the Error
+ *
+ * @param error
+ * the error message
+ * @throws SyntaxError
+ * the error raised
+ */
+ // private void throwSyntaxError(String error, int startRow) {
+ // throw new SyntaxError(startRow, 0, " ", error);
+ // }
+ private void throwSyntaxError(String error, int problemStartPosition,
+ int problemEndPosition) {
+ if (referenceContext != null) {
+ problemReporter.phpParsingError(new String[] { error },
+ problemStartPosition, problemEndPosition, referenceContext,
+ compilationUnit.compilationResult);
+ }
+ throw new SyntaxError(1, 0, " ", error);
+ }
+
+ private void reportSyntaxError(String error) {
+ int problemStartPosition = scanner.getCurrentTokenStartPosition();
+ int problemEndPosition = scanner.getCurrentTokenEndPosition();
+ reportSyntaxError(error, problemStartPosition, problemEndPosition + 1);
+ }
+
+ private void reportSyntaxError(String error, int problemStartPosition,
+ int problemEndPosition) {
+ if (referenceContext != null) {
+ problemReporter.phpParsingError(new String[] { error },
+ problemStartPosition, problemEndPosition, referenceContext,
+ compilationUnit.compilationResult);
+ }
+ }
+
+ // private void reportSyntaxWarning(String error, int problemStartPosition,
+ // int problemEndPosition) {
+ // if (referenceContext != null) {
+ // problemReporter.phpParsingWarning(new String[] { error },
+ // problemStartPosition, problemEndPosition, referenceContext,
+ // compilationUnit.compilationResult);
+ // }
+ // }
+
+ /**
+ * gets the next token from input
+ */
+ private void getNextToken() {
+ try {
+ token = scanner.getNextToken();
+ if (Scanner.DEBUG) {
+ int currentEndPosition = scanner.getCurrentTokenEndPosition();
+ int currentStartPosition = scanner
+ .getCurrentTokenStartPosition();
+ System.out.print(currentStartPosition + ","
+ + currentEndPosition + ": ");
+ System.out.println(scanner.toStringAction(token));
+ }
+ } catch (InvalidInputException e) {
+ token = TokenNameERROR;
+ String detailedMessage = e.getMessage();
+
+ if (detailedMessage == Scanner.UNTERMINATED_STRING) {
+ throwSyntaxError("Unterminated string.");
+ } else if (detailedMessage == Scanner.UNTERMINATED_COMMENT) {
+ throwSyntaxError("Unterminated commment.");
+ }
+ }
+ return;
+ }
+
+ public void init(String s) {
+ // this.str = s;
+ this.token = TokenNameEOF;
+ this.includesList = new ArrayList();
+ // this.chIndx = 0;
+ // this.rowCount = 1;
+ // this.columnCount = 0;
+ // this.phpEnd = false;
+ // this.phpMode = false;
+ /* scanner initialization */
+ scanner.setSource(s.toCharArray());
+ scanner.setPHPMode(false);
+ astPtr = 0;
+ }
+
+ protected void initialize(boolean phpMode) {
+ initialize(phpMode, null);
+ }
+
+ protected void initialize(boolean phpMode,
+ IdentifierIndexManager indexManager) {
+ compilationUnit = null;
+ referenceContext = null;
+ this.includesList = new ArrayList();
+ // this.indexManager = indexManager;
+ // this.str = "";
+ this.token = TokenNameEOF;
+ // this.chIndx = 0;
+ // this.rowCount = 1;
+ // this.columnCount = 0;
+ // this.phpEnd = false;
+ // this.phpMode = phpMode;
+ scanner.setPHPMode(phpMode);
+ astPtr = 0;
+ }
+
+ /**
+ * Parses a string with php tags i.e. '<body> <?php phpinfo() ?>
+ * </body>'
+ */
+ public void parse(String s) {
+ parse(s, null);
+ }
+
+ /**
+ * Parses a string with php tags i.e. '<body> <?php phpinfo() ?>
+ * </body>'
+ */
+ public void parse(String s, HashMap variables) {
+ fMethodVariables = variables;
+ fStackUnassigned = new ArrayList();
+ init(s);
+ parse();
+ }
+
+ /**
+ * Parses a string with php tags i.e. '<body> <?php phpinfo() ?>
+ * </body>'
+ */
+ protected void parse() {
+ if (scanner.compilationUnit != null) {
+ IResource resource = scanner.compilationUnit.getResource();
+ if (resource != null && resource instanceof IFile) {
+ // set the package name
+ consumePackageDeclarationName((IFile) resource);
+ }
+ }
+ getNextToken();
+ do {
+ try {
+ if (token != TokenNameEOF && token != TokenNameERROR) {
+ statementList();
+ }
+ if (token != TokenNameEOF) {
+ if (token == TokenNameERROR) {
+ throwSyntaxError("Scanner error (Found unknown token: "
+ + scanner.toStringAction(token) + ")");
+ }
+ if (token == TokenNameRPAREN) {
+ throwSyntaxError("Too many closing ')'; end-of-file not reached.");
+ }
+ if (token == TokenNameRBRACE) {
+ throwSyntaxError("Too many closing '}'; end-of-file not reached.");
+ }
+ if (token == TokenNameRBRACKET) {
+ throwSyntaxError("Too many closing ']'; end-of-file not reached.");
+ }
+ if (token == TokenNameLPAREN) {
+ throwSyntaxError("Read character '('; end-of-file not reached.");
+ }
+ if (token == TokenNameLBRACE) {
+ throwSyntaxError("Read character '{'; end-of-file not reached.");
+ }
+ if (token == TokenNameLBRACKET) {
+ throwSyntaxError("Read character '['; end-of-file not reached.");
+ }
+ throwSyntaxError("End-of-file not reached.");
+ }
+ break;
+ } catch (SyntaxError syntaxError) {
+ // syntaxError.printStackTrace();
+ break;
+ }
+ } while (true);
+
+ endParse(0);
+ }
+
+ /**
+ * Parses a string with php tags i.e. '<body> <?php phpinfo() ?>
+ * </body>'
+ */
+ public void parseFunction(String s, HashMap variables) {
+ init(s);
+ scanner.phpMode = true;
+ parseFunction(variables);
+ }
+
+ /**
+ * Parses a string with php tags i.e. '<body> <?php phpinfo() ?>
+ * </body>'
+ */
+ protected void parseFunction(HashMap variables) {
+ getNextToken();
+ boolean hasModifiers = member_modifiers();
+ if (token == TokenNamefunction) {
+ if (!hasModifiers) {
+ checkAndSetModifiers(AccPublic);
+ }
+ this.fMethodVariables = variables;
+
+ MethodDeclaration methodDecl = new MethodDeclaration(null);
+ methodDecl.declarationSourceStart = scanner
+ .getCurrentTokenStartPosition();
+ methodDecl.modifiers = this.modifiers;
+ methodDecl.type = MethodDeclaration.METHOD_DEFINITION;
+ try {
+ getNextToken();
+ functionDefinition(methodDecl);
+ } catch (SyntaxError sytaxErr1) {
+ return;
+ } finally {
+ int sourceEnd = methodDecl.sourceEnd;
+ if (sourceEnd <= 0
+ || methodDecl.declarationSourceStart > sourceEnd) {
+ sourceEnd = methodDecl.declarationSourceStart + 1;
+ }
+ methodDecl.sourceEnd = sourceEnd;
+ methodDecl.declarationSourceEnd = sourceEnd;
+ }
+ }
+ }
+
+ protected CompilationUnitDeclaration endParse(int act) {
+
+ this.lastAct = act;
+
+ // if (currentElement != null) {
+ // currentElement.topElement().updateParseTree();
+ // if (VERBOSE_RECOVERY) {
+ // System.out.print(Util.bind("parser.syntaxRecovery")); //$NON-NLS-1$
+ // System.out.println("--------------------------"); //$NON-NLS-1$
+ // System.out.println(compilationUnit);
+ // System.out.println("----------------------------------");
+ // //$NON-NLS-1$
+ // }
+ // } else {
+ if (diet & VERBOSE_RECOVERY) {
+ System.out.print(Util.bind("parser.regularParse")); //$NON-NLS-1$
+ System.out.println("--------------------------"); //$NON-NLS-1$
+ System.out.println(compilationUnit);
+ System.out.println("----------------------------------"); //$NON-NLS-1$
+ }
+ // }
+ if (scanner.recordLineSeparator) {
+ compilationUnit.compilationResult.lineSeparatorPositions = scanner
+ .getLineEnds();
+ }
+ if (scanner.taskTags != null) {
+ for (int i = 0; i < scanner.foundTaskCount; i++) {
+ problemReporter().task(
+ new String(scanner.foundTaskTags[i]),
+ new String(scanner.foundTaskMessages[i]),
+ scanner.foundTaskPriorities[i] == null ? null
+ : new String(scanner.foundTaskPriorities[i]),
+ scanner.foundTaskPositions[i][0],
+ scanner.foundTaskPositions[i][1]);
+ }
+ }
+ compilationUnit.imports = new ImportReference[includesList.size()];
+ for (int i = 0; i < includesList.size(); i++) {
+ compilationUnit.imports[i] = (ImportReference) includesList.get(i);
+ }
+ return compilationUnit;
+ }
+
+ private Block statementList() {
+ boolean branchStatement = false;
+ Statement statement;
+ int blockStart = scanner.getCurrentTokenStartPosition();
+ ArrayList blockStatements = new ArrayList();
+ do {
+ try {
+ statement = statement();
+ blockStatements.add(statement);
+ if (token == TokenNameEOF) {
+ return null;
+ }
+ if (branchStatement && statement != null) {
+ // reportSyntaxError("Unreachable code",
+ // statement.sourceStart,
+ // statement.sourceEnd);
+ if (!(statement instanceof BreakStatement)) {
+ /*
+ * don't give an error for break statement following
+ * return statement Technically it's unreachable code,
+ * but in switch-case it's recommended to avoid
+ * accidental fall-through later when editing the code
+ */
+ problemReporter.unreachableCode(new String(scanner
+ .getCurrentIdentifierSource()),
+ statement.sourceStart, statement.sourceEnd,
+ referenceContext,
+ compilationUnit.compilationResult);
+ }
+ }
+ if ((token == TokenNameRBRACE) || (token == TokenNamecase)
+ || (token == TokenNamedefault)
+ || (token == TokenNameelse)
+ || (token == TokenNameelseif)
+ || (token == TokenNameendif)
+ || (token == TokenNameendfor)
+ || (token == TokenNameendforeach)
+ || (token == TokenNameendwhile)
+ || (token == TokenNameendswitch)
+ || (token == TokenNameenddeclare)
+ || (token == TokenNameEOF) || (token == TokenNameERROR)) {
+ return createBlock(blockStart, blockStatements);
+ }
+ branchStatement = checkUnreachableStatements(statement);
+ } catch (SyntaxError sytaxErr1) {
+ // if an error occured,
+ // try to find keywords
+ // to parse the rest of the string
+ boolean tokenize = scanner.tokenizeStrings;
+ if (!tokenize) {
+ scanner.tokenizeStrings = true;
+ }
+ try {
+ while (token != TokenNameEOF) {
+ if ((token == TokenNameRBRACE)
+ || (token == TokenNamecase)
+ || (token == TokenNamedefault)
+ || (token == TokenNameelse)
+ || (token == TokenNameelseif)
+ || (token == TokenNameendif)
+ || (token == TokenNameendfor)
+ || (token == TokenNameendforeach)
+ || (token == TokenNameendwhile)
+ || (token == TokenNameendswitch)
+ || (token == TokenNameenddeclare)
+ || (token == TokenNameEOF)
+ || (token == TokenNameERROR)) {
+ return createBlock(blockStart, blockStatements);
+ }
+ if (token == TokenNameif || token == TokenNameswitch
+ || token == TokenNamefor
+ || token == TokenNamewhile
+ || token == TokenNamedo
+ || token == TokenNameforeach
+ || token == TokenNamecontinue
+ || token == TokenNamebreak
+ || token == TokenNamereturn
+ || token == TokenNameexit
+ || token == TokenNameecho
+ || token == TokenNameECHO_INVISIBLE
+ || token == TokenNameglobal
+ || token == TokenNamestatic
+ || token == TokenNameunset
+ || token == TokenNamefunction
+ || token == TokenNamedeclare
+ || token == TokenNametry
+ || token == TokenNamecatch
+ || token == TokenNamethrow
+ || token == TokenNamefinal
+ || token == TokenNameabstract
+ || token == TokenNameclass
+ || token == TokenNameinterface) {
+ break;
+ }
+ // System.out.println(scanner.toStringAction(token));
+ getNextToken();
+ // System.out.println(scanner.toStringAction(token));
+ }
+ if (token == TokenNameEOF) {
+ throw sytaxErr1;
+ }
+ } finally {
+ scanner.tokenizeStrings = tokenize;
+ }
+ }
+ } while (true);
+ }
+
+ /**
+ * @param statement
+ * @return
+ */
+ private boolean checkUnreachableStatements(Statement statement) {
+ if (statement instanceof ReturnStatement
+ || statement instanceof ContinueStatement
+ || statement instanceof BreakStatement) {
+ return true;
+ } else if (statement instanceof IfStatement
+ && ((IfStatement) statement).checkUnreachable) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * @param blockStart
+ * @param blockStatements
+ * @return
+ */
+ private Block createBlock(int blockStart, ArrayList blockStatements) {
+ int blockEnd = scanner.getCurrentTokenEndPosition();
+ Block b = Block.EmptyWith(blockStart, blockEnd);
+ b.statements = new Statement[blockStatements.size()];
+ blockStatements.toArray(b.statements);
+ return b;
+ }
+
+ private void functionBody(MethodDeclaration methodDecl) {
+ // '{' [statement-list] '}'
+ if (token == TokenNameLBRACE) {
+ getNextToken();
+ } else {
+ methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1;
+ throwSyntaxError("'{' expected in compound-statement.");
+ }
+ if (token != TokenNameRBRACE) {
+ statementList();
+ }
+ if (token == TokenNameRBRACE) {
+ methodDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
+ getNextToken();
+ } else {
+ methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1;
+ throwSyntaxError("'}' expected in compound-statement.");
+ }
+ }
+
+ private Statement statement() {
+ Statement statement = null;
+ Expression expression;
+ int sourceStart = scanner.getCurrentTokenStartPosition();
+ int sourceEnd;
+ if (token == TokenNameif) {
+ // T_IF '(' expr ')' statement elseif_list else_single
+ // T_IF '(' expr ')' ':' inner_statement_list new_elseif_list
+ // new_else_single T_ENDIF ';'
+ getNextToken();
+ if (token == TokenNameLPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'(' expected after 'if' keyword.");
+ }
+ expression = expr();
+ if (token == TokenNameRPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("')' expected after 'if' condition.");
+ }
+ // create basic IfStatement
+ IfStatement ifStatement = new IfStatement(expression, null, null,
+ sourceStart, -1);
+ if (token == TokenNameCOLON) {
+ getNextToken();
+ ifStatementColon(ifStatement);
+ } else {
+ ifStatement(ifStatement);
+ }
+ return ifStatement;
+ } else if (token == TokenNameswitch) {
+ getNextToken();
+ if (token == TokenNameLPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'(' expected after 'switch' keyword.");
+ }
+ expr();
+ if (token == TokenNameRPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("')' expected after 'switch' condition.");
+ }
+ switchStatement();
+ return statement;
+ } else if (token == TokenNamefor) {
+ getNextToken();
+ if (token == TokenNameLPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'(' expected after 'for' keyword.");
+ }
+ if (token == TokenNameSEMICOLON) {
+ getNextToken();
+ } else {
+ expressionList();
+ if (token == TokenNameSEMICOLON) {
+ getNextToken();
+ } else {
+ throwSyntaxError("';' expected after 'for'.");
+ }
+ }
+ if (token == TokenNameSEMICOLON) {
+ getNextToken();
+ } else {
+ expressionList();
+ if (token == TokenNameSEMICOLON) {
+ getNextToken();
+ } else {
+ throwSyntaxError("';' expected after 'for'.");
+ }
+ }
+ if (token == TokenNameRPAREN) {
+ getNextToken();
+ } else {
+ expressionList();
+ if (token == TokenNameRPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("')' expected after 'for'.");
+ }
+ }
+ forStatement();
+ return statement;
+ } else if (token == TokenNamewhile) {
+ getNextToken();
+ if (token == TokenNameLPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'(' expected after 'while' keyword.");
+ }
+ expr();
+ if (token == TokenNameRPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("')' expected after 'while' condition.");
+ }
+ whileStatement();
+ return statement;
+ } else if (token == TokenNamedo) {
+ getNextToken();
+ if (token == TokenNameLBRACE) {
+ getNextToken();
+ if (token != TokenNameRBRACE) {
+ statementList();
+ }
+ if (token == TokenNameRBRACE) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'}' expected after 'do' keyword.");
+ }
+ } else {
+ statement();
+ }
+ if (token == TokenNamewhile) {
+ getNextToken();
+ if (token == TokenNameLPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'(' expected after 'while' keyword.");
+ }
+ expr();
+ if (token == TokenNameRPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("')' expected after 'while' condition.");
+ }
+ } else {
+ throwSyntaxError("'while' expected after 'do' keyword.");
+ }
+ if (token == TokenNameSEMICOLON) {
+ getNextToken();
+ } else {
+ if (token != TokenNameINLINE_HTML) {
+ throwSyntaxError("';' expected after do-while statement.");
+ }
+ getNextToken();
+ }
+ return statement;
+ } else if (token == TokenNameforeach) {
+ getNextToken();
+ if (token == TokenNameLPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'(' expected after 'foreach' keyword.");
+ }
+ expr();
+ if (token == TokenNameas) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'as' expected after 'foreach' exxpression.");
+ }
+ // variable();
+ foreach_variable();
+ foreach_optional_arg();
+ if (token == TokenNameEQUAL_GREATER) {
+ getNextToken();
+ variable(false, false);
+ }
+ if (token == TokenNameRPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("')' expected after 'foreach' expression.");
+ }
+ foreachStatement();
+ return statement;
+ } else if (token == TokenNamebreak) {
+ expression = null;
+ getNextToken();
+ if (token != TokenNameSEMICOLON) {
+ expression = expr();
+ }
+ if (token == TokenNameSEMICOLON) {
+ sourceEnd = scanner.getCurrentTokenEndPosition();
+ getNextToken();
+ } else {
+ if (token != TokenNameINLINE_HTML) {
+ throwSyntaxError("';' expected after 'break'.");
+ }
+ sourceEnd = scanner.getCurrentTokenEndPosition();
+ getNextToken();
+ }
+ return new BreakStatement(null, sourceStart, sourceEnd);
+ } else if (token == TokenNamecontinue) {
+ expression = null;
+ getNextToken();
+ if (token != TokenNameSEMICOLON) {
+ expression = expr();
+ }
+ if (token == TokenNameSEMICOLON) {
+ sourceEnd = scanner.getCurrentTokenEndPosition();
+ getNextToken();
+ } else {
+ if (token != TokenNameINLINE_HTML) {
+ throwSyntaxError("';' expected after 'continue'.");
+ }
+ sourceEnd = scanner.getCurrentTokenEndPosition();
+ getNextToken();
+ }
+ return new ContinueStatement(null, sourceStart, sourceEnd);
+ } else if (token == TokenNamereturn) {
+ expression = null;
+ getNextToken();
+ if (token != TokenNameSEMICOLON) {
+ expression = expr();
+ }
+ if (token == TokenNameSEMICOLON) {
+ sourceEnd = scanner.getCurrentTokenEndPosition();
+ getNextToken();
+ } else {
+ if (token != TokenNameINLINE_HTML) {
+ throwSyntaxError("';' expected after 'return'.");
+ }
+ sourceEnd = scanner.getCurrentTokenEndPosition();
+ getNextToken();
+ }
+ return new ReturnStatement(expression, sourceStart, sourceEnd);
+ } else if (token == TokenNameecho) {
+ getNextToken();
+ expressionList();
+ if (token == TokenNameSEMICOLON) {
+ getNextToken();
+ } else {
+ if (token != TokenNameINLINE_HTML) {
+ throwSyntaxError("';' expected after 'echo' statement.");
+ }
+ getNextToken();
+ }
+ return statement;
+ } else if (token == TokenNameECHO_INVISIBLE) {
+ // 0-length token directly after PHP short tag <?=
+ getNextToken();
+ expressionList();
+ if (token == TokenNameSEMICOLON) {
+ getNextToken();
+ // if (token != TokenNameINLINE_HTML) {
+ // // TODO should this become a configurable warning?
+ // reportSyntaxError("Probably '?>' expected after PHP short tag
+ // expression (only the first expression will be echoed).");
+ // }
+ } else {
+ if (token != TokenNameINLINE_HTML) {
+ throwSyntaxError("';' expected after PHP short tag '<?=' expression.");
+ }
+ getNextToken();
+ }
+ return statement;
+ } else if (token == TokenNameINLINE_HTML) {
+ getNextToken();
+ return statement;
+ } else if (token == TokenNameglobal) {
+ getNextToken();
+ global_var_list();
+ if (token == TokenNameSEMICOLON) {
+ getNextToken();
+ } else {
+ if (token != TokenNameINLINE_HTML) {
+ throwSyntaxError("';' expected after 'global' statement.");
+ }
+ getNextToken();
+ }
+ return statement;
+ } else if (token == TokenNamestatic) {
+ getNextToken();
+ static_var_list();
+ if (token == TokenNameSEMICOLON) {
+ getNextToken();
+ } else {
+ if (token != TokenNameINLINE_HTML) {
+ throwSyntaxError("';' expected after 'static' statement.");
+ }
+ getNextToken();
+ }
+ return statement;
+ } else if (token == TokenNameunset) {
+ getNextToken();
+ if (token == TokenNameLPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'(' expected after 'unset' statement.");
+ }
+ unset_variables();
+ if (token == TokenNameRPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("')' expected after 'unset' statement.");
+ }
+ if (token == TokenNameSEMICOLON) {
+ getNextToken();
+ } else {
+ if (token != TokenNameINLINE_HTML) {
+ throwSyntaxError("';' expected after 'unset' statement.");
+ }
+ getNextToken();
+ }
+ return statement;
+ } else if (token == TokenNamefunction) {
+ MethodDeclaration methodDecl = new MethodDeclaration(
+ this.compilationUnit.compilationResult);
+ methodDecl.declarationSourceStart = scanner
+ .getCurrentTokenStartPosition();
+ methodDecl.modifiers = AccDefault;
+ methodDecl.type = MethodDeclaration.FUNCTION_DEFINITION;
+ try {
+ getNextToken();
+ functionDefinition(methodDecl);
+ } finally {
+ sourceEnd = methodDecl.sourceEnd;
+ if (sourceEnd <= 0
+ || methodDecl.declarationSourceStart > sourceEnd) {
+ sourceEnd = methodDecl.declarationSourceStart + 1;
+ }
+ methodDecl.declarationSourceEnd = sourceEnd;
+ methodDecl.sourceEnd = sourceEnd;
+ }
+ return statement;
+ } else if (token == TokenNamedeclare) {
+ // T_DECLARE '(' declare_list ')' declare_statement
+ getNextToken();
+ if (token != TokenNameLPAREN) {
+ throwSyntaxError("'(' expected in 'declare' statement.");
+ }
+ getNextToken();
+ declare_list();
+ if (token != TokenNameRPAREN) {
+ throwSyntaxError("')' expected in 'declare' statement.");
+ }
+ getNextToken();
+ declare_statement();
+ return statement;
+ } else if (token == TokenNametry) {
+ getNextToken();
+ if (token != TokenNameLBRACE) {
+ throwSyntaxError("'{' expected in 'try' statement.");
+ }
+ getNextToken();
+ statementList();
+ if (token != TokenNameRBRACE) {
+ throwSyntaxError("'}' expected in 'try' statement.");
+ }
+ getNextToken();
+ return statement;
+ } else if (token == TokenNamecatch) {
+ getNextToken();
+ if (token != TokenNameLPAREN) {
+ throwSyntaxError("'(' expected in 'catch' statement.");
+ }
+ getNextToken();
+ fully_qualified_class_name();
+ if (token != TokenNameVariable) {
+ throwSyntaxError("Variable expected in 'catch' statement.");
+ }
+ addVariableSet();
+ getNextToken();
+ if (token != TokenNameRPAREN) {
+ throwSyntaxError("')' expected in 'catch' statement.");
+ }
+ getNextToken();
+ if (token != TokenNameLBRACE) {
+ throwSyntaxError("'{' expected in 'catch' statement.");
+ }
+ getNextToken();
+ if (token != TokenNameRBRACE) {
+ statementList();
+ if (token != TokenNameRBRACE) {
+ throwSyntaxError("'}' expected in 'catch' statement.");
+ }
+ }
+ getNextToken();
+ additional_catches();
+ return statement;
+ } else if (token == TokenNamethrow) {
+ getNextToken();
+ expr();
+ if (token == TokenNameSEMICOLON) {
+ getNextToken();
+ } else {
+ throwSyntaxError("';' expected after 'throw' exxpression.");
+ }
+ return statement;
+ } else if (token == TokenNamefinal || token == TokenNameabstract
+ || token == TokenNameclass || token == TokenNameinterface) {
+ try {
+ TypeDeclaration typeDecl = new TypeDeclaration(
+ this.compilationUnit.compilationResult);
+ typeDecl.declarationSourceStart = scanner
+ .getCurrentTokenStartPosition();
+ typeDecl.declarationSourceEnd = scanner
+ .getCurrentTokenEndPosition();
+ typeDecl.name = new char[] { ' ' };
+ // default super class
+ typeDecl.superclass = new SingleTypeReference(
+ TypeConstants.OBJECT, 0);
+ compilationUnit.types.add(typeDecl);
+ pushOnAstStack(typeDecl);
+ unticked_class_declaration_statement(typeDecl);
+ } finally {
+ // reduce stack:
+ astPtr--;
+ astLengthPtr--;
+ }
+ return statement;
+ // } else {
+ // throwSyntaxError("Unexpected keyword '" + keyword + "'");
+ } else if (token == TokenNameLBRACE) {
+ getNextToken();
+ if (token != TokenNameRBRACE) {
+ statement = statementList();
+ }
+ if (token == TokenNameRBRACE) {
+ getNextToken();
+ return statement;
+ } else {
+ throwSyntaxError("'}' expected.");
+ }
+ } else {
+ if (token != TokenNameSEMICOLON) {
+ expr();
+ }
+ if (token == TokenNameSEMICOLON) {
+ getNextToken();
+ return statement;
+ } else {
+ if (token == TokenNameRBRACE) {
+ reportSyntaxError("';' expected after expression (Found token: "
+ + scanner.toStringAction(token) + ")");
+ } else {
+ if (token != TokenNameINLINE_HTML && token != TokenNameEOF) {
+ throwSyntaxError("';' expected after expression (Found token: "
+ + scanner.toStringAction(token) + ")");
+ }
+ getNextToken();
+ }
+ }
+ }
+ // may be null
+ return statement;
+ }
+
+ private void declare_statement() {
+ // statement
+ // | ':' inner_statement_list T_ENDDECLARE ';'
+ // ;
+ if (token == TokenNameCOLON) {
+ getNextToken();
+ // TODO: implement inner_statement_list();
+ statementList();
+ if (token != TokenNameenddeclare) {
+ throwSyntaxError("'enddeclare' expected in 'declare' statement.");
+ }
+ getNextToken();
+ if (token != TokenNameSEMICOLON) {
+ throwSyntaxError("';' expected after 'enddeclare' keyword.");
+ }
+ getNextToken();
+ } else {
+ statement();
+ }
+ }
+
+ private void declare_list() {
+ // T_STRING '=' static_scalar
+ // | declare_list ',' T_STRING '=' static_scalar
+ while (true) {
+ if (token != TokenNameIdentifier) {
+ throwSyntaxError("Identifier expected in 'declare' list.");
+ }
+ getNextToken();
+ if (token != TokenNameEQUAL) {
+ throwSyntaxError("'=' expected in 'declare' list.");
+ }
+ getNextToken();
+ static_scalar();
+ if (token != TokenNameCOMMA) {
+ break;
+ }
+ getNextToken();
+ }
+ }
+
+ private void additional_catches() {
+ while (token == TokenNamecatch) {
+ getNextToken();
+ if (token != TokenNameLPAREN) {
+ throwSyntaxError("'(' expected in 'catch' statement.");
+ }
+ getNextToken();
+ fully_qualified_class_name();
+ if (token != TokenNameVariable) {
+ throwSyntaxError("Variable expected in 'catch' statement.");
+ }
+ addVariableSet();
+ getNextToken();
+ if (token != TokenNameRPAREN) {
+ throwSyntaxError("')' expected in 'catch' statement.");
+ }
+ getNextToken();
+ if (token != TokenNameLBRACE) {
+ throwSyntaxError("'{' expected in 'catch' statement.");
+ }
+ getNextToken();
+ if (token != TokenNameRBRACE) {
+ statementList();
+ }
+ if (token != TokenNameRBRACE) {
+ throwSyntaxError("'}' expected in 'catch' statement.");
+ }
+ getNextToken();
+ }
+ }
+
+ private void foreach_variable() {
+ // w_variable
+ // | '&' w_variable
+ if (token == TokenNameAND) {
+ getNextToken();
+ }
+ w_variable(true);
+ }
+
+ private void foreach_optional_arg() {
+ // /* empty */
+ // | T_DOUBLE_ARROW foreach_variable
+ if (token == TokenNameEQUAL_GREATER) {
+ getNextToken();
+ foreach_variable();
+ }
+ }
+
+ private void global_var_list() {
+ // global_var_list:
+ // global_var_list ',' global_var
+ // | global_var
+ HashSet set = peekVariableSet();
+ while (true) {
+ global_var(set);
+ if (token != TokenNameCOMMA) {
+ break;
+ }
+ getNextToken();
+ }
+ }
+
+ private void global_var(HashSet set) {
+ // global_var:
+ // T_VARIABLE
+ // | '$' r_variable
+ // | '$' '{' expr '}'
+ if (token == TokenNameVariable) {
+ if (fMethodVariables != null) {
+ VariableInfo info = new VariableInfo(scanner
+ .getCurrentTokenStartPosition(),
+ VariableInfo.LEVEL_GLOBAL_VAR);
+ fMethodVariables.put(new String(scanner
+ .getCurrentIdentifierSource()), info);
+ }
+ addVariableSet(set);
+ getNextToken();
+ } else if (token == TokenNameDOLLAR) {
+ getNextToken();
+ if (token == TokenNameLBRACE) {
+ getNextToken();
+ expr();
+ if (token != TokenNameRBRACE) {
+ throwSyntaxError("'}' expected in global variable.");
+ }
+ getNextToken();
+ } else {
+ r_variable();
+ }
+ }
+ }
+
+ private void static_var_list() {
+ // static_var_list:
+ // static_var_list ',' T_VARIABLE
+ // | static_var_list ',' T_VARIABLE '=' static_scalar
+ // | T_VARIABLE
+ // | T_VARIABLE '=' static_scalar,
+ HashSet set = peekVariableSet();
+ while (true) {
+ if (token == TokenNameVariable) {
+ if (fMethodVariables != null) {
+ VariableInfo info = new VariableInfo(scanner
+ .getCurrentTokenStartPosition(),
+ VariableInfo.LEVEL_STATIC_VAR);
+ fMethodVariables.put(new String(scanner
+ .getCurrentIdentifierSource()), info);
+ }
+ addVariableSet(set);
+ getNextToken();
+ if (token == TokenNameEQUAL) {
+ getNextToken();
+ static_scalar();
+ }
+ if (token != TokenNameCOMMA) {
+ break;
+ }
+ getNextToken();
+ } else {
+ break;
+ }
+ }
+ }
+
+ private void unset_variables() {
+ // unset_variables:
+ // unset_variable
+ // | unset_variables ',' unset_variable
+ // unset_variable:
+ // variable
+ while (true) {
+ variable(false, false);
+ if (token != TokenNameCOMMA) {
+ break;
+ }
+ getNextToken();
+ }
+ }
+
+ private final void initializeModifiers() {
+ this.modifiers = 0;
+ this.modifiersSourceStart = -1;
+ }
+
+ private final void checkAndSetModifiers(int flag) {
+ this.modifiers |= flag;
+ if (this.modifiersSourceStart < 0)
+ this.modifiersSourceStart = this.scanner.startPosition;
+ }
+
+ private void unticked_class_declaration_statement(TypeDeclaration typeDecl) {
+ initializeModifiers();
+ if (token == TokenNameinterface) {
+ // interface_entry T_STRING
+ // interface_extends_list
+ // '{' class_statement_list '}'
+ checkAndSetModifiers(AccInterface);
+ getNextToken();
+ typeDecl.modifiers = this.modifiers;
+ typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
+ typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
+ if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
+ typeDecl.name = scanner.getCurrentIdentifierSource();
+ if (token > TokenNameKEYWORD) {
+ problemReporter.phpKeywordWarning(new String[] { scanner
+ .toStringAction(token) }, scanner
+ .getCurrentTokenStartPosition(), scanner
+ .getCurrentTokenEndPosition(), referenceContext,
+ compilationUnit.compilationResult);
+ // throwSyntaxError("Don't use a keyword for interface
+ // declaration ["
+ // + scanner.toStringAction(token) + "].",
+ // typeDecl.sourceStart, typeDecl.sourceEnd);
+ }
+ getNextToken();
+ interface_extends_list(typeDecl);
+ } else {
+ typeDecl.name = new char[] { ' ' };
+ throwSyntaxError(
+ "Interface name expected after keyword 'interface'.",
+ typeDecl.sourceStart, typeDecl.sourceEnd);
+ return;
+ }
+ } else {
+ // class_entry_type T_STRING extends_from
+ // implements_list
+ // '{' class_statement_list'}'
+ class_entry_type();
+ typeDecl.modifiers = this.modifiers;
+ typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
+ typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
+ // identifier
+ // identifier 'extends' identifier
+ if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
+ typeDecl.name = scanner.getCurrentIdentifierSource();
+ if (token > TokenNameKEYWORD) {
+ problemReporter.phpKeywordWarning(new String[] { scanner
+ .toStringAction(token) }, scanner
+ .getCurrentTokenStartPosition(), scanner
+ .getCurrentTokenEndPosition(), referenceContext,
+ compilationUnit.compilationResult);
+ // throwSyntaxError("Don't use a keyword for class
+ // declaration [" +
+ // scanner.toStringAction(token) + "].",
+ // typeDecl.sourceStart, typeDecl.sourceEnd);
+ }
+ getNextToken();
+ // extends_from:
+ // /* empty */
+ // | T_EXTENDS fully_qualified_class_name
+ if (token == TokenNameextends) {
+ class_extends_list(typeDecl);
+ // getNextToken();
+ // if (token != TokenNameIdentifier) {
+ // throwSyntaxError("Class name expected after keyword
+ // 'extends'.",
+ // scanner.getCurrentTokenStartPosition(), scanner
+ // .getCurrentTokenEndPosition());
+ // }
+ }
+ implements_list(typeDecl);
+ } else {
+ typeDecl.name = new char[] { ' ' };
+ throwSyntaxError("Class name expected after keyword 'class'.",
+ typeDecl.sourceStart, typeDecl.sourceEnd);
+ return;
+ }
+ }
+ // '{' class_statement_list '}'
+ if (token == TokenNameLBRACE) {
+ getNextToken();
+ if (token != TokenNameRBRACE) {
+ ArrayList list = new ArrayList();
+ class_statement_list(list);
+ typeDecl.fields = new FieldDeclaration[list.size()];
+ for (int i = 0; i < list.size(); i++) {
+ typeDecl.fields[i] = (FieldDeclaration) list.get(i);
+ }
+ }
+ if (token == TokenNameRBRACE) {
+ typeDecl.declarationSourceEnd = scanner
+ .getCurrentTokenEndPosition();
+ getNextToken();
+ } else {
+ throwSyntaxError("'}' expected at end of class body.");
+ }
+ } else {
+ throwSyntaxError("'{' expected at start of class body.");
+ }
+ }
+
+ private void class_entry_type() {
+ // T_CLASS
+ // | T_ABSTRACT T_CLASS
+ // | T_FINAL T_CLASS
+ if (token == TokenNameclass) {
+ getNextToken();
+ } else if (token == TokenNameabstract) {
+ checkAndSetModifiers(AccAbstract);
+ getNextToken();
+ if (token != TokenNameclass) {
+ throwSyntaxError("Keyword 'class' expected after keyword 'abstract'.");
+ }
+ getNextToken();
+ } else if (token == TokenNamefinal) {
+ checkAndSetModifiers(AccFinal);
+ getNextToken();
+ if (token != TokenNameclass) {
+ throwSyntaxError("Keyword 'class' expected after keyword 'final'.");
+ }
+ getNextToken();
+ } else {
+ throwSyntaxError("Keyword 'class' 'final' or 'abstract' expected");
+ }
+ }
+
+ // private void class_extends(TypeDeclaration typeDecl) {
+ // // /* empty */
+ // // | T_EXTENDS interface_list
+ // if (token == TokenNameextends) {
+ // getNextToken();
+ //
+ // if (token == TokenNameIdentifier) {
+ // getNextToken();
+ // } else {
+ // throwSyntaxError("Class name expected after keyword 'extends'.");
+ // }
+ // }
+ // }
+
+ private void interface_extends_list(TypeDeclaration typeDecl) {
+ // /* empty */
+ // | T_EXTENDS interface_list
+ if (token == TokenNameextends) {
+ getNextToken();
+ interface_list(typeDecl);
+ }
+ }
+
+ private void class_extends_list(TypeDeclaration typeDecl) {
+ // /* empty */
+ // | T_EXTENDS interface_list
+ if (token == TokenNameextends) {
+ getNextToken();
+ class_list(typeDecl);
+ }
+ }
+
+ private void implements_list(TypeDeclaration typeDecl) {
+ // /* empty */
+ // | T_IMPLEMENTS interface_list
+ if (token == TokenNameimplements) {
+ getNextToken();
+ interface_list(typeDecl);
+ }
+ }
+
+ private void class_list(TypeDeclaration typeDecl) {
+ // class_list:
+ // fully_qualified_class_name
+ do {
+ if (token == TokenNameIdentifier) {
+ char[] ident = scanner.getCurrentIdentifierSource();
+ // TODO make this code working better:
+ // SingleTypeReference ref =
+ // ParserUtil.getTypeReference(scanner,
+ // includesList, ident);
+ // if (ref != null) {
+ // typeDecl.superclass = ref;
+ // }
+ getNextToken();
+ } else {
+ throwSyntaxError("Classname expected after keyword 'extends'.");
+ }
+ if (token == TokenNameCOMMA) {
+ reportSyntaxError("No multiple inheritance allowed. Expected token 'implements' or '{'.");
+ getNextToken();
+ continue;
+ } else {
+ break;
+ }
+ } while (true);
+ }
+
+ private void interface_list(TypeDeclaration typeDecl) {
+ // interface_list:
+ // fully_qualified_class_name
+ // | interface_list ',' fully_qualified_class_name
+ do {
+ if (token == TokenNameIdentifier) {
+ getNextToken();
+ } else {
+ throwSyntaxError("Interfacename expected after keyword 'implements'.");
+ }
+ if (token != TokenNameCOMMA) {
+ return;
+ }
+ getNextToken();
+ } while (true);
+ }
+
+ // private void classBody(TypeDeclaration typeDecl) {
+ // //'{' [class-element-list] '}'
+ // if (token == TokenNameLBRACE) {
+ // getNextToken();
+ // if (token != TokenNameRBRACE) {
+ // class_statement_list();
+ // }
+ // if (token == TokenNameRBRACE) {
+ // typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
+ // getNextToken();
+ // } else {
+ // throwSyntaxError("'}' expected at end of class body.");
+ // }
+ // } else {
+ // throwSyntaxError("'{' expected at start of class body.");
+ // }
+ // }
+ private void class_statement_list(ArrayList list) {
+ do {
+ try {
+ class_statement(list);
+ if (token == TokenNamepublic || token == TokenNameprotected
+ || token == TokenNameprivate
+ || token == TokenNamestatic
+ || token == TokenNameabstract
+ || token == TokenNamefinal
+ || token == TokenNamefunction || token == TokenNamevar
+ || token == TokenNameconst) {
+ continue;
+ }
+ if (token == TokenNameRBRACE) {
+ break;
+ }
+ throwSyntaxError("'}' at end of class statement.");
+ } catch (SyntaxError sytaxErr1) {
+ boolean tokenize = scanner.tokenizeStrings;
+ if (!tokenize) {
+ scanner.tokenizeStrings = true;
+ }
+ try {
+ // if an error occured,
+ // try to find keywords
+ // to parse the rest of the string
+ while (token != TokenNameEOF) {
+ if (token == TokenNamepublic
+ || token == TokenNameprotected
+ || token == TokenNameprivate
+ || token == TokenNamestatic
+ || token == TokenNameabstract
+ || token == TokenNamefinal
+ || token == TokenNamefunction
+ || token == TokenNamevar
+ || token == TokenNameconst) {
+ break;
+ }
+ // System.out.println(scanner.toStringAction(token));
+ getNextToken();
+ }
+ if (token == TokenNameEOF) {
+ throw sytaxErr1;
+ }
+ } finally {
+ scanner.tokenizeStrings = tokenize;
+ }
+ }
+ } while (true);
+ }
+
+ private void class_statement(ArrayList list) {
+ // class_statement:
+ // variable_modifiers class_variable_declaration ';'
+ // | class_constant_declaration ';'
+ // | method_modifiers T_FUNCTION is_reference T_STRING
+ // '(' parameter_list ')' method_body
+ initializeModifiers();
+ int declarationSourceStart = scanner.getCurrentTokenStartPosition();
+
+ if (token == TokenNamevar) {
+ checkAndSetModifiers(AccPublic);
+ problemReporter.phpVarDeprecatedWarning(scanner
+ .getCurrentTokenStartPosition(), scanner
+ .getCurrentTokenEndPosition(), referenceContext,
+ compilationUnit.compilationResult);
+ getNextToken();
+ class_variable_declaration(declarationSourceStart, list);
+ } else if (token == TokenNameconst) {
+ checkAndSetModifiers(AccFinal | AccPublic);
+ class_constant_declaration(declarationSourceStart, list);
+ if (token != TokenNameSEMICOLON) {
+ throwSyntaxError("';' expected after class const declaration.");
+ }
+ getNextToken();
+ } else {
+ boolean hasModifiers = member_modifiers();
+ if (token == TokenNamefunction) {
+ if (!hasModifiers) {
+ checkAndSetModifiers(AccPublic);
+ }
+ MethodDeclaration methodDecl = new MethodDeclaration(
+ this.compilationUnit.compilationResult);
+ methodDecl.declarationSourceStart = scanner
+ .getCurrentTokenStartPosition();
+ methodDecl.modifiers = this.modifiers;
+ methodDecl.type = MethodDeclaration.METHOD_DEFINITION;
+ try {
+ getNextToken();
+ functionDefinition(methodDecl);
+ } finally {
+ int sourceEnd = methodDecl.sourceEnd;
+ if (sourceEnd <= 0
+ || methodDecl.declarationSourceStart > sourceEnd) {
+ sourceEnd = methodDecl.declarationSourceStart + 1;
+ }
+ methodDecl.declarationSourceEnd = sourceEnd;
+ methodDecl.sourceEnd = sourceEnd;
+ }
+ } else {
+ if (!hasModifiers) {
+ throwSyntaxError("'public' 'private' or 'protected' modifier expected for field declarations.");
+ }
+ class_variable_declaration(declarationSourceStart, list);
+ }
+ }
+ }
+
+ private void class_constant_declaration(int declarationSourceStart,
+ ArrayList list) {
+ // class_constant_declaration ',' T_STRING '=' static_scalar
+ // | T_CONST T_STRING '=' static_scalar
+ if (token != TokenNameconst) {
+ throwSyntaxError("'const' keyword expected in class declaration.");
+ } else {
+ getNextToken();
+ }
+ while (true) {
+ if (token != TokenNameIdentifier) {
+ throwSyntaxError("Identifier expected in class const declaration.");
+ }
+ FieldDeclaration fieldDeclaration = new FieldDeclaration(scanner
+ .getCurrentIdentifierSource(), scanner
+ .getCurrentTokenStartPosition(), scanner
+ .getCurrentTokenEndPosition());
+ fieldDeclaration.modifiers = this.modifiers;
+ fieldDeclaration.declarationSourceStart = declarationSourceStart;
+ fieldDeclaration.declarationSourceEnd = scanner
+ .getCurrentTokenEndPosition();
+ fieldDeclaration.modifiersSourceStart = declarationSourceStart;
+ // fieldDeclaration.type
+ list.add(fieldDeclaration);
+ getNextToken();
+ if (token != TokenNameEQUAL) {
+ throwSyntaxError("'=' expected in class const declaration.");
+ }
+ getNextToken();
+ static_scalar();
+ if (token != TokenNameCOMMA) {
+ break; // while(true)-loop
+ }
+ getNextToken();
+ }
+ }
+
+ // private void variable_modifiers() {
+ // // variable_modifiers:
+ // // non_empty_member_modifiers
+ // //| T_VAR
+ // initializeModifiers();
+ // if (token == TokenNamevar) {
+ // checkAndSetModifiers(AccPublic);
+ // reportSyntaxError(
+ // "Keyword 'var' is deprecated. Please use 'public' 'private' or
+ // 'protected'
+ // modifier for field declarations.",
+ // scanner.getCurrentTokenStartPosition(), scanner
+ // .getCurrentTokenEndPosition());
+ // getNextToken();
+ // } else {
+ // if (!member_modifiers()) {
+ // throwSyntaxError("'public' 'private' or 'protected' modifier expected for
+ // field declarations.");
+ // }
+ // }
+ // }
+ // private void method_modifiers() {
+ // //method_modifiers:
+ // // /* empty */
+ // //| non_empty_member_modifiers
+ // initializeModifiers();
+ // if (!member_modifiers()) {
+ // checkAndSetModifiers(AccPublic);
+ // }
+ // }
+ private boolean member_modifiers() {
+ // T_PUBLIC
+ // | T_PROTECTED
+ // | T_PRIVATE
+ // | T_STATIC
+ // | T_ABSTRACT
+ // | T_FINAL
+ boolean foundToken = false;
+ while (true) {
+ if (token == TokenNamepublic) {
+ checkAndSetModifiers(AccPublic);
+ getNextToken();
+ foundToken = true;
+ } else if (token == TokenNameprotected) {
+ checkAndSetModifiers(AccProtected);
+ getNextToken();
+ foundToken = true;
+ } else if (token == TokenNameprivate) {
+ checkAndSetModifiers(AccPrivate);
+ getNextToken();
+ foundToken = true;
+ } else if (token == TokenNamestatic) {
+ checkAndSetModifiers(AccStatic);
+ getNextToken();
+ foundToken = true;
+ } else if (token == TokenNameabstract) {
+ checkAndSetModifiers(AccAbstract);
+ getNextToken();
+ foundToken = true;
+ } else if (token == TokenNamefinal) {
+ checkAndSetModifiers(AccFinal);
+ getNextToken();
+ foundToken = true;
+ } else {
+ break;
+ }
+ }
+ return foundToken;
+ }
+
+ private void class_variable_declaration(int declarationSourceStart,
+ ArrayList list) {
+ // class_variable_declaration:
+ // class_variable_declaration ',' T_VARIABLE
+ // | class_variable_declaration ',' T_VARIABLE '=' static_scalar
+ // | T_VARIABLE
+ // | T_VARIABLE '=' static_scalar
+ char[] classVariable;
+ do {
+ if (token == TokenNameVariable) {
+ classVariable = scanner.getCurrentIdentifierSource();
+ // indexManager.addIdentifierInformation('v', classVariable,
+ // buf, -1,
+ // -1);
+ FieldDeclaration fieldDeclaration = new FieldDeclaration(
+ classVariable, scanner.getCurrentTokenStartPosition(),
+ scanner.getCurrentTokenEndPosition());
+ fieldDeclaration.modifiers = this.modifiers;
+ fieldDeclaration.declarationSourceStart = declarationSourceStart;
+ fieldDeclaration.declarationSourceEnd = scanner
+ .getCurrentTokenEndPosition();
+ fieldDeclaration.modifiersSourceStart = declarationSourceStart;
+ list.add(fieldDeclaration);
+ if (fTypeVariables != null) {
+ VariableInfo info = new VariableInfo(scanner
+ .getCurrentTokenStartPosition(),
+ VariableInfo.LEVEL_CLASS_UNIT);
+ fTypeVariables.put(new String(scanner
+ .getCurrentIdentifierSource()), info);
+ }
+ getNextToken();
+ if (token == TokenNameEQUAL) {
+ getNextToken();
+ static_scalar();
+ }
+ } else {
+ // if (token == TokenNamethis) {
+ // throwSyntaxError("'$this' not allowed after keyword 'public'
+ // 'protected' 'private' 'var'.");
+ // }
+ throwSyntaxError("Variable expected after keyword 'public' 'protected' 'private' 'var'.");
+ }
+ if (token != TokenNameCOMMA) {
+ break;
+ }
+ getNextToken();
+ } while (true);
+ if (token != TokenNameSEMICOLON) {
+ throwSyntaxError("';' expected after field declaration.");
+ }
+ getNextToken();
+ }
+
+ private void functionDefinition(MethodDeclaration methodDecl) {
+ boolean isAbstract = false;
+ if (astPtr == 0) {
+ if (compilationUnit != null) {
+ compilationUnit.types.add(methodDecl);
+ }
+ } else {
+ ASTNode node = astStack[astPtr];
+ if (node instanceof TypeDeclaration) {
+ TypeDeclaration typeDecl = ((TypeDeclaration) node);
+ if (typeDecl.methods == null) {
+ typeDecl.methods = new AbstractMethodDeclaration[] { methodDecl };
+ } else {
+ AbstractMethodDeclaration[] newMethods;
+ System
+ .arraycopy(
+ typeDecl.methods,
+ 0,
+ newMethods = new AbstractMethodDeclaration[typeDecl.methods.length + 1],
+ 0, typeDecl.methods.length);
+ newMethods[typeDecl.methods.length] = methodDecl;
+ typeDecl.methods = newMethods;
+ }
+ if ((typeDecl.modifiers & AccAbstract) == AccAbstract) {
+ isAbstract = true;
+ } else if ((typeDecl.modifiers & AccInterface) == AccInterface) {
+ isAbstract = true;
+ }
+ }
+ }
+ try {
+ pushFunctionVariableSet();
+ functionDeclarator(methodDecl);
+ if (token == TokenNameSEMICOLON) {
+ if (!isAbstract) {
+ methodDecl.sourceEnd = scanner
+ .getCurrentTokenStartPosition() - 1;
+ throwSyntaxError("Body declaration expected for method: "
+ + new String(methodDecl.selector));
+ }
+ getNextToken();
+ return;
+ }
+ functionBody(methodDecl);
+ } finally {
+ if (!fStackUnassigned.isEmpty()) {
+ fStackUnassigned.remove(fStackUnassigned.size() - 1);
+ }
+ }
+ }
+
+ private void functionDeclarator(MethodDeclaration methodDecl) {
+ // identifier '(' [parameter-list] ')'
+ if (token == TokenNameAND) {
+ getNextToken();
+ }
+ methodDecl.sourceStart = scanner.getCurrentTokenStartPosition();
+ methodDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
+ if (Scanner.isIdentifierOrKeyword(token)) {
+ methodDecl.selector = scanner.getCurrentIdentifierSource();
+ if (token > TokenNameKEYWORD) {
+ problemReporter.phpKeywordWarning(new String[] { scanner
+ .toStringAction(token) }, scanner
+ .getCurrentTokenStartPosition(), scanner
+ .getCurrentTokenEndPosition(), referenceContext,
+ compilationUnit.compilationResult);
+ }
+ getNextToken();
+ if (token == TokenNameLPAREN) {
+ getNextToken();
+ } else {
+ methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1;
+ throwSyntaxError("'(' expected in function declaration.");
+ }
+ if (token != TokenNameRPAREN) {
+ parameter_list(methodDecl);
+ }
+ if (token != TokenNameRPAREN) {
+ methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1;
+ throwSyntaxError("')' expected in function declaration.");
+ } else {
+ methodDecl.bodyStart = scanner.getCurrentTokenEndPosition() + 1;
+ getNextToken();
+ }
+ } else {
+ methodDecl.selector = "<undefined>".toCharArray();
+ methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1;
+ throwSyntaxError("Function name expected after keyword 'function'.");
+ }
+ }
+
+ //
+ private void parameter_list(MethodDeclaration methodDecl) {
+ // non_empty_parameter_list
+ // | /* empty */
+ non_empty_parameter_list(methodDecl, true);
+ }
+
+ private void non_empty_parameter_list(MethodDeclaration methodDecl,
+ boolean empty_allowed) {
+ // optional_class_type T_VARIABLE
+ // | optional_class_type '&' T_VARIABLE
+ // | optional_class_type '&' T_VARIABLE '=' static_scalar
+ // | optional_class_type T_VARIABLE '=' static_scalar
+ // | non_empty_parameter_list ',' optional_class_type T_VARIABLE
+ // | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE
+ // | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE '='
+ // static_scalar
+ // | non_empty_parameter_list ',' optional_class_type T_VARIABLE '='
+ // static_scalar
+ char[] typeIdentifier = null;
+ if (token == TokenNameIdentifier || token == TokenNamearray
+ || token == TokenNameVariable || token == TokenNameAND) {
+ HashSet set = peekVariableSet();
+ while (true) {
+ if (token == TokenNameIdentifier || token == TokenNamearray) {// feature
+ // req.
+ // #1254275
+ typeIdentifier = scanner.getCurrentIdentifierSource();
+ getNextToken();
+ }
+ if (token == TokenNameAND) {
+ getNextToken();
+ }
+ if (token == TokenNameVariable) {
+ if (fMethodVariables != null) {
+ VariableInfo info;
+ if (methodDecl.type == MethodDeclaration.FUNCTION_DEFINITION) {
+ info = new VariableInfo(scanner
+ .getCurrentTokenStartPosition(),
+ VariableInfo.LEVEL_FUNCTION_DEFINITION);
+ } else {
+ info = new VariableInfo(scanner
+ .getCurrentTokenStartPosition(),
+ VariableInfo.LEVEL_METHOD_DEFINITION);
+ }
+ info.typeIdentifier = typeIdentifier;
+ fMethodVariables.put(new String(scanner
+ .getCurrentIdentifierSource()), info);
+ }
+ addVariableSet(set);
+ getNextToken();
+ if (token == TokenNameEQUAL) {
+ getNextToken();
+ static_scalar();
+ }
+ } else {
+ throwSyntaxError("Variable expected in parameter list.");
+ }
+ if (token != TokenNameCOMMA) {
+ break;
+ }
+ getNextToken();
+ }
+ return;
+ }
+ if (!empty_allowed) {
+ throwSyntaxError("Identifier expected in parameter list.");
+ }
+ }
+
+ private void optional_class_type() {
+ // /* empty */
+ // | T_STRING
+ }
+
+ // private void parameterDeclaration() {
+ // //variable
+ // //variable-reference
+ // if (token == TokenNameAND) {
+ // getNextToken();
+ // if (isVariable()) {
+ // getNextToken();
+ // } else {
+ // throwSyntaxError("Variable expected after reference operator '&'.");
+ // }
+ // }
+ // //variable '=' constant
+ // if (token == TokenNameVariable) {
+ // getNextToken();
+ // if (token == TokenNameEQUAL) {
+ // getNextToken();
+ // static_scalar();
+ // }
+ // return;
+ // }
+ // // if (token == TokenNamethis) {
+ // // throwSyntaxError("Reserved word '$this' not allowed in parameter
+ // // declaration.");
+ // // }
+ // }
+
+ private void labeledStatementList() {
+ if (token != TokenNamecase && token != TokenNamedefault) {
+ throwSyntaxError("'case' or 'default' expected.");
+ }
+ do {
+ if (token == TokenNamecase) {
+ getNextToken();
+ expr(); // constant();
+ if (token == TokenNameCOLON || token == TokenNameSEMICOLON) {
+ getNextToken();
+ if (token == TokenNameRBRACE) {
+ // empty case; assumes that the '}' token belongs to the
+ // wrapping
+ // switch statement - #1371992
+ break;
+ }
+ if (token == TokenNamecase || token == TokenNamedefault) {
+ // empty case statement ?
+ continue;
+ }
+ statementList();
+ }
+ // else if (token == TokenNameSEMICOLON) {
+ // setMarker(
+ // "':' expected after 'case' keyword (Found token: " +
+ // scanner.toStringAction(token) + ")",
+ // scanner.getCurrentTokenStartPosition(),
+ // scanner.getCurrentTokenEndPosition(),
+ // INFO);
+ // getNextToken();
+ // if (token == TokenNamecase) { // empty case statement ?
+ // continue;
+ // }
+ // statementList();
+ // }
+ else {
+ throwSyntaxError("':' character expected after 'case' constant (Found token: "
+ + scanner.toStringAction(token) + ")");
+ }
+ } else { // TokenNamedefault
+ getNextToken();
+ if (token == TokenNameCOLON || token == TokenNameSEMICOLON) {
+ getNextToken();
+ if (token == TokenNameRBRACE) {
+ // empty default case; ; assumes that the '}' token
+ // belongs to the
+ // wrapping switch statement - #1371992
+ break;
+ }
+ if (token != TokenNamecase) {
+ statementList();
+ }
+ } else {
+ throwSyntaxError("':' character expected after 'default'.");
+ }
+ }
+ } while (token == TokenNamecase || token == TokenNamedefault);
+ }
+
+ private void ifStatementColon(IfStatement iState) {
+ // T_IF '(' expr ')' ':' inner_statement_list new_elseif_list
+ // new_else_single T_ENDIF ';'
+ HashSet assignedVariableSet = null;
+ try {
+ Block b = inner_statement_list();
+ iState.thenStatement = b;
+ checkUnreachable(iState, b);
+ } finally {
+ assignedVariableSet = removeIfVariableSet();
+ }
+ if (token == TokenNameelseif) {
+ try {
+ pushIfVariableSet();
+ new_elseif_list(iState);
+ } finally {
+ HashSet set = removeIfVariableSet();
+ if (assignedVariableSet != null && set != null) {
+ assignedVariableSet.addAll(set);
+ }
+ }
+ }
+ try {
+ pushIfVariableSet();
+ new_else_single(iState);
+ } finally {
+ HashSet set = removeIfVariableSet();
+ if (assignedVariableSet != null) {
+ HashSet topSet = peekVariableSet();
+ if (topSet != null) {
+ if (set != null) {
+ topSet.addAll(set);
+ }
+ topSet.addAll(assignedVariableSet);
+ }
+ }
+ }
+ if (token != TokenNameendif) {
+ throwSyntaxError("'endif' expected.");
+ }
+ getNextToken();
+ if (token != TokenNameSEMICOLON) {
+ reportSyntaxError("';' expected after if-statement.");
+ iState.sourceEnd = scanner.getCurrentTokenStartPosition();
+ } else {
+ iState.sourceEnd = scanner.getCurrentTokenEndPosition();
+ getNextToken();
+ }
+ }
+
+ private void ifStatement(IfStatement iState) {
+ // T_IF '(' expr ')' statement elseif_list else_single
+ HashSet assignedVariableSet = null;
+ try {
+ pushIfVariableSet();
+ Statement s = statement();
+ iState.thenStatement = s;
+ checkUnreachable(iState, s);
+ } finally {
+ assignedVariableSet = removeIfVariableSet();
+ }
+
+ if (token == TokenNameelseif) {
+ try {
+ pushIfVariableSet();
+ elseif_list(iState);
+ } finally {
+ HashSet set = removeIfVariableSet();
+ if (assignedVariableSet != null && set != null) {
+ assignedVariableSet.addAll(set);
+ }
+ }
+ }
+ try {
+ pushIfVariableSet();
+ else_single(iState);
+ } finally {
+ HashSet set = removeIfVariableSet();
+ if (assignedVariableSet != null) {
+ HashSet topSet = peekVariableSet();
+ if (topSet != null) {
+ if (set != null) {
+ topSet.addAll(set);
+ }
+ topSet.addAll(assignedVariableSet);
+ }
+ }
+ }
+ }
+
+ private void elseif_list(IfStatement iState) {
+ // /* empty */
+ // | elseif_list T_ELSEIF '(' expr ')' statement
+ ArrayList conditionList = new ArrayList();
+ ArrayList statementList = new ArrayList();
+ Expression e;
+ Statement s;
+ while (token == TokenNameelseif) {
+ getNextToken();
+ if (token == TokenNameLPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'(' expected after 'elseif' keyword.");
+ }
+ e = expr();
+ conditionList.add(e);
+ if (token == TokenNameRPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("')' expected after 'elseif' condition.");
+ }
+ s = statement();
+ statementList.add(s);
+ checkUnreachable(iState, s);
+ }
+ iState.elseifConditions = new Expression[conditionList.size()];
+ iState.elseifStatements = new Statement[statementList.size()];
+ conditionList.toArray(iState.elseifConditions);
+ statementList.toArray(iState.elseifStatements);
+ }
+
+ private void new_elseif_list(IfStatement iState) {
+ // /* empty */
+ // | new_elseif_list T_ELSEIF '(' expr ')' ':' inner_statement_list
+ ArrayList conditionList = new ArrayList();
+ ArrayList statementList = new ArrayList();
+ Expression e;
+ Block b;
+ while (token == TokenNameelseif) {
+ getNextToken();
+ if (token == TokenNameLPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'(' expected after 'elseif' keyword.");
+ }
+ e = expr();
+ conditionList.add(e);
+ if (token == TokenNameRPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("')' expected after 'elseif' condition.");
+ }
+ if (token == TokenNameCOLON) {
+ getNextToken();
+ } else {
+ throwSyntaxError("':' expected after 'elseif' keyword.");
+ }
+ b = inner_statement_list();
+ statementList.add(b);
+ checkUnreachable(iState, b);
+ }
+ iState.elseifConditions = new Expression[conditionList.size()];
+ iState.elseifStatements = new Statement[statementList.size()];
+ conditionList.toArray(iState.elseifConditions);
+ statementList.toArray(iState.elseifStatements);
+ }
+
+ private void else_single(IfStatement iState) {
+ // /* empty */
+ // T_ELSE statement
+ if (token == TokenNameelse) {
+ getNextToken();
+ Statement s = statement();
+ iState.elseStatement = s;
+ checkUnreachable(iState, s);
+ } else {
+ iState.checkUnreachable = false;
+ }
+ iState.sourceEnd = scanner.getCurrentTokenStartPosition();
+ }
+
+ private void new_else_single(IfStatement iState) {
+ // /* empty */
+ // | T_ELSE ':' inner_statement_list
+ if (token == TokenNameelse) {
+ getNextToken();
+ if (token == TokenNameCOLON) {
+ getNextToken();
+ } else {
+ throwSyntaxError("':' expected after 'else' keyword.");
+ }
+ Block b = inner_statement_list();
+ iState.elseStatement = b;
+ checkUnreachable(iState, b);
+ } else {
+ iState.checkUnreachable = false;
+ }
+ }
+
+ private Block inner_statement_list() {
+ // inner_statement_list inner_statement
+ // /* empty */
+ return statementList();
+ }
+
+ /**
+ * @param iState
+ * @param b
+ */
+ private void checkUnreachable(IfStatement iState, Statement s) {
+ if (s instanceof Block) {
+ Block b = (Block) s;
+ if (b.statements == null || b.statements.length == 0) {
+ iState.checkUnreachable = false;
+ } else {
+ int off = b.statements.length - 1;
+ if (!(b.statements[off] instanceof ReturnStatement)
+ && !(b.statements[off] instanceof ContinueStatement)
+ && !(b.statements[off] instanceof BreakStatement)) {
+ if (!(b.statements[off] instanceof IfStatement)
+ || !((IfStatement) b.statements[off]).checkUnreachable) {
+ iState.checkUnreachable = false;
+ }
+ }
+ }
+ } else {
+ if (!(s instanceof ReturnStatement)
+ && !(s instanceof ContinueStatement)
+ && !(s instanceof BreakStatement)) {
+ if (!(s instanceof IfStatement)
+ || !((IfStatement) s).checkUnreachable) {
+ iState.checkUnreachable = false;
+ }
+ }
+ }
+ }
+
+ // private void elseifStatementList() {
+ // do {
+ // elseifStatement();
+ // switch (token) {
+ // case TokenNameelse:
+ // getNextToken();
+ // if (token == TokenNameCOLON) {
+ // getNextToken();
+ // if (token != TokenNameendif) {
+ // statementList();
+ // }
+ // return;
+ // } else {
+ // if (token == TokenNameif) { //'else if'
+ // getNextToken();
+ // } else {
+ // throwSyntaxError("':' expected after 'else'.");
+ // }
+ // }
+ // break;
+ // case TokenNameelseif:
+ // getNextToken();
+ // break;
+ // default:
+ // return;
+ // }
+ // } while (true);
+ // }
+
+ // private void elseifStatement() {
+ // if (token == TokenNameLPAREN) {
+ // getNextToken();
+ // expr();
+ // if (token != TokenNameRPAREN) {
+ // throwSyntaxError("')' expected in else-if-statement.");
+ // }
+ // getNextToken();
+ // if (token != TokenNameCOLON) {
+ // throwSyntaxError("':' expected in else-if-statement.");
+ // }
+ // getNextToken();
+ // if (token != TokenNameendif) {
+ // statementList();
+ // }
+ // }
+ // }
+
+ private void switchStatement() {
+ if (token == TokenNameCOLON) {
+ // ':' [labeled-statement-list] 'endswitch' ';'
+ getNextToken();
+ labeledStatementList();
+ if (token != TokenNameendswitch) {
+ throwSyntaxError("'endswitch' expected.");
+ }
+ getNextToken();
+ if (token != TokenNameSEMICOLON) {
+ throwSyntaxError("';' expected after switch-statement.");
+ }
+ getNextToken();
+ } else {
+ // '{' [labeled-statement-list] '}'
+ if (token != TokenNameLBRACE) {
+ throwSyntaxError("'{' expected in switch statement.");
+ }
+ getNextToken();
+ if (token != TokenNameRBRACE) {
+ labeledStatementList();
+ }
+ if (token != TokenNameRBRACE) {
+ throwSyntaxError("'}' expected in switch statement.");
+ }
+ getNextToken();
+ }
+ }
+
+ private void forStatement() {
+ if (token == TokenNameCOLON) {
+ getNextToken();
+ statementList();
+ if (token != TokenNameendfor) {
+ throwSyntaxError("'endfor' expected.");
+ }
+ getNextToken();
+ if (token != TokenNameSEMICOLON) {
+ throwSyntaxError("';' expected after for-statement.");
+ }
+ getNextToken();
+ } else {
+ statement();
+ }
+ }
+
+ private void whileStatement() {
+ // ':' statement-list 'endwhile' ';'
+ if (token == TokenNameCOLON) {
+ getNextToken();
+ statementList();
+ if (token != TokenNameendwhile) {
+ throwSyntaxError("'endwhile' expected.");
+ }
+ getNextToken();
+ if (token != TokenNameSEMICOLON) {
+ throwSyntaxError("';' expected after while-statement.");
+ }
+ getNextToken();
+ } else {
+ statement();
+ }
+ }
+
+ private void foreachStatement() {
+ if (token == TokenNameCOLON) {
+ getNextToken();
+ statementList();
+ if (token != TokenNameendforeach) {
+ throwSyntaxError("'endforeach' expected.");
+ }
+ getNextToken();
+ if (token != TokenNameSEMICOLON) {
+ throwSyntaxError("';' expected after foreach-statement.");
+ }
+ getNextToken();
+ } else {
+ statement();
+ }
+ }
+
+ // private void exitStatus() {
+ // if (token == TokenNameLPAREN) {
+ // getNextToken();
+ // } else {
+ // throwSyntaxError("'(' expected in 'exit-status'.");
+ // }
+ // if (token != TokenNameRPAREN) {
+ // expression();
+ // }
+ // if (token == TokenNameRPAREN) {
+ // getNextToken();
+ // } else {
+ // throwSyntaxError("')' expected after 'exit-status'.");
+ // }
+ // }
+ private void expressionList() {
+ do {
+ expr();
+ if (token == TokenNameCOMMA) {
+ getNextToken();
+ } else {
+ break;
+ }
+ } while (true);
+ }
+
+ private Expression expr() {
+ // r_variable
+ // | expr_without_variable
+ // if (token!=TokenNameEOF) {
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: expr()");
+ }
+ return expr_without_variable(true, null);
+ // }
+ }
+
+ private Expression expr_without_variable(boolean only_variable,
+ UninitializedVariableHandler initHandler) {
+ int exprSourceStart = scanner.getCurrentTokenStartPosition();
+ int exprSourceEnd = scanner.getCurrentTokenEndPosition();
+ Expression expression = new Expression();
+ expression.sourceStart = exprSourceStart;
+ // default, may be overwritten
+ expression.sourceEnd = exprSourceEnd;
+ try {
+ // internal_functions_in_yacc
+ // | T_CLONE expr
+ // | T_PRINT expr
+ // | '(' expr ')'
+ // | '@' expr
+ // | '+' expr
+ // | '-' expr
+ // | '!' expr
+ // | '~' expr
+ // | T_INC rw_variable
+ // | T_DEC rw_variable
+ // | T_INT_CAST expr
+ // | T_DOUBLE_CAST expr
+ // | T_STRING_CAST expr
+ // | T_ARRAY_CAST expr
+ // | T_OBJECT_CAST expr
+ // | T_BOOL_CAST expr
+ // | T_UNSET_CAST expr
+ // | T_EXIT exit_expr
+ // | scalar
+ // | T_ARRAY '(' array_pair_list ')'
+ // | '`' encaps_list '`'
+ // | T_LIST '(' assignment_list ')' '=' expr
+ // | T_NEW class_name_reference ctor_arguments
+ // | variable '=' expr
+ // | variable '=' '&' variable
+ // | variable '=' '&' T_NEW class_name_reference ctor_arguments
+ // | variable T_PLUS_EQUAL expr
+ // | variable T_MINUS_EQUAL expr
+ // | variable T_MUL_EQUAL expr
+ // | variable T_DIV_EQUAL expr
+ // | variable T_CONCAT_EQUAL expr
+ // | variable T_MOD_EQUAL expr
+ // | variable T_AND_EQUAL expr
+ // | variable T_OR_EQUAL expr
+ // | variable T_XOR_EQUAL expr
+ // | variable T_SL_EQUAL expr
+ // | variable T_SR_EQUAL expr
+ // | rw_variable T_INC
+ // | rw_variable T_DEC
+ // | expr T_BOOLEAN_OR expr
+ // | expr T_BOOLEAN_AND expr
+ // | expr T_LOGICAL_OR expr
+ // | expr T_LOGICAL_AND expr
+ // | expr T_LOGICAL_XOR expr
+ // | expr '|' expr
+ // | expr '&' expr
+ // | expr '^' expr
+ // | expr '.' expr
+ // | expr '+' expr
+ // | expr '-' expr
+ // | expr '*' expr
+ // | expr '/' expr
+ // | expr '%' expr
+ // | expr T_SL expr
+ // | expr T_SR expr
+ // | expr T_IS_IDENTICAL expr
+ // | expr T_IS_NOT_IDENTICAL expr
+ // | expr T_IS_EQUAL expr
+ // | expr T_IS_NOT_EQUAL expr
+ // | expr '<' expr
+ // | expr T_IS_SMALLER_OR_EQUAL expr
+ // | expr '>' expr
+ // | expr T_IS_GREATER_OR_EQUAL expr
+ // | expr T_INSTANCEOF class_name_reference
+ // | expr '?' expr ':' expr
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: expr_without_variable() PART 1");
+ }
+ switch (token) {
+ case TokenNameisset:
+ // T_ISSET '(' isset_variables ')'
+ getNextToken();
+ if (token != TokenNameLPAREN) {
+ throwSyntaxError("'(' expected after keyword 'isset'");
+ }
+ getNextToken();
+ isset_variables();
+ if (token != TokenNameRPAREN) {
+ throwSyntaxError("')' expected after keyword 'isset'");
+ }
+ getNextToken();
+ break;
+ case TokenNameempty:
+ getNextToken();
+ if (token != TokenNameLPAREN) {
+ throwSyntaxError("'(' expected after keyword 'empty'");
+ }
+ getNextToken();
+ variable(true, false);
+ if (token != TokenNameRPAREN) {
+ throwSyntaxError("')' expected after keyword 'empty'");
+ }
+ getNextToken();
+ break;
+ case TokenNameeval:
+ case TokenNameinclude:
+ case TokenNameinclude_once:
+ case TokenNamerequire:
+ case TokenNamerequire_once:
+ internal_functions_in_yacc();
+ break;
+ // | '(' expr ')'
+ case TokenNameLPAREN:
+ getNextToken();
+ expr();
+ if (token == TokenNameRPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("')' expected in expression.");
+ }
+ break;
+ // | T_CLONE expr
+ // | T_PRINT expr
+ // | '@' expr
+ // | '+' expr
+ // | '-' expr
+ // | '!' expr
+ // | '~' expr
+ // | T_INT_CAST expr
+ // | T_DOUBLE_CAST expr
+ // | T_STRING_CAST expr
+ // | T_ARRAY_CAST expr
+ // | T_OBJECT_CAST expr
+ // | T_BOOL_CAST expr
+ // | T_UNSET_CAST expr
+ case TokenNameclone:
+ case TokenNameprint:
+ case TokenNameAT:
+ case TokenNamePLUS:
+ case TokenNameMINUS:
+ case TokenNameNOT:
+ case TokenNameTWIDDLE:
+ case TokenNameintCAST:
+ case TokenNamedoubleCAST:
+ case TokenNamestringCAST:
+ case TokenNamearrayCAST:
+ case TokenNameobjectCAST:
+ case TokenNameboolCAST:
+ case TokenNameunsetCAST:
+ getNextToken();
+ expr();
+ break;
+ case TokenNameexit:
+ getNextToken();
+ exit_expr();
+ break;
+ // scalar:
+ // T_STRING
+ // | T_STRING_VARNAME
+ // | class_constant
+ // | T_START_HEREDOC encaps_list T_END_HEREDOC
+ // | '`' encaps_list '`'
+ // | common_scalar
+ // | '`' encaps_list '`'
+ // case TokenNameEncapsedString0:
+ // scanner.encapsedStringStack.push(new Character('`'));
+ // getNextToken();
+ // try {
+ // if (token == TokenNameEncapsedString0) {
+ // } else {
+ // encaps_list();
+ // if (token != TokenNameEncapsedString0) {
+ // throwSyntaxError("\'`\' expected at end of string" + "(Found
+ // token: " +
+ // scanner.toStringAction(token) + " )");
+ // }
+ // }
+ // } finally {
+ // scanner.encapsedStringStack.pop();
+ // getNextToken();
+ // }
+ // break;
+ // // | '\'' encaps_list '\''
+ // case TokenNameEncapsedString1:
+ // scanner.encapsedStringStack.push(new Character('\''));
+ // getNextToken();
+ // try {
+ // exprSourceStart = scanner.getCurrentTokenStartPosition();
+ // if (token == TokenNameEncapsedString1) {
+ // expression = new
+ // StringLiteralSQ(scanner.getCurrentStringLiteralSource(exprSourceStart),
+ // exprSourceStart, scanner
+ // .getCurrentTokenEndPosition());
+ // } else {
+ // encaps_list();
+ // if (token != TokenNameEncapsedString1) {
+ // throwSyntaxError("\'\'\' expected at end of string" + "(Found
+ // token: "
+ // + scanner.toStringAction(token) + " )");
+ // } else {
+ // expression = new
+ // StringLiteralSQ(scanner.getCurrentStringLiteralSource(exprSourceStart),
+ // exprSourceStart, scanner
+ // .getCurrentTokenEndPosition());
+ // }
+ // }
+ // } finally {
+ // scanner.encapsedStringStack.pop();
+ // getNextToken();
+ // }
+ // break;
+ // //| '"' encaps_list '"'
+ // case TokenNameEncapsedString2:
+ // scanner.encapsedStringStack.push(new Character('"'));
+ // getNextToken();
+ // try {
+ // exprSourceStart = scanner.getCurrentTokenStartPosition();
+ // if (token == TokenNameEncapsedString2) {
+ // expression = new
+ // StringLiteralDQ(scanner.getCurrentStringLiteralSource(exprSourceStart),
+ // exprSourceStart, scanner
+ // .getCurrentTokenEndPosition());
+ // } else {
+ // encaps_list();
+ // if (token != TokenNameEncapsedString2) {
+ // throwSyntaxError("'\"' expected at end of string" + "(Found
+ // token: " +
+ // scanner.toStringAction(token) + " )");
+ // } else {
+ // expression = new
+ // StringLiteralDQ(scanner.getCurrentStringLiteralSource(exprSourceStart),
+ // exprSourceStart, scanner
+ // .getCurrentTokenEndPosition());
+ // }
+ // }
+ // } finally {
+ // scanner.encapsedStringStack.pop();
+ // getNextToken();
+ // }
+ // break;
+ case TokenNameStringDoubleQuote:
+ expression = new StringLiteralDQ(scanner
+ .getCurrentStringLiteralSource(), scanner
+ .getCurrentTokenStartPosition(), scanner
+ .getCurrentTokenEndPosition());
+ common_scalar();
+ break;
+ case TokenNameStringSingleQuote:
+ expression = new StringLiteralSQ(scanner
+ .getCurrentStringLiteralSource(), scanner
+ .getCurrentTokenStartPosition(), scanner
+ .getCurrentTokenEndPosition());
+ common_scalar();
+ break;
+ case TokenNameIntegerLiteral:
+ case TokenNameDoubleLiteral:
+ case TokenNameStringInterpolated:
+ case TokenNameFILE:
+ case TokenNameLINE:
+ case TokenNameCLASS_C:
+ case TokenNameMETHOD_C:
+ case TokenNameFUNC_C:
+ common_scalar();
+ break;
+ case TokenNameHEREDOC:
+ getNextToken();
+ break;
+ case TokenNamearray:
+ // T_ARRAY '(' array_pair_list ')'
+ getNextToken();
+ if (token == TokenNameLPAREN) {
+ getNextToken();
+ if (token == TokenNameRPAREN) {
+ getNextToken();
+ break;
+ }
+ array_pair_list();
+ if (token != TokenNameRPAREN) {
+ throwSyntaxError("')' or ',' expected after keyword 'array'"
+ + "(Found token: "
+ + scanner.toStringAction(token) + ")");
+ }
+ getNextToken();
+ } else {
+ throwSyntaxError("'(' expected after keyword 'array'"
+ + "(Found token: " + scanner.toStringAction(token)
+ + ")");
+ }
+ break;
+ case TokenNamelist:
+ // | T_LIST '(' assignment_list ')' '=' expr
+ getNextToken();
+ if (token == TokenNameLPAREN) {
+ getNextToken();
+ assignment_list();
+ if (token != TokenNameRPAREN) {
+ throwSyntaxError("')' expected after 'list' keyword.");
+ }
+ getNextToken();
+ if (token != TokenNameEQUAL) {
+ throwSyntaxError("'=' expected after 'list' keyword.");
+ }
+ getNextToken();
+ expr();
+ } else {
+ throwSyntaxError("'(' expected after 'list' keyword.");
+ }
+ break;
+ case TokenNamenew:
+ // | T_NEW class_name_reference ctor_arguments
+ getNextToken();
+ Expression typeRef = class_name_reference();
+ ctor_arguments();
+ if (typeRef != null) {
+ expression = typeRef;
+ }
+ break;
+ // | T_INC rw_variable
+ // | T_DEC rw_variable
+ case TokenNamePLUS_PLUS:
+ case TokenNameMINUS_MINUS:
+ getNextToken();
+ rw_variable();
+ break;
+ // | variable '=' expr
+ // | variable '=' '&' variable
+ // | variable '=' '&' T_NEW class_name_reference ctor_arguments
+ // | variable T_PLUS_EQUAL expr
+ // | variable T_MINUS_EQUAL expr
+ // | variable T_MUL_EQUAL expr
+ // | variable T_DIV_EQUAL expr
+ // | variable T_CONCAT_EQUAL expr
+ // | variable T_MOD_EQUAL expr
+ // | variable T_AND_EQUAL expr
+ // | variable T_OR_EQUAL expr
+ // | variable T_XOR_EQUAL expr
+ // | variable T_SL_EQUAL expr
+ // | variable T_SR_EQUAL expr
+ // | rw_variable T_INC
+ // | rw_variable T_DEC
+ case TokenNameIdentifier:
+ case TokenNameVariable:
+ case TokenNameDOLLAR:
+ Expression lhs = null;
+ boolean rememberedVar = false;
+ if (token == TokenNameIdentifier) {
+ lhs = identifier(true, true);
+ if (lhs != null) {
+ expression = lhs;
+ }
+ } else {
+ lhs = variable(true, true);
+ if (lhs != null) {
+ expression = lhs;
+ }
+ if (lhs != null && lhs instanceof FieldReference
+ && token != TokenNameEQUAL
+ && token != TokenNamePLUS_EQUAL
+ && token != TokenNameMINUS_EQUAL
+ && token != TokenNameMULTIPLY_EQUAL
+ && token != TokenNameDIVIDE_EQUAL
+ && token != TokenNameDOT_EQUAL
+ && token != TokenNameREMAINDER_EQUAL
+ && token != TokenNameAND_EQUAL
+ && token != TokenNameOR_EQUAL
+ && token != TokenNameXOR_EQUAL
+ && token != TokenNameRIGHT_SHIFT_EQUAL
+ && token != TokenNameLEFT_SHIFT_EQUAL) {
+ FieldReference ref = (FieldReference) lhs;
+ if (!containsVariableSet(ref.token)) {
+ if (null == initHandler
+ || initHandler.reportError()) {
+ problemReporter.uninitializedLocalVariable(
+ new String(ref.token), ref.sourceStart,
+ ref.sourceEnd, referenceContext,
+ compilationUnit.compilationResult);
+ }
+ addVariableSet(ref.token);
+ }
+ }
+ }
+ switch (token) {
+ case TokenNameEQUAL:
+ if (lhs != null && lhs instanceof FieldReference) {
+ addVariableSet(((FieldReference) lhs).token);
+ }
+ getNextToken();
+ if (token == TokenNameAND) {
+ getNextToken();
+ if (token == TokenNamenew) {
+ // | variable '=' '&' T_NEW class_name_reference
+ // ctor_arguments
+ getNextToken();
+ SingleTypeReference classRef = class_name_reference();
+ ctor_arguments();
+ if (classRef != null) {
+ if (lhs != null
+ && lhs instanceof FieldReference) {
+ // example:
+ // $var = & new Object();
+ if (fMethodVariables != null) {
+ VariableInfo lhsInfo = new VariableInfo(
+ ((FieldReference) lhs).sourceStart);
+ lhsInfo.reference = classRef;
+ lhsInfo.typeIdentifier = classRef.token;
+ fMethodVariables.put(new String(
+ ((FieldReference) lhs).token),
+ lhsInfo);
+ rememberedVar = true;
+ }
+ }
+ }
+ } else {
+ Expression rhs = variable(false, false);
+ if (rhs != null && rhs instanceof FieldReference
+ && lhs != null
+ && lhs instanceof FieldReference) {
+ // example:
+ // $var = &$ref;
+ if (fMethodVariables != null) {
+ VariableInfo rhsInfo = (VariableInfo) fMethodVariables
+ .get(((FieldReference) rhs).token);
+ if (rhsInfo != null
+ && rhsInfo.reference != null) {
+ VariableInfo lhsInfo = new VariableInfo(
+ ((FieldReference) lhs).sourceStart);
+ lhsInfo.reference = rhsInfo.reference;
+ lhsInfo.typeIdentifier = rhsInfo.typeIdentifier;
+ fMethodVariables.put(new String(
+ ((FieldReference) lhs).token),
+ lhsInfo);
+ rememberedVar = true;
+ }
+ }
+ }
+ }
+ } else {
+ Expression rhs = expr();
+ if (lhs != null && lhs instanceof FieldReference) {
+ if (rhs != null && rhs instanceof FieldReference) {
+ // example:
+ // $var = $ref;
+ if (fMethodVariables != null) {
+ VariableInfo rhsInfo = (VariableInfo) fMethodVariables
+ .get(((FieldReference) rhs).token);
+ if (rhsInfo != null
+ && rhsInfo.reference != null) {
+ VariableInfo lhsInfo = new VariableInfo(
+ ((FieldReference) lhs).sourceStart);
+ lhsInfo.reference = rhsInfo.reference;
+ lhsInfo.typeIdentifier = rhsInfo.typeIdentifier;
+ fMethodVariables.put(new String(
+ ((FieldReference) lhs).token),
+ lhsInfo);
+ rememberedVar = true;
+ }
+ }
+ } else if (rhs != null
+ && rhs instanceof SingleTypeReference) {
+ // example:
+ // $var = new Object();
+ if (fMethodVariables != null) {
+ VariableInfo lhsInfo = new VariableInfo(
+ ((FieldReference) lhs).sourceStart);
+ lhsInfo.reference = (SingleTypeReference) rhs;
+ lhsInfo.typeIdentifier = ((SingleTypeReference) rhs).token;
+ fMethodVariables.put(new String(
+ ((FieldReference) lhs).token),
+ lhsInfo);
+ rememberedVar = true;
+ }
+ }
+ }
+ }
+ if (rememberedVar == false && lhs != null
+ && lhs instanceof FieldReference) {
+ if (fMethodVariables != null) {
+ VariableInfo lhsInfo = new VariableInfo(
+ ((FieldReference) lhs).sourceStart);
+ fMethodVariables.put(new String(
+ ((FieldReference) lhs).token), lhsInfo);
+ }
+ }
+ break;
+ case TokenNamePLUS_EQUAL:
+ case TokenNameMINUS_EQUAL:
+ case TokenNameMULTIPLY_EQUAL:
+ case TokenNameDIVIDE_EQUAL:
+ case TokenNameDOT_EQUAL:
+ case TokenNameREMAINDER_EQUAL:
+ case TokenNameAND_EQUAL:
+ case TokenNameOR_EQUAL:
+ case TokenNameXOR_EQUAL:
+ case TokenNameRIGHT_SHIFT_EQUAL:
+ case TokenNameLEFT_SHIFT_EQUAL:
+ if (lhs != null && lhs instanceof FieldReference) {
+ addVariableSet(((FieldReference) lhs).token);
+ }
+ getNextToken();
+ expr();
+ break;
+ case TokenNamePLUS_PLUS:
+ case TokenNameMINUS_MINUS:
+ getNextToken();
+ break;
+ default:
+ if (!only_variable) {
+ throwSyntaxError("Variable expression not allowed (found token '"
+ + scanner.toStringAction(token) + "').");
+ }
+ if (lhs != null) {
+ expression = lhs;
+ }
+ }
+ break;
+ default:
+ if (token != TokenNameINLINE_HTML) {
+ if (token > TokenNameKEYWORD) {
+ getNextToken();
+ break;
+ } else {
+ // System.out.println(scanner.getCurrentTokenStartPosition());
+ // System.out.println(scanner.getCurrentTokenEndPosition());
+
+ throwSyntaxError("Error in expression (found token '"
+ + scanner.toStringAction(token) + "').");
+ }
+ }
+ return expression;
+ }
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: expr_without_variable() PART 2");
+ }
+ // | expr T_BOOLEAN_OR expr
+ // | expr T_BOOLEAN_AND expr
+ // | expr T_LOGICAL_OR expr
+ // | expr T_LOGICAL_AND expr
+ // | expr T_LOGICAL_XOR expr
+ // | expr '|' expr
+ // | expr '&' expr
+ // | expr '^' expr
+ // | expr '.' expr
+ // | expr '+' expr
+ // | expr '-' expr
+ // | expr '*' expr
+ // | expr '/' expr
+ // | expr '%' expr
+ // | expr T_SL expr
+ // | expr T_SR expr
+ // | expr T_IS_IDENTICAL expr
+ // | expr T_IS_NOT_IDENTICAL expr
+ // | expr T_IS_EQUAL expr
+ // | expr T_IS_NOT_EQUAL expr
+ // | expr '<' expr
+ // | expr T_IS_SMALLER_OR_EQUAL expr
+ // | expr '>' expr
+ // | expr T_IS_GREATER_OR_EQUAL expr
+ while (true) {
+ switch (token) {
+ case TokenNameOR_OR:
+ getNextToken();
+ expression = new OR_OR_Expression(expression, expr(), token);
+ break;
+ case TokenNameAND_AND:
+ getNextToken();
+ expression = new AND_AND_Expression(expression, expr(),
+ token);
+ break;
+ case TokenNameEQUAL_EQUAL:
+ getNextToken();
+ expression = new EqualExpression(expression, expr(), token);
+ break;
+ case TokenNameand:
+ case TokenNameor:
+ case TokenNamexor:
+ case TokenNameAND:
+ case TokenNameOR:
+ case TokenNameXOR:
+ case TokenNameDOT:
+ case TokenNamePLUS:
+ case TokenNameMINUS:
+ case TokenNameMULTIPLY:
+ case TokenNameDIVIDE:
+ case TokenNameREMAINDER:
+ case TokenNameLEFT_SHIFT:
+ case TokenNameRIGHT_SHIFT:
+ case TokenNameEQUAL_EQUAL_EQUAL:
+ case TokenNameNOT_EQUAL_EQUAL:
+ case TokenNameNOT_EQUAL:
+ case TokenNameLESS:
+ case TokenNameLESS_EQUAL:
+ case TokenNameGREATER:
+ case TokenNameGREATER_EQUAL:
+ getNextToken();
+ expression = new BinaryExpression(expression, expr(), token);
+ break;
+ // | expr T_INSTANCEOF class_name_reference
+ // | expr '?' expr ':' expr
+ case TokenNameinstanceof:
+ getNextToken();
+ TypeReference classRef = class_name_reference();
+ if (classRef != null) {
+ expression = new InstanceOfExpression(expression,
+ classRef, OperatorIds.INSTANCEOF);
+ expression.sourceStart = exprSourceStart;
+ expression.sourceEnd = scanner
+ .getCurrentTokenEndPosition();
+ }
+ break;
+ case TokenNameQUESTION:
+ getNextToken();
+ Expression valueIfTrue = expr();
+ if (token != TokenNameCOLON) {
+ throwSyntaxError("':' expected in conditional expression.");
+ }
+ getNextToken();
+ Expression valueIfFalse = expr();
+
+ expression = new ConditionalExpression(expression,
+ valueIfTrue, valueIfFalse);
+ break;
+ default:
+ return expression;
+ }
+ }
+ } catch (SyntaxError e) {
+ // try to find next token after expression with errors:
+ if (token == TokenNameSEMICOLON) {
+ getNextToken();
+ return expression;
+ }
+ if (token == TokenNameRBRACE || token == TokenNameRPAREN
+ || token == TokenNameRBRACKET) {
+ getNextToken();
+ return expression;
+ }
+ throw e;
+ }
+ }
+
+ private SingleTypeReference class_name_reference() {
+ // class_name_reference:
+ // T_STRING
+ // | dynamic_class_name_reference
+ SingleTypeReference ref = null;
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: class_name_reference()");
+ }
+ if (token == TokenNameIdentifier) {
+ ref = new SingleTypeReference(scanner.getCurrentIdentifierSource(),
+ scanner.getCurrentTokenStartPosition());
+ getNextToken();
+ } else {
+ ref = null;
+ dynamic_class_name_reference();
+ }
+ return ref;
+ }
+
+ private void dynamic_class_name_reference() {
+ // dynamic_class_name_reference:
+ // base_variable T_OBJECT_OPERATOR object_property
+ // dynamic_class_name_variable_properties
+ // | base_variable
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: dynamic_class_name_reference()");
+ }
+ base_variable(true);
+ if (token == TokenNameMINUS_GREATER) {
+ getNextToken();
+ object_property();
+ dynamic_class_name_variable_properties();
+ }
+ }
+
+ private void dynamic_class_name_variable_properties() {
+ // dynamic_class_name_variable_properties:
+ // dynamic_class_name_variable_properties
+ // dynamic_class_name_variable_property
+ // | /* empty */
+ if (Scanner.TRACE) {
+ System.out
+ .println("TRACE: dynamic_class_name_variable_properties()");
+ }
+ while (token == TokenNameMINUS_GREATER) {
+ dynamic_class_name_variable_property();
+ }
+ }
+
+ private void dynamic_class_name_variable_property() {
+ // dynamic_class_name_variable_property:
+ // T_OBJECT_OPERATOR object_property
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: dynamic_class_name_variable_property()");
+ }
+ if (token == TokenNameMINUS_GREATER) {
+ getNextToken();
+ object_property();
+ }
+ }
+
+ private void ctor_arguments() {
+ // ctor_arguments:
+ // /* empty */
+ // | '(' function_call_parameter_list ')'
+ if (token == TokenNameLPAREN) {
+ getNextToken();
+ if (token == TokenNameRPAREN) {
+ getNextToken();
+ return;
+ }
+ non_empty_function_call_parameter_list();
+ if (token != TokenNameRPAREN) {
+ throwSyntaxError("')' expected in ctor_arguments.");
+ }
+ getNextToken();
+ }
+ }
+
+ private void assignment_list() {
+ // assignment_list:
+ // assignment_list ',' assignment_list_element
+ // | assignment_list_element
+ while (true) {
+ assignment_list_element();
+ if (token != TokenNameCOMMA) {
+ break;
+ }
+ getNextToken();
+ }
+ }
+
+ private void assignment_list_element() {
+ // assignment_list_element:
+ // variable
+ // | T_LIST '(' assignment_list ')'
+ // | /* empty */
+ if (token == TokenNameVariable) {
+ variable(true, false);
+ } else if (token == TokenNameDOLLAR) {
+ variable(false, false);
+ } else if (token == TokenNameIdentifier) {
+ identifier(true, true);
+ } else {
+ if (token == TokenNamelist) {
+ getNextToken();
+ if (token == TokenNameLPAREN) {
+ getNextToken();
+ assignment_list();
+ if (token != TokenNameRPAREN) {
+ throwSyntaxError("')' expected after 'list' keyword.");
+ }
+ getNextToken();
+ } else {
+ throwSyntaxError("'(' expected after 'list' keyword.");
+ }
+ }
+ }
+ }
+
+ private void array_pair_list() {
+ // array_pair_list:
+ // /* empty */
+ // | non_empty_array_pair_list possible_comma
+ non_empty_array_pair_list();
+ if (token == TokenNameCOMMA) {
+ getNextToken();
+ }
+ }
+
+ private void non_empty_array_pair_list() {
+ // non_empty_array_pair_list:
+ // non_empty_array_pair_list ',' expr T_DOUBLE_ARROW expr
+ // | non_empty_array_pair_list ',' expr
+ // | expr T_DOUBLE_ARROW expr
+ // | expr
+ // | non_empty_array_pair_list ',' expr T_DOUBLE_ARROW '&' w_variable
+ // | non_empty_array_pair_list ',' '&' w_variable
+ // | expr T_DOUBLE_ARROW '&' w_variable
+ // | '&' w_variable
+ while (true) {
+ if (token == TokenNameAND) {
+ getNextToken();
+ variable(true, false);
+ } else {
+ expr();
+ if (token == TokenNameAND) {
+ getNextToken();
+ variable(true, false);
+ } else if (token == TokenNameEQUAL_GREATER) {
+ getNextToken();
+ if (token == TokenNameAND) {
+ getNextToken();
+ variable(true, false);
+ } else {
+ expr();
+ }
+ }
+ }
+ if (token != TokenNameCOMMA) {
+ return;
+ }
+ getNextToken();
+ if (token == TokenNameRPAREN) {
+ return;
+ }
+ }
+ }
+
+ // private void variableList() {
+ // do {
+ // variable();
+ // if (token == TokenNameCOMMA) {
+ // getNextToken();
+ // } else {
+ // break;
+ // }
+ // } while (true);
+ // }
+ private Expression variable_without_objects(boolean lefthandside,
+ boolean ignoreVar) {
+ // variable_without_objects:
+ // reference_variable
+ // | simple_indirect_reference reference_variable
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: variable_without_objects()");
+ }
+ while (token == TokenNameDOLLAR) {
+ getNextToken();
+ }
+ return reference_variable(lefthandside, ignoreVar);
+ }
+
+ private Expression function_call(boolean lefthandside, boolean ignoreVar) {
+ // function_call:
+ // T_STRING '(' function_call_parameter_list ')'
+ // | class_constant '(' function_call_parameter_list ')'
+ // | static_member '(' function_call_parameter_list ')'
+ // | variable_without_objects '(' function_call_parameter_list ')'
+ char[] defineName = null;
+ char[] ident = null;
+ int startPos = 0;
+ int endPos = 0;
+ Expression ref = null;
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: function_call()");
+ }
+ if (token == TokenNameIdentifier) {
+ ident = scanner.getCurrentIdentifierSource();
+ defineName = ident;
+ startPos = scanner.getCurrentTokenStartPosition();
+ endPos = scanner.getCurrentTokenEndPosition();
+ getNextToken();
+ switch (token) {
+ case TokenNamePAAMAYIM_NEKUDOTAYIM:
+ // static member:
+ defineName = null;
+ getNextToken();
+ if (token == TokenNameIdentifier) {
+ // class _constant
+ getNextToken();
+ } else {
+ // static member:
+ variable_without_objects(true, false);
+ }
+ break;
+ }
+ } else {
+ ref = variable_without_objects(lefthandside, ignoreVar);
+ }
+ if (token != TokenNameLPAREN) {
+ if (defineName != null) {
+ // does this identifier contain only uppercase characters?
+ if (defineName.length == 3) {
+ if (defineName[0] == 'd' && defineName[1] == 'i'
+ && defineName[2] == 'e') {
+ defineName = null;
+ }
+ } else if (defineName.length == 4) {
+ if (defineName[0] == 't' && defineName[1] == 'r'
+ && defineName[2] == 'u' && defineName[3] == 'e') {
+ defineName = null;
+ } else if (defineName[0] == 'n' && defineName[1] == 'u'
+ && defineName[2] == 'l' && defineName[3] == 'l') {
+ defineName = null;
+ }
+ } else if (defineName.length == 5) {
+ if (defineName[0] == 'f' && defineName[1] == 'a'
+ && defineName[2] == 'l' && defineName[3] == 's'
+ && defineName[4] == 'e') {
+ defineName = null;
+ }
+ }
+ if (defineName != null) {
+ for (int i = 0; i < defineName.length; i++) {
+ if (Character.isLowerCase(defineName[i])) {
+ problemReporter.phpUppercaseIdentifierWarning(
+ startPos, endPos, referenceContext,
+ compilationUnit.compilationResult);
+ break;
+ }
+ }
+ }
+ }
+ } else {
+ getNextToken();
+ if (token == TokenNameRPAREN) {
+ getNextToken();
+ return ref;
+ }
+ non_empty_function_call_parameter_list();
+ if (token != TokenNameRPAREN) {
+ String functionName;
+ if (ident == null) {
+ functionName = new String(" ");
+ } else {
+ functionName = new String(ident);
+ }
+ throwSyntaxError("')' expected in function call ("
+ + functionName + ").");
+ }
+ getNextToken();
+ }
+ return ref;
+ }
+
+ private void non_empty_function_call_parameter_list() {
+ this.non_empty_function_call_parameter_list(null);
+ }
+
+ // private void function_call_parameter_list() {
+ // function_call_parameter_list:
+ // non_empty_function_call_parameter_list { $$ = $1; }
+ // | /* empty */
+ // }
+ private void non_empty_function_call_parameter_list(String functionName) {
+ // non_empty_function_call_parameter_list:
+ // expr_without_variable
+ // | variable
+ // | '&' w_variable
+ // | non_empty_function_call_parameter_list ',' expr_without_variable
+ // | non_empty_function_call_parameter_list ',' variable
+ // | non_empty_function_call_parameter_list ',' '&' w_variable
+ if (Scanner.TRACE) {
+ System.out
+ .println("TRACE: non_empty_function_call_parameter_list()");
+ }
+ UninitializedVariableHandler initHandler = new UninitializedVariableHandler();
+ initHandler.setFunctionName(functionName);
+ while (true) {
+ initHandler.incrementArgumentCount();
+ if (token == TokenNameAND) {
+ getNextToken();
+ w_variable(true);
+ } else {
+ // if (token == TokenNameIdentifier || token ==
+ // TokenNameVariable
+ // || token == TokenNameDOLLAR) {
+ // variable();
+ // } else {
+ expr_without_variable(true, initHandler);
+ // }
+ }
+ if (token != TokenNameCOMMA) {
+ break;
+ }
+ getNextToken();
+ }
+ }
+
+ private void fully_qualified_class_name() {
+ if (token == TokenNameIdentifier) {
+ getNextToken();
+ } else {
+ throwSyntaxError("Class name expected.");
+ }
+ }
+
+ private void static_member() {
+ // static_member:
+ // fully_qualified_class_name T_PAAMAYIM_NEKUDOTAYIM
+ // variable_without_objects
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: static_member()");
+ }
+ fully_qualified_class_name();
+ if (token != TokenNamePAAMAYIM_NEKUDOTAYIM) {
+ throwSyntaxError("'::' expected after class name (static_member).");
+ }
+ getNextToken();
+ variable_without_objects(false, false);
+ }
+
+ private Expression base_variable_with_function_calls(boolean lefthandside,
+ boolean ignoreVar) {
+ // base_variable_with_function_calls:
+ // base_variable
+ // | function_call
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: base_variable_with_function_calls()");
+ }
+ return function_call(lefthandside, ignoreVar);
+ }
+
+ private Expression base_variable(boolean lefthandside) {
+ // base_variable:
+ // reference_variable
+ // | simple_indirect_reference reference_variable
+ // | static_member
+ Expression ref = null;
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: base_variable()");
+ }
+ if (token == TokenNameIdentifier) {
+ static_member();
+ } else {
+ while (token == TokenNameDOLLAR) {
+ getNextToken();
+ }
+ reference_variable(lefthandside, false);
+ }
+ return ref;
+ }
+
+ // private void simple_indirect_reference() {
+ // // simple_indirect_reference:
+ // // '$'
+ // //| simple_indirect_reference '$'
+ // }
+ private Expression reference_variable(boolean lefthandside,
+ boolean ignoreVar) {
+ // reference_variable:
+ // reference_variable '[' dim_offset ']'
+ // | reference_variable '{' expr '}'
+ // | compound_variable
+ Expression ref = null;
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: reference_variable()");
+ }
+ ref = compound_variable(lefthandside, ignoreVar);
+ while (true) {
+ if (token == TokenNameLBRACE) {
+ ref = null;
+ getNextToken();
+ expr();
+ if (token != TokenNameRBRACE) {
+ throwSyntaxError("'}' expected in reference variable.");
+ }
+ getNextToken();
+ } else if (token == TokenNameLBRACKET) {
+ // To remove "ref = null;" here, is probably better than the
+ // patch
+ // commented in #1368081 - axelcl
+ getNextToken();
+ if (token != TokenNameRBRACKET) {
+ expr();
+ // dim_offset();
+ if (token != TokenNameRBRACKET) {
+ throwSyntaxError("']' expected in reference variable.");
+ }
+ }
+ getNextToken();
+ } else {
+ break;
+ }
+ }
+ return ref;
+ }
+
+ private Expression compound_variable(boolean lefthandside, boolean ignoreVar) {
+ // compound_variable:
+ // T_VARIABLE
+ // | '$' '{' expr '}'
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: compound_variable()");
+ }
+ if (token == TokenNameVariable) {
+ if (!lefthandside) {
+ if (!containsVariableSet()) {
+ // reportSyntaxError("The local variable " + new
+ // String(scanner.getCurrentIdentifierSource())
+ // + " may not have been initialized");
+ problemReporter.uninitializedLocalVariable(new String(
+ scanner.getCurrentIdentifierSource()), scanner
+ .getCurrentTokenStartPosition(), scanner
+ .getCurrentTokenEndPosition(), referenceContext,
+ compilationUnit.compilationResult);
+ }
+ } else {
+ if (!ignoreVar) {
+ addVariableSet();
+ }
+ }
+ FieldReference ref = new FieldReference(scanner
+ .getCurrentIdentifierSource(), scanner
+ .getCurrentTokenStartPosition());
+ getNextToken();
+ return ref;
+ } else {
+ // because of simple_indirect_reference
+ while (token == TokenNameDOLLAR) {
+ getNextToken();
+ }
+ if (token != TokenNameLBRACE) {
+ reportSyntaxError("'{' expected after compound variable token '$'.");
+ return null;
+ }
+ getNextToken();
+ expr();
+ if (token != TokenNameRBRACE) {
+ throwSyntaxError("'}' expected after compound variable token '$'.");
+ }
+ getNextToken();
+ }
+ return null;
+ } // private void dim_offset() { // // dim_offset: // // /* empty */
+
+ // // | expr
+ // expr();
+ // }
+ private void object_property() {
+ // object_property:
+ // object_dim_list
+ // | variable_without_objects
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: object_property()");
+ }
+ if (token == TokenNameVariable || token == TokenNameDOLLAR) {
+ variable_without_objects(false, false);
+ } else {
+ object_dim_list();
+ }
+ }
+
+ private void object_dim_list() {
+ // object_dim_list:
+ // object_dim_list '[' dim_offset ']'
+ // | object_dim_list '{' expr '}'
+ // | variable_name
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: object_dim_list()");
+ }
+ variable_name();
+ while (true) {
+ if (token == TokenNameLBRACE) {
+ getNextToken();
+ expr();
+ if (token != TokenNameRBRACE) {
+ throwSyntaxError("'}' expected in object_dim_list.");
+ }
+ getNextToken();
+ } else if (token == TokenNameLBRACKET) {
+ getNextToken();
+ if (token == TokenNameRBRACKET) {
+ getNextToken();
+ continue;
+ }
+ expr();
+ if (token != TokenNameRBRACKET) {
+ throwSyntaxError("']' expected in object_dim_list.");
+ }
+ getNextToken();
+ } else {
+ break;
+ }
+ }
+ }
+
+ private void variable_name() {
+ // variable_name:
+ // T_STRING
+ // | '{' expr '}'
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: variable_name()");
+ }
+ if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
+ if (token > TokenNameKEYWORD) {
+ // TODO show a warning "Keyword used as variable" ?
+ }
+ getNextToken();
+ } else {
+ if (token != TokenNameLBRACE) {
+ throwSyntaxError("'{' expected in variable name.");
+ }
+ getNextToken();
+ expr();
+ if (token != TokenNameRBRACE) {
+ throwSyntaxError("'}' expected in variable name.");
+ }
+ getNextToken();
+ }
+ }
+
+ private void r_variable() {
+ variable(false, false);
+ }
+
+ private void w_variable(boolean lefthandside) {
+ variable(lefthandside, false);
+ }
+
+ private void rw_variable() {
+ variable(false, false);
+ }
+
+ private Expression variable(boolean lefthandside, boolean ignoreVar) {
+ // variable:
+ // base_variable_with_function_calls T_OBJECT_OPERATOR
+ // object_property method_or_not variable_properties
+ // | base_variable_with_function_calls
+ Expression ref = base_variable_with_function_calls(lefthandside,
+ ignoreVar);
+ if (token == TokenNameMINUS_GREATER) {
+ ref = null;
+ getNextToken();
+ object_property();
+ method_or_not();
+ variable_properties();
+ }
+ return ref;
+ }
+
+ private void variable_properties() {
+ // variable_properties:
+ // variable_properties variable_property
+ // | /* empty */
+ while (token == TokenNameMINUS_GREATER) {
+ variable_property();
+ }
+ }
+
+ private void variable_property() {
+ // variable_property:
+ // T_OBJECT_OPERATOR object_property method_or_not
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: variable_property()");
+ }
+ if (token == TokenNameMINUS_GREATER) {
+ getNextToken();
+ object_property();
+ method_or_not();
+ } else {
+ throwSyntaxError("'->' expected in variable_property.");
+ }
+ }
+
+ private Expression identifier(boolean lefthandside, boolean ignoreVar) {
+ // variable:
+ // base_variable_with_function_calls T_OBJECT_OPERATOR
+ // object_property method_or_not variable_properties
+ // | base_variable_with_function_calls
+
+ // Expression ref = function_call(lefthandside, ignoreVar);
+
+ // function_call:
+ // T_STRING '(' function_call_parameter_list ')'
+ // | class_constant '(' function_call_parameter_list ')'
+ // | static_member '(' function_call_parameter_list ')'
+ // | variable_without_objects '(' function_call_parameter_list ')'
+ char[] defineName = null;
+ char[] ident = null;
+ int startPos = 0;
+ int endPos = 0;
+ Expression ref = null;
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: function_call()");
+ }
+ if (token == TokenNameIdentifier) {
+ ident = scanner.getCurrentIdentifierSource();
+ defineName = ident;
+ startPos = scanner.getCurrentTokenStartPosition();
+ endPos = scanner.getCurrentTokenEndPosition();
+ getNextToken();
+
+ if (token == TokenNameEQUAL || token == TokenNamePLUS_EQUAL
+ || token == TokenNameMINUS_EQUAL
+ || token == TokenNameMULTIPLY_EQUAL
+ || token == TokenNameDIVIDE_EQUAL
+ || token == TokenNameDOT_EQUAL
+ || token == TokenNameREMAINDER_EQUAL
+ || token == TokenNameAND_EQUAL
+ || token == TokenNameOR_EQUAL
+ || token == TokenNameXOR_EQUAL
+ || token == TokenNameRIGHT_SHIFT_EQUAL
+ || token == TokenNameLEFT_SHIFT_EQUAL) {
+ String error = "Assignment operator '"
+ + scanner.toStringAction(token)
+ + "' not allowed after identifier '"
+ + new String(ident)
+ + "' (use 'define(...)' to define constants).";
+ reportSyntaxError(error);
+ }
+
+ switch (token) {
+ case TokenNamePAAMAYIM_NEKUDOTAYIM:
+ // static member:
+ defineName = null;
+ getNextToken();
+ if (token == TokenNameIdentifier) {
+ // class _constant
+ getNextToken();
+ } else {
+ // static member:
+ variable_without_objects(true, false);
+ }
+ break;
+ }
+ } else {
+ ref = variable_without_objects(lefthandside, ignoreVar);
+ }
+ if (token != TokenNameLPAREN) {
+ if (defineName != null) {
+ // does this identifier contain only uppercase characters?
+ if (defineName.length == 3) {
+ if (defineName[0] == 'd' && defineName[1] == 'i'
+ && defineName[2] == 'e') {
+ defineName = null;
+ }
+ } else if (defineName.length == 4) {
+ if (defineName[0] == 't' && defineName[1] == 'r'
+ && defineName[2] == 'u' && defineName[3] == 'e') {
+ defineName = null;
+ } else if (defineName[0] == 'n' && defineName[1] == 'u'
+ && defineName[2] == 'l' && defineName[3] == 'l') {
+ defineName = null;
+ }
+ } else if (defineName.length == 5) {
+ if (defineName[0] == 'f' && defineName[1] == 'a'
+ && defineName[2] == 'l' && defineName[3] == 's'
+ && defineName[4] == 'e') {
+ defineName = null;
+ }
+ }
+ if (defineName != null) {
+ for (int i = 0; i < defineName.length; i++) {
+ if (Character.isLowerCase(defineName[i])) {
+ problemReporter.phpUppercaseIdentifierWarning(
+ startPos, endPos, referenceContext,
+ compilationUnit.compilationResult);
+ break;
+ }
+ }
+ }
+ }
+ // TODO is this ok ?
+ // return ref;
+ // throwSyntaxError("'(' expected in function call.");
+ } else {
+ getNextToken();
+
+ if (token == TokenNameRPAREN) {
+ getNextToken();
+ ref = null;
+ } else {
+ String functionName;
+ if (ident == null) {
+ functionName = new String(" ");
+ } else {
+ functionName = new String(ident);
+ }
+ non_empty_function_call_parameter_list(functionName);
+ if (token != TokenNameRPAREN) {
+ throwSyntaxError("')' expected in function call ("
+ + functionName + ").");
+ }
+ getNextToken();
+ }
+ }
+ if (token == TokenNameMINUS_GREATER) {
+ ref = null;
+ getNextToken();
+ object_property();
+ method_or_not();
+ variable_properties();
+ }
+ return ref;
+ }
+
+ private void method_or_not() {
+ // method_or_not:
+ // '(' function_call_parameter_list ')'
+ // | /* empty */
+ if (Scanner.TRACE) {
+ System.out.println("TRACE: method_or_not()");
+ }
+ if (token == TokenNameLPAREN) {
+ getNextToken();
+ if (token == TokenNameRPAREN) {
+ getNextToken();
+ return;
+ }
+ non_empty_function_call_parameter_list();
+ if (token != TokenNameRPAREN) {
+ throwSyntaxError("')' expected in method_or_not.");
+ }
+ getNextToken();
+ }
+ }
+
+ private void exit_expr() {
+ // /* empty */
+ // | '(' ')'
+ // | '(' expr ')'
+ if (token != TokenNameLPAREN) {
+ return;
+ }
+ getNextToken();
+ if (token == TokenNameRPAREN) {
+ getNextToken();
+ return;
+ }
+ expr();
+ if (token != TokenNameRPAREN) {
+ throwSyntaxError("')' expected after keyword 'exit'");
+ }
+ getNextToken();
+ }
+
+ // private void encaps_list() {
+ // // encaps_list encaps_var
+ // // | encaps_list T_STRING
+ // // | encaps_list T_NUM_STRING
+ // // | encaps_list T_ENCAPSED_AND_WHITESPACE
+ // // | encaps_list T_CHARACTER
+ // // | encaps_list T_BAD_CHARACTER
+ // // | encaps_list '['
+ // // | encaps_list ']'
+ // // | encaps_list '{'
+ // // | encaps_list '}'
+ // // | encaps_list T_OBJECT_OPERATOR
+ // // | /* empty */
+ // while (true) {
+ // switch (token) {
+ // case TokenNameSTRING:
+ // getNextToken();
+ // break;
+ // case TokenNameLBRACE:
+ // // scanner.encapsedStringStack.pop();
+ // getNextToken();
+ // break;
+ // case TokenNameRBRACE:
+ // // scanner.encapsedStringStack.pop();
+ // getNextToken();
+ // break;
+ // case TokenNameLBRACKET:
+ // // scanner.encapsedStringStack.pop();
+ // getNextToken();
+ // break;
+ // case TokenNameRBRACKET:
+ // // scanner.encapsedStringStack.pop();
+ // getNextToken();
+ // break;
+ // case TokenNameMINUS_GREATER:
+ // // scanner.encapsedStringStack.pop();
+ // getNextToken();
+ // break;
+ // case TokenNameVariable:
+ // case TokenNameDOLLAR_LBRACE:
+ // case TokenNameLBRACE_DOLLAR:
+ // encaps_var();
+ // break;
+ // default:
+ // char encapsedChar = ((Character)
+ // scanner.encapsedStringStack.peek()).charValue();
+ // if (encapsedChar == '$') {
+ // scanner.encapsedStringStack.pop();
+ // encapsedChar = ((Character)
+ // scanner.encapsedStringStack.peek()).charValue();
+ // switch (encapsedChar) {
+ // case '`':
+ // if (token == TokenNameEncapsedString0) {
+ // return;
+ // }
+ // token = TokenNameSTRING;
+ // continue;
+ // case '\'':
+ // if (token == TokenNameEncapsedString1) {
+ // return;
+ // }
+ // token = TokenNameSTRING;
+ // continue;
+ // case '"':
+ // if (token == TokenNameEncapsedString2) {
+ // return;
+ // }
+ // token = TokenNameSTRING;
+ // continue;
+ // }
+ // }
+ // return;
+ // }
+ // }
+ // }
+
+ // private void encaps_var() {
+ // // T_VARIABLE
+ // // | T_VARIABLE '[' encaps_var_offset ']'
+ // // | T_VARIABLE T_OBJECT_OPERATOR T_STRING
+ // // | T_DOLLAR_OPEN_CURLY_BRACES expr '}'
+ // // | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}'
+ // // | T_CURLY_OPEN variable '}'
+ // switch (token) {
+ // case TokenNameVariable:
+ // getNextToken();
+ // if (token == TokenNameLBRACKET) {
+ // getNextToken();
+ // expr(); //encaps_var_offset();
+ // if (token != TokenNameRBRACKET) {
+ // throwSyntaxError("']' expected after variable.");
+ // }
+ // // scanner.encapsedStringStack.pop();
+ // getNextToken();
+ // // }
+ // } else if (token == TokenNameMINUS_GREATER) {
+ // getNextToken();
+ // if (token != TokenNameIdentifier) {
+ // throwSyntaxError("Identifier expected after '->'.");
+ // }
+ // // scanner.encapsedStringStack.pop();
+ // getNextToken();
+ // }
+ // // else {
+ // // // scanner.encapsedStringStack.pop();
+ // // int tempToken = TokenNameSTRING;
+ // // if (!scanner.encapsedStringStack.isEmpty()
+ // // && (token == TokenNameEncapsedString0
+ // // || token == TokenNameEncapsedString1
+ // // || token == TokenNameEncapsedString2 || token ==
+ // // TokenNameERROR)) {
+ // // char encapsedChar = ((Character)
+ // // scanner.encapsedStringStack.peek())
+ // // .charValue();
+ // // switch (token) {
+ // // case TokenNameEncapsedString0 :
+ // // if (encapsedChar == '`') {
+ // // tempToken = TokenNameEncapsedString0;
+ // // }
+ // // break;
+ // // case TokenNameEncapsedString1 :
+ // // if (encapsedChar == '\'') {
+ // // tempToken = TokenNameEncapsedString1;
+ // // }
+ // // break;
+ // // case TokenNameEncapsedString2 :
+ // // if (encapsedChar == '"') {
+ // // tempToken = TokenNameEncapsedString2;
+ // // }
+ // // break;
+ // // case TokenNameERROR :
+ // // if (scanner.source[scanner.currentPosition - 1] == '\\') {
+ // // scanner.currentPosition--;
+ // // getNextToken();
+ // // }
+ // // break;
+ // // }
+ // // }
+ // // token = tempToken;
+ // // }
+ // break;
+ // case TokenNameDOLLAR_LBRACE:
+ // getNextToken();
+ // if (token == TokenNameDOLLAR_LBRACE) {
+ // encaps_var();
+ // } else if (token == TokenNameIdentifier) {
+ // getNextToken();
+ // if (token == TokenNameLBRACKET) {
+ // getNextToken();
+ // // if (token == TokenNameRBRACKET) {
+ // // getNextToken();
+ // // } else {
+ // expr();
+ // if (token != TokenNameRBRACKET) {
+ // throwSyntaxError("']' expected after '${'.");
+ // }
+ // getNextToken();
+ // // }
+ // }
+ // } else {
+ // expr();
+ // }
+ // if (token != TokenNameRBRACE) {
+ // throwSyntaxError("'}' expected.");
+ // }
+ // getNextToken();
+ // break;
+ // case TokenNameLBRACE_DOLLAR:
+ // getNextToken();
+ // if (token == TokenNameLBRACE_DOLLAR) {
+ // encaps_var();
+ // } else if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
+ // getNextToken();
+ // if (token == TokenNameLBRACKET) {
+ // getNextToken();
+ // // if (token == TokenNameRBRACKET) {
+ // // getNextToken();
+ // // } else {
+ // expr();
+ // if (token != TokenNameRBRACKET) {
+ // throwSyntaxError("']' expected.");
+ // }
+ // getNextToken();
+ // // }
+ // } else if (token == TokenNameMINUS_GREATER) {
+ // getNextToken();
+ // if (token != TokenNameIdentifier && token != TokenNameVariable) {
+ // throwSyntaxError("String or Variable token expected.");
+ // }
+ // getNextToken();
+ // if (token == TokenNameLBRACKET) {
+ // getNextToken();
+ // // if (token == TokenNameRBRACKET) {
+ // // getNextToken();
+ // // } else {
+ // expr();
+ // if (token != TokenNameRBRACKET) {
+ // throwSyntaxError("']' expected after '${'.");
+ // }
+ // getNextToken();
+ // // }
+ // }
+ // }
+ // // if (token != TokenNameRBRACE) {
+ // // throwSyntaxError("'}' expected after '{$'.");
+ // // }
+ // // // scanner.encapsedStringStack.pop();
+ // // getNextToken();
+ // } else {
+ // expr();
+ // if (token != TokenNameRBRACE) {
+ // throwSyntaxError("'}' expected.");
+ // }
+ // // scanner.encapsedStringStack.pop();
+ // getNextToken();
+ // }
+ // break;
+ // }
+ // }
+
+ // private void encaps_var_offset() {
+ // // T_STRING
+ // // | T_NUM_STRING
+ // // | T_VARIABLE
+ // switch (token) {
+ // case TokenNameSTRING:
+ // getNextToken();
+ // break;
+ // case TokenNameIntegerLiteral:
+ // getNextToken();
+ // break;
+ // case TokenNameVariable:
+ // getNextToken();
+ // break;
+ // case TokenNameIdentifier:
+ // getNextToken();
+ // break;
+ // default:
+ // throwSyntaxError("Variable or String token expected.");
+ // break;
+ // }
+ // }
+
+ private void internal_functions_in_yacc() {
+ // int start = 0;
+ switch (token) {
+ // case TokenNameisset:
+ // // T_ISSET '(' isset_variables ')'
+ // getNextToken();
+ // if (token != TokenNameLPAREN) {
+ // throwSyntaxError("'(' expected after keyword 'isset'");
+ // }
+ // getNextToken();
+ // isset_variables();
+ // if (token != TokenNameRPAREN) {
+ // throwSyntaxError("')' expected after keyword 'isset'");
+ // }
+ // getNextToken();
+ // break;
+ // case TokenNameempty:
+ // // T_EMPTY '(' variable ')'
+ // getNextToken();
+ // if (token != TokenNameLPAREN) {
+ // throwSyntaxError("'(' expected after keyword 'empty'");
+ // }
+ // getNextToken();
+ // variable(false);
+ // if (token != TokenNameRPAREN) {
+ // throwSyntaxError("')' expected after keyword 'empty'");
+ // }
+ // getNextToken();
+ // break;
+ case TokenNameinclude:
+ // T_INCLUDE expr
+ checkFileName(token);
+ break;
+ case TokenNameinclude_once:
+ // T_INCLUDE_ONCE expr
+ checkFileName(token);
+ break;
+ case TokenNameeval:
+ // T_EVAL '(' expr ')'
+ getNextToken();
+ if (token != TokenNameLPAREN) {
+ throwSyntaxError("'(' expected after keyword 'eval'");
+ }
+ getNextToken();
+ expr();
+ if (token != TokenNameRPAREN) {
+ throwSyntaxError("')' expected after keyword 'eval'");
+ }
+ getNextToken();
+ break;
+ case TokenNamerequire:
+ // T_REQUIRE expr
+ checkFileName(token);
+ break;
+ case TokenNamerequire_once:
+ // T_REQUIRE_ONCE expr
+ checkFileName(token);
+ break;
+ }
+ }
+
+ /**
+ * Parse and check the include file name
+ *
+ * @param includeToken
+ */
+ private void checkFileName(int includeToken) {
+ // <include-token> expr
+ int start = scanner.getCurrentTokenStartPosition();
+ boolean hasLPAREN = false;
+ getNextToken();
+ if (token == TokenNameLPAREN) {
+ hasLPAREN = true;
+ getNextToken();
+ }
+ Expression expression = expr();
+ if (hasLPAREN) {
+ if (token == TokenNameRPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("')' expected for keyword '"
+ + scanner.toStringAction(includeToken) + "'");
+ }
+ }
+ char[] currTokenSource = scanner.getCurrentTokenSource(start);
+ IFile file = null;
+ if (scanner.compilationUnit != null) {
+ IResource resource = scanner.compilationUnit.getResource();
+ if (resource != null && resource instanceof IFile) {
+ file = (IFile) resource;
+ }
+ }
+ char[][] tokens;
+ tokens = new char[1][];
+ tokens[0] = currTokenSource;
+
+ ImportReference impt = new ImportReference(tokens, currTokenSource,
+ start, scanner.getCurrentTokenEndPosition(), false);
+ impt.declarationSourceEnd = impt.sourceEnd;
+ impt.declarationEnd = impt.declarationSourceEnd;
+ // endPosition is just before the ;
+ impt.declarationSourceStart = start;
+ includesList.add(impt);
+
+ if (expression instanceof StringLiteral) {
+ StringLiteral literal = (StringLiteral) expression;
+ char[] includeName = literal.source();
+ if (includeName.length == 0) {
+ reportSyntaxError("Empty filename after keyword '"
+ + scanner.toStringAction(includeToken) + "'",
+ literal.sourceStart, literal.sourceStart + 1);
+ }
+ String includeNameString = new String(includeName);
+ if (literal instanceof StringLiteralDQ) {
+ if (includeNameString.indexOf('$') >= 0) {
+ // assuming that the filename contains a variable => no
+ // filename check
+ return;
+ }
+ }
+ if (includeNameString.startsWith("http://")) {
+ // assuming external include location
+ return;
+ }
+ if (file != null) {
+ // check the filename:
+ // System.out.println(new
+ // String(compilationUnit.getFileName())+" - "+
+ // expression.toStringExpression());
+ IProject project = file.getProject();
+ if (project != null) {
+ IPath path = PHPFileUtil.determineFilePath(
+ includeNameString, file, project);
+
+ if (path == null) {
+ // SyntaxError: "File: << >> doesn't exist in project."
+ String[] args = { expression.toStringExpression(),
+ project.getLocation().toString() };
+ problemReporter.phpIncludeNotExistWarning(args,
+ literal.sourceStart, literal.sourceEnd,
+ referenceContext,
+ compilationUnit.compilationResult);
+ } else {
+ try {
+ String filePath = path.toString();
+ String ext = file.getRawLocation()
+ .getFileExtension();
+ int fileExtensionLength = ext == null ? 0 : ext
+ .length() + 1;
+
+ IFile f = PHPFileUtil.createFile(path, project);
+
+ impt.tokens = CharOperation.splitOn('/', filePath
+ .toCharArray(), 0, filePath.length()
+ - fileExtensionLength);
+ impt.setFile(f);
+ } catch (Exception e) {
+ // the file is outside of the workspace
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private void isset_variables() {
+ // variable
+ // | isset_variables ','
+ if (token == TokenNameRPAREN) {
+ throwSyntaxError("Variable expected after keyword 'isset'");
+ }
+ while (true) {
+ variable(true, false);
+ if (token == TokenNameCOMMA) {
+ getNextToken();
+ } else {
+ break;
+ }
+ }
+ }
+
+ private boolean common_scalar() {
+ // common_scalar:
+ // T_LNUMBER
+ // | T_DNUMBER
+ // | T_CONSTANT_ENCAPSED_STRING
+ // | T_LINE
+ // | T_FILE
+ // | T_CLASS_C
+ // | T_METHOD_C
+ // | T_FUNC_C
+ switch (token) {
+ case TokenNameIntegerLiteral:
+ getNextToken();
+ return true;
+ case TokenNameDoubleLiteral:
+ getNextToken();
+ return true;
+ case TokenNameStringDoubleQuote:
+ getNextToken();
+ return true;
+ case TokenNameStringSingleQuote:
+ getNextToken();
+ return true;
+ case TokenNameStringInterpolated:
+ getNextToken();
+ return true;
+ case TokenNameFILE:
+ getNextToken();
+ return true;
+ case TokenNameLINE:
+ getNextToken();
+ return true;
+ case TokenNameCLASS_C:
+ getNextToken();
+ return true;
+ case TokenNameMETHOD_C:
+ getNextToken();
+ return true;
+ case TokenNameFUNC_C:
+ getNextToken();
+ return true;
+ }
+ return false;
+ }
+
+ private void scalar() {
+ // scalar:
+ // T_STRING
+ // | T_STRING_VARNAME
+ // | class_constant
+ // | common_scalar
+ // | '"' encaps_list '"'
+ // | '\'' encaps_list '\''
+ // | T_START_HEREDOC encaps_list T_END_HEREDOC
+ throwSyntaxError("Not yet implemented (scalar).");
+ }
+
+ private void static_scalar() {
+ // static_scalar: /* compile-time evaluated scalars */
+ // common_scalar
+ // | T_STRING
+ // | '+' static_scalar
+ // | '-' static_scalar
+ // | T_ARRAY '(' static_array_pair_list ')'
+ // | static_class_constant
+ if (common_scalar()) {
+ return;
+ }
+ switch (token) {
+ case TokenNameIdentifier:
+ getNextToken();
+ // static_class_constant:
+ // T_STRING T_PAAMAYIM_NEKUDOTAYIM T_STRING
+ if (token == TokenNamePAAMAYIM_NEKUDOTAYIM) {
+ getNextToken();
+ if (token == TokenNameIdentifier) {
+ getNextToken();
+ } else {
+ throwSyntaxError("Identifier expected after '::' operator.");
+ }
+ }
+ break;
+ case TokenNameEncapsedString0:
+ try {
+ scanner.currentCharacter = scanner.source[scanner.currentPosition++];
+ while (scanner.currentCharacter != '`') {
+ if (scanner.currentCharacter == '\\') {
+ scanner.currentPosition++;
+ }
+ scanner.currentCharacter = scanner.source[scanner.currentPosition++];
+ }
+ getNextToken();
+ } catch (IndexOutOfBoundsException e) {
+ throwSyntaxError("'`' expected at end of static string.");
+ }
+ break;
+ // case TokenNameEncapsedString1:
+ // try {
+ // scanner.currentCharacter = scanner.source[scanner.currentPosition++];
+ // while (scanner.currentCharacter != '\'') {
+ // if (scanner.currentCharacter == '\\') {
+ // scanner.currentPosition++;
+ // }
+ // scanner.currentCharacter = scanner.source[scanner.currentPosition++];
+ // }
+ // getNextToken();
+ // } catch (IndexOutOfBoundsException e) {
+ // throwSyntaxError("'\'' expected at end of static string.");
+ // }
+ // break;
+ // case TokenNameEncapsedString2:
+ // try {
+ // scanner.currentCharacter = scanner.source[scanner.currentPosition++];
+ // while (scanner.currentCharacter != '"') {
+ // if (scanner.currentCharacter == '\\') {
+ // scanner.currentPosition++;
+ // }
+ // scanner.currentCharacter = scanner.source[scanner.currentPosition++];
+ // }
+ // getNextToken();
+ // } catch (IndexOutOfBoundsException e) {
+ // throwSyntaxError("'\"' expected at end of static string.");
+ // }
+ // break;
+ case TokenNameStringSingleQuote:
+ getNextToken();
+ break;
+ case TokenNameStringDoubleQuote:
+ getNextToken();
+ break;
+ case TokenNamePLUS:
+ getNextToken();
+ static_scalar();
+ break;
+ case TokenNameMINUS:
+ getNextToken();
+ static_scalar();
+ break;
+ case TokenNamearray:
+ getNextToken();
+ if (token != TokenNameLPAREN) {
+ throwSyntaxError("'(' expected after keyword 'array'");
+ }
+ getNextToken();
+ if (token == TokenNameRPAREN) {
+ getNextToken();
+ break;
+ }
+ non_empty_static_array_pair_list();
+ if (token != TokenNameRPAREN) {
+ throwSyntaxError("')' or ',' expected after keyword 'array'");
+ }
+ getNextToken();
+ break;
+ // case TokenNamenull :
+ // getNextToken();
+ // break;
+ // case TokenNamefalse :
+ // getNextToken();
+ // break;
+ // case TokenNametrue :
+ // getNextToken();
+ // break;
+ default:
+ throwSyntaxError("Static scalar/constant expected.");
+ }
+ }
+
+ private void non_empty_static_array_pair_list() {
+ // non_empty_static_array_pair_list:
+ // non_empty_static_array_pair_list ',' static_scalar T_DOUBLE_ARROW
+ // static_scalar
+ // | non_empty_static_array_pair_list ',' static_scalar
+ // | static_scalar T_DOUBLE_ARROW static_scalar
+ // | static_scalar
+ while (true) {
+ static_scalar();
+ if (token == TokenNameEQUAL_GREATER) {
+ getNextToken();
+ static_scalar();
+ }
+ if (token != TokenNameCOMMA) {
+ break;
+ }
+ getNextToken();
+ if (token == TokenNameRPAREN) {
+ break;
+ }
+ }
+ }
+
+ // public void reportSyntaxError() { //int act, int currentKind, int
+ // // stateStackTop) {
+ // /* remember current scanner position */
+ // int startPos = scanner.startPosition;
+ // int currentPos = scanner.currentPosition;
+ //
+ // this.checkAndReportBracketAnomalies(problemReporter());
+ // /* reset scanner where it was */
+ // scanner.startPosition = startPos;
+ // scanner.currentPosition = currentPos;
+ // }
+
+ public static final int RoundBracket = 0;
+
+ public static final int SquareBracket = 1;
+
+ public static final int CurlyBracket = 2;
+
+ public static final int BracketKinds = 3;
+
+ protected int[] nestedMethod; // the ptr is nestedType
+
+ protected int nestedType, dimensions;
+
+ // variable set stack
+ final static int VariableStackIncrement = 10;
+
+ HashMap fTypeVariables = null;
+
+ HashMap fMethodVariables = null;
+
+ ArrayList fStackUnassigned = new ArrayList();
+
+ // ast stack
+ final static int AstStackIncrement = 100;
+
+ protected int astPtr;
+
+ protected ASTNode[] astStack = new ASTNode[AstStackIncrement];
+
+ protected int astLengthPtr;
+
+ protected int[] astLengthStack;
+
+ ASTNode[] noAstNodes = new ASTNode[AstStackIncrement];
+
+ public CompilationUnitDeclaration compilationUnit; /*
+ * the result from
+ * parse()
+ */
+
+ protected ReferenceContext referenceContext;
+
+ protected ProblemReporter problemReporter;
+
+ protected CompilerOptions options;
+
+ private ArrayList includesList;
+
+ // protected CompilationResult compilationResult;
+ /**
+ * Returns this parser's problem reporter initialized with its reference
+ * context. Also it is assumed that a problem is going to be reported, so
+ * initializes the compilation result's line positions.
+ */
+ public ProblemReporter problemReporter() {
+ if (scanner.recordLineSeparator) {
+ compilationUnit.compilationResult.lineSeparatorPositions = scanner
+ .getLineEnds();
+ }
+ problemReporter.referenceContext = referenceContext;
+ return problemReporter;
+ }
+
+ /*
+ * Reconsider the entire source looking for inconsistencies in {} () []
+ */
+ // public boolean checkAndReportBracketAnomalies(ProblemReporter
+ // problemReporter) {
+ // scanner.wasAcr = false;
+ // boolean anomaliesDetected = false;
+ // try {
+ // char[] source = scanner.source;
+ // int[] leftCount = { 0, 0, 0 };
+ // int[] rightCount = { 0, 0, 0 };
+ // int[] depths = { 0, 0, 0 };
+ // int[][] leftPositions = new int[][] { new int[10], new int[10], new
+ // int[10]
+ // };
+ // int[][] leftDepths = new int[][] { new int[10], new int[10], new int[10]
+ // };
+ // int[][] rightPositions = new int[][] { new int[10], new int[10], new
+ // int[10] };
+ // int[][] rightDepths = new int[][] { new int[10], new int[10], new int[10]
+ // };
+ // scanner.currentPosition = scanner.initialPosition; //starting
+ // // point
+ // // (first-zero-based
+ // // char)
+ // while (scanner.currentPosition < scanner.eofPosition) { //loop for
+ // // jumping
+ // // over
+ // // comments
+ // try {
+ // // ---------Consume white space and handles
+ // // startPosition---------
+ // boolean isWhiteSpace;
+ // do {
+ // scanner.startPosition = scanner.currentPosition;
+ // // if (((scanner.currentCharacter =
+ // // source[scanner.currentPosition++]) == '\\') &&
+ // // (source[scanner.currentPosition] == 'u')) {
+ // // isWhiteSpace = scanner.jumpOverUnicodeWhiteSpace();
+ // // } else {
+ // if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') ||
+ // (scanner.currentCharacter == '\n'))) {
+ // if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
+ // // only record line positions we have not
+ // // recorded yet
+ // scanner.pushLineSeparator();
+ // }
+ // }
+ // isWhiteSpace = CharOperation.isWhitespace(scanner.currentCharacter);
+ // // }
+ // } while (isWhiteSpace && (scanner.currentPosition <
+ // scanner.eofPosition));
+ // // -------consume token until } is found---------
+ // switch (scanner.currentCharacter) {
+ // case '{': {
+ // int index = leftCount[CurlyBracket]++;
+ // if (index == leftPositions[CurlyBracket].length) {
+ // System.arraycopy(leftPositions[CurlyBracket], 0,
+ // (leftPositions[CurlyBracket] = new int[index * 2]), 0, index);
+ // System.arraycopy(leftDepths[CurlyBracket], 0, (leftDepths[CurlyBracket] =
+ // new int[index * 2]), 0, index);
+ // }
+ // leftPositions[CurlyBracket][index] = scanner.startPosition;
+ // leftDepths[CurlyBracket][index] = depths[CurlyBracket]++;
+ // }
+ // break;
+ // case '}': {
+ // int index = rightCount[CurlyBracket]++;
+ // if (index == rightPositions[CurlyBracket].length) {
+ // System.arraycopy(rightPositions[CurlyBracket], 0,
+ // (rightPositions[CurlyBracket] = new int[index * 2]), 0, index);
+ // System.arraycopy(rightDepths[CurlyBracket], 0, (rightDepths[CurlyBracket]
+ // =
+ // new int[index * 2]), 0, index);
+ // }
+ // rightPositions[CurlyBracket][index] = scanner.startPosition;
+ // rightDepths[CurlyBracket][index] = --depths[CurlyBracket];
+ // }
+ // break;
+ // case '(': {
+ // int index = leftCount[RoundBracket]++;
+ // if (index == leftPositions[RoundBracket].length) {
+ // System.arraycopy(leftPositions[RoundBracket], 0,
+ // (leftPositions[RoundBracket] = new int[index * 2]), 0, index);
+ // System.arraycopy(leftDepths[RoundBracket], 0, (leftDepths[RoundBracket] =
+ // new int[index * 2]), 0, index);
+ // }
+ // leftPositions[RoundBracket][index] = scanner.startPosition;
+ // leftDepths[RoundBracket][index] = depths[RoundBracket]++;
+ // }
+ // break;
+ // case ')': {
+ // int index = rightCount[RoundBracket]++;
+ // if (index == rightPositions[RoundBracket].length) {
+ // System.arraycopy(rightPositions[RoundBracket], 0,
+ // (rightPositions[RoundBracket] = new int[index * 2]), 0, index);
+ // System.arraycopy(rightDepths[RoundBracket], 0, (rightDepths[RoundBracket]
+ // =
+ // new int[index * 2]), 0, index);
+ // }
+ // rightPositions[RoundBracket][index] = scanner.startPosition;
+ // rightDepths[RoundBracket][index] = --depths[RoundBracket];
+ // }
+ // break;
+ // case '[': {
+ // int index = leftCount[SquareBracket]++;
+ // if (index == leftPositions[SquareBracket].length) {
+ // System.arraycopy(leftPositions[SquareBracket], 0,
+ // (leftPositions[SquareBracket] = new int[index * 2]), 0, index);
+ // System.arraycopy(leftDepths[SquareBracket], 0, (leftDepths[SquareBracket]
+ // =
+ // new int[index * 2]), 0, index);
+ // }
+ // leftPositions[SquareBracket][index] = scanner.startPosition;
+ // leftDepths[SquareBracket][index] = depths[SquareBracket]++;
+ // }
+ // break;
+ // case ']': {
+ // int index = rightCount[SquareBracket]++;
+ // if (index == rightPositions[SquareBracket].length) {
+ // System.arraycopy(rightPositions[SquareBracket], 0,
+ // (rightPositions[SquareBracket] = new int[index * 2]), 0, index);
+ // System.arraycopy(rightDepths[SquareBracket], 0,
+ // (rightDepths[SquareBracket]
+ // = new int[index * 2]), 0, index);
+ // }
+ // rightPositions[SquareBracket][index] = scanner.startPosition;
+ // rightDepths[SquareBracket][index] = --depths[SquareBracket];
+ // }
+ // break;
+ // case '\'': {
+ // if (scanner.getNextChar('\\')) {
+ // scanner.scanEscapeCharacter();
+ // } else { // consume next character
+ // scanner.unicodeAsBackSlash = false;
+ // // if (((scanner.currentCharacter =
+ // // source[scanner.currentPosition++]) ==
+ // // '\\') &&
+ // // (source[scanner.currentPosition] ==
+ // // 'u')) {
+ // // scanner.getNextUnicodeChar();
+ // // } else {
+ // if (scanner.withoutUnicodePtr != 0) {
+ // scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] =
+ // scanner.currentCharacter;
+ // }
+ // // }
+ // }
+ // scanner.getNextChar('\'');
+ // break;
+ // }
+ // case '"':
+ // // consume next character
+ // scanner.unicodeAsBackSlash = false;
+ // // if (((scanner.currentCharacter =
+ // // source[scanner.currentPosition++]) == '\\') &&
+ // // (source[scanner.currentPosition] == 'u')) {
+ // // scanner.getNextUnicodeChar();
+ // // } else {
+ // if (scanner.withoutUnicodePtr != 0) {
+ // scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] =
+ // scanner.currentCharacter;
+ // }
+ // // }
+ // while (scanner.currentCharacter != '"') {
+ // if (scanner.currentCharacter == '\r') {
+ // if (source[scanner.currentPosition] == '\n')
+ // scanner.currentPosition++;
+ // break; // the string cannot go further that
+ // // the line
+ // }
+ // if (scanner.currentCharacter == '\n') {
+ // break; // the string cannot go further that
+ // // the line
+ // }
+ // if (scanner.currentCharacter == '\\') {
+ // scanner.scanEscapeCharacter();
+ // }
+ // // consume next character
+ // scanner.unicodeAsBackSlash = false;
+ // // if (((scanner.currentCharacter =
+ // // source[scanner.currentPosition++]) == '\\')
+ // // && (source[scanner.currentPosition] == 'u'))
+ // // {
+ // // scanner.getNextUnicodeChar();
+ // // } else {
+ // if (scanner.withoutUnicodePtr != 0) {
+ // scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] =
+ // scanner.currentCharacter;
+ // }
+ // // }
+ // }
+ // break;
+ // case '/': {
+ // int test;
+ // if ((test = scanner.getNextChar('/', '*')) == 0) { //line
+ // // comment
+ // //get the next char
+ // if (((scanner.currentCharacter = source[scanner.currentPosition++]) ==
+ // '\\')
+ // && (source[scanner.currentPosition] == 'u')) {
+ // //-------------unicode traitement
+ // // ------------
+ // int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
+ // scanner.currentPosition++;
+ // while (source[scanner.currentPosition] == 'u') {
+ // scanner.currentPosition++;
+ // }
+ // if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15 || c1 < 0
+ // || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15
+ // || c2 < 0
+ // || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15
+ // || c3 < 0
+ // || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15
+ // || c4 < 0) { //error
+ // // don't
+ // // care of the
+ // // value
+ // scanner.currentCharacter = 'A';
+ // } //something different from \n and \r
+ // else {
+ // scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+ // }
+ // }
+ // while (scanner.currentCharacter != '\r' && scanner.currentCharacter !=
+ // '\n') {
+ // //get the next char
+ // scanner.startPosition = scanner.currentPosition;
+ // if (((scanner.currentCharacter = source[scanner.currentPosition++]) ==
+ // '\\')
+ // && (source[scanner.currentPosition] == 'u')) {
+ // //-------------unicode traitement
+ // // ------------
+ // int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
+ // scanner.currentPosition++;
+ // while (source[scanner.currentPosition] == 'u') {
+ // scanner.currentPosition++;
+ // }
+ // if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15 || c1 < 0
+ // || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15
+ // || c2 < 0
+ // || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15
+ // || c3 < 0
+ // || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15
+ // || c4 < 0) { //error
+ // // don't
+ // // care of the
+ // // value
+ // scanner.currentCharacter = 'A';
+ // } //something different from \n
+ // // and \r
+ // else {
+ // scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+ // }
+ // }
+ // }
+ // if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') ||
+ // (scanner.currentCharacter == '\n'))) {
+ // if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
+ // // only record line positions we
+ // // have not recorded yet
+ // scanner.pushLineSeparator();
+ // if (this.scanner.taskTags != null) {
+ // this.scanner.checkTaskTag(this.scanner.getCurrentTokenStartPosition(),
+ // this.scanner
+ // .getCurrentTokenEndPosition());
+ // }
+ // }
+ // }
+ // break;
+ // }
+ // if (test > 0) { //traditional and annotation
+ // // comment
+ // boolean star = false;
+ // // consume next character
+ // scanner.unicodeAsBackSlash = false;
+ // // if (((scanner.currentCharacter =
+ // // source[scanner.currentPosition++]) ==
+ // // '\\') &&
+ // // (source[scanner.currentPosition] ==
+ // // 'u')) {
+ // // scanner.getNextUnicodeChar();
+ // // } else {
+ // if (scanner.withoutUnicodePtr != 0) {
+ // scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] =
+ // scanner.currentCharacter;
+ // }
+ // // }
+ // if (scanner.currentCharacter == '*') {
+ // star = true;
+ // }
+ // //get the next char
+ // if (((scanner.currentCharacter = source[scanner.currentPosition++]) ==
+ // '\\')
+ // && (source[scanner.currentPosition] == 'u')) {
+ // //-------------unicode traitement
+ // // ------------
+ // int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
+ // scanner.currentPosition++;
+ // while (source[scanner.currentPosition] == 'u') {
+ // scanner.currentPosition++;
+ // }
+ // if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15 || c1 < 0
+ // || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15
+ // || c2 < 0
+ // || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15
+ // || c3 < 0
+ // || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15
+ // || c4 < 0) { //error
+ // // don't
+ // // care of the
+ // // value
+ // scanner.currentCharacter = 'A';
+ // } //something different from * and /
+ // else {
+ // scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+ // }
+ // }
+ // //loop until end of comment */
+ // while ((scanner.currentCharacter != '/') || (!star)) {
+ // star = scanner.currentCharacter == '*';
+ // //get next char
+ // if (((scanner.currentCharacter = source[scanner.currentPosition++]) ==
+ // '\\')
+ // && (source[scanner.currentPosition] == 'u')) {
+ // //-------------unicode traitement
+ // // ------------
+ // int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
+ // scanner.currentPosition++;
+ // while (source[scanner.currentPosition] == 'u') {
+ // scanner.currentPosition++;
+ // }
+ // if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15 || c1 < 0
+ // || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15
+ // || c2 < 0
+ // || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15
+ // || c3 < 0
+ // || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) >
+ // 15
+ // || c4 < 0) { //error
+ // // don't
+ // // care of the
+ // // value
+ // scanner.currentCharacter = 'A';
+ // } //something different from * and
+ // // /
+ // else {
+ // scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+ // }
+ // }
+ // }
+ // if (this.scanner.taskTags != null) {
+ // this.scanner.checkTaskTag(this.scanner.getCurrentTokenStartPosition(),
+ // this.scanner.getCurrentTokenEndPosition());
+ // }
+ // break;
+ // }
+ // break;
+ // }
+ // default:
+ // if (Scanner.isPHPIdentifierStart(scanner.currentCharacter)) {
+ // scanner.scanIdentifierOrKeyword(false);
+ // break;
+ // }
+ // if (Character.isDigit(scanner.currentCharacter)) {
+ // scanner.scanNumber(false);
+ // break;
+ // }
+ // }
+ // //-----------------end switch while
+ // // try--------------------
+ // } catch (IndexOutOfBoundsException e) {
+ // break; // read until EOF
+ // } catch (InvalidInputException e) {
+ // return false; // no clue
+ // }
+ // }
+ // if (scanner.recordLineSeparator) {
+ // compilationUnit.compilationResult.lineSeparatorPositions =
+ // scanner.getLineEnds();
+ // }
+ // // check placement anomalies against other kinds of brackets
+ // for (int kind = 0; kind < BracketKinds; kind++) {
+ // for (int leftIndex = leftCount[kind] - 1; leftIndex >= 0; leftIndex--) {
+ // int start = leftPositions[kind][leftIndex]; // deepest
+ // // first
+ // // find matching closing bracket
+ // int depth = leftDepths[kind][leftIndex];
+ // int end = -1;
+ // for (int i = 0; i < rightCount[kind]; i++) {
+ // int pos = rightPositions[kind][i];
+ // // want matching bracket further in source with same
+ // // depth
+ // if ((pos > start) && (depth == rightDepths[kind][i])) {
+ // end = pos;
+ // break;
+ // }
+ // }
+ // if (end < 0) { // did not find a good closing match
+ // problemReporter.unmatchedBracket(start, referenceContext,
+ // compilationUnit.compilationResult);
+ // return true;
+ // }
+ // // check if even number of opening/closing other brackets
+ // // in between this pair of brackets
+ // int balance = 0;
+ // for (int otherKind = 0; (balance == 0) && (otherKind < BracketKinds);
+ // otherKind++) {
+ // for (int i = 0; i < leftCount[otherKind]; i++) {
+ // int pos = leftPositions[otherKind][i];
+ // if ((pos > start) && (pos < end))
+ // balance++;
+ // }
+ // for (int i = 0; i < rightCount[otherKind]; i++) {
+ // int pos = rightPositions[otherKind][i];
+ // if ((pos > start) && (pos < end))
+ // balance--;
+ // }
+ // if (balance != 0) {
+ // problemReporter.unmatchedBracket(start, referenceContext,
+ // compilationUnit.compilationResult); //bracket
+ // // anomaly
+ // return true;
+ // }
+ // }
+ // }
+ // // too many opening brackets ?
+ // for (int i = rightCount[kind]; i < leftCount[kind]; i++) {
+ // anomaliesDetected = true;
+ // problemReporter.unmatchedBracket(leftPositions[kind][leftCount[kind] - i
+ // -
+ // 1], referenceContext,
+ // compilationUnit.compilationResult);
+ // }
+ // // too many closing brackets ?
+ // for (int i = leftCount[kind]; i < rightCount[kind]; i++) {
+ // anomaliesDetected = true;
+ // problemReporter.unmatchedBracket(rightPositions[kind][i],
+ // referenceContext,
+ // compilationUnit.compilationResult);
+ // }
+ // if (anomaliesDetected)
+ // return true;
+ // }
+ // return anomaliesDetected;
+ // } catch (ArrayStoreException e) { // jdk1.2.2 jit bug
+ // return anomaliesDetected;
+ // } catch (NullPointerException e) { // jdk1.2.2 jit bug
+ // return anomaliesDetected;
+ // }
+ // }
+ protected void pushOnAstLengthStack(int pos) {
+ try {
+ astLengthStack[++astLengthPtr] = pos;
+ } catch (IndexOutOfBoundsException e) {
+ int oldStackLength = astLengthStack.length;
+ int[] oldPos = astLengthStack;
+ astLengthStack = new int[oldStackLength + StackIncrement];
+ System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
+ astLengthStack[astLengthPtr] = pos;
+ }
+ }
+
+ protected void pushOnAstStack(ASTNode node) {
+ /*
+ * add a new obj on top of the ast stack
+ */
+ try {
+ astStack[++astPtr] = node;
+ } catch (IndexOutOfBoundsException e) {
+ int oldStackLength = astStack.length;
+ ASTNode[] oldStack = astStack;
+ astStack = new ASTNode[oldStackLength + AstStackIncrement];
+ System.arraycopy(oldStack, 0, astStack, 0, oldStackLength);
+ astPtr = oldStackLength;
+ astStack[astPtr] = node;
+ }
+ try {
+ astLengthStack[++astLengthPtr] = 1;
+ } catch (IndexOutOfBoundsException e) {
+ int oldStackLength = astLengthStack.length;
+ int[] oldPos = astLengthStack;
+ astLengthStack = new int[oldStackLength + AstStackIncrement];
+ System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
+ astLengthStack[astLengthPtr] = 1;
+ }
+ }
+
+ protected void resetModifiers() {
+ this.modifiers = AccDefault;
+ this.modifiersSourceStart = -1; // <-- see comment into
+ // modifiersFlag(int)
+ this.scanner.commentPtr = -1;
+ }
+
+ protected void consumePackageDeclarationName(IFile file) {
+ // create a package name similar to java package names
+ String projectPath = ProjectPrefUtil.getDocumentRoot(file.getProject())
+ .toString();
+ String filePath = file.getRawLocation().toString();
+ String ext = file.getRawLocation().getFileExtension();
+ int fileExtensionLength = ext == null ? 0 : ext.length() + 1;
+ ImportReference impt;
+ char[][] tokens;
+ if (filePath.startsWith(projectPath)) {
+ tokens = CharOperation.splitOn('/', filePath.toCharArray(),
+ projectPath.length() + 1, filePath.length()
+ - fileExtensionLength);
+ } else {
+ String name = file.getName();
+ tokens = new char[1][];
+ tokens[0] = name.substring(0, name.length() - fileExtensionLength)
+ .toCharArray();
+ }
+
+ this.compilationUnit.currentPackage = impt = new ImportReference(
+ tokens, new char[0], 0, 0, true);
+
+ impt.declarationSourceStart = 0;
+ impt.declarationSourceEnd = 0;
+ impt.declarationEnd = 0;
+ // endPosition is just before the ;
+
+ }
+
+ public final static String[] GLOBALS = { "$this", "$_COOKIE", "$_ENV",
+ "$_FILES", "$_GET", "$GLOBALS", "$_POST", "$_REQUEST", "$_SESSION",
+ "$_SERVER" };
+
+ /**
+ *
+ */
+ private void pushFunctionVariableSet() {
+ HashSet set = new HashSet();
+ if (fStackUnassigned.isEmpty()) {
+ for (int i = 0; i < GLOBALS.length; i++) {
+ set.add(GLOBALS[i]);
+ }
+ }
+ fStackUnassigned.add(set);
+ }
+
+ private void pushIfVariableSet() {
+ if (!fStackUnassigned.isEmpty()) {
+ HashSet set = new HashSet();
+ fStackUnassigned.add(set);
+ }
+ }
+
+ private HashSet removeIfVariableSet() {
+ if (!fStackUnassigned.isEmpty()) {
+ return (HashSet) fStackUnassigned
+ .remove(fStackUnassigned.size() - 1);
+ }
+ return null;
+ }
+
+ /**
+ * Returns the <i>set of assigned variables </i> returns null if no Set is
+ * defined at the current scanner position
+ */
+ private HashSet peekVariableSet() {
+ if (!fStackUnassigned.isEmpty()) {
+ return (HashSet) fStackUnassigned.get(fStackUnassigned.size() - 1);
+ }
+ return null;
+ }
+
+ /**
+ * add the current identifier source to the <i>set of assigned variables
+ * </i>
+ *
+ * @param set
+ */
+ private void addVariableSet(HashSet set) {
+ if (set != null) {
+ set.add(new String(scanner.getCurrentTokenSource()));
+ }
+ }
+
+ /**
+ * add the current identifier source to the <i>set of assigned variables
+ * </i>
+ *
+ */
+ private void addVariableSet() {
+ HashSet set = peekVariableSet();
+ if (set != null) {
+ set.add(new String(scanner.getCurrentTokenSource()));
+ }
+ }
+
+ /**
+ * add the current identifier source to the <i>set of assigned variables
+ * </i>
+ *
+ */
+ private void addVariableSet(char[] token) {
+ HashSet set = peekVariableSet();
+ if (set != null) {
+ set.add(new String(token));
+ }
+ }
+
+ /**
+ * check if the current identifier source is in the <i>set of assigned
+ * variables </i> Returns true, if no set is defined for the current scanner
+ * position
+ *
+ */
+ private boolean containsVariableSet() {
+ return containsVariableSet(scanner.getCurrentTokenSource());
+ }
+
+ private boolean containsVariableSet(char[] token) {
+
+ if (!fStackUnassigned.isEmpty()) {
+ HashSet set;
+ String str = new String(token);
+ for (int i = 0; i < fStackUnassigned.size(); i++) {
+ set = (HashSet) fStackUnassigned.get(i);
+ if (set.contains(str)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ return true;
+ }
+}
\ 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.core;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.WeakHashMap;
+import java.util.zip.ZipFile;
+
+import net.sourceforge.phpdt.core.ElementChangedEvent;
+import net.sourceforge.phpdt.core.IClasspathEntry;
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IElementChangedListener;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IJavaElementDelta;
+import net.sourceforge.phpdt.core.IJavaModel;
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.core.IPackageFragment;
+import net.sourceforge.phpdt.core.IPackageFragmentRoot;
+import net.sourceforge.phpdt.core.IParent;
+import net.sourceforge.phpdt.core.IProblemRequestor;
+import net.sourceforge.phpdt.core.IWorkingCopy;
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.core.WorkingCopyOwner;
+import net.sourceforge.phpdt.core.compiler.IProblem;
+import net.sourceforge.phpdt.internal.core.builder.PHPBuilder;
+import net.sourceforge.phpdt.internal.core.util.Util;
+import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.ISaveContext;
+import org.eclipse.core.resources.ISaveParticipant;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceDescription;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.Preferences.PropertyChangeEvent;
+
+/**
+ * The <code>JavaModelManager</code> manages instances of
+ * <code>IJavaModel</code>. <code>IElementChangedListener</code>s register
+ * with the <code>JavaModelManager</code>, and receive
+ * <code>ElementChangedEvent</code>s for all <code>IJavaModel</code>s.
+ * <p>
+ * The single instance of <code>JavaModelManager</code> is available from the
+ * static method <code>JavaModelManager.getJavaModelManager()</code>.
+ */
+public class JavaModelManager implements ISaveParticipant {
+ /**
+ * Unique handle onto the JavaModel
+ */
+ final JavaModel javaModel = new JavaModel();
+
+ // public IndexManager indexManager = new IndexManager();
+ /**
+ * Classpath variables pool
+ */
+ public static HashMap Variables = new HashMap(5);
+
+ public static HashMap PreviousSessionVariables = new HashMap(5);
+
+ public static HashSet OptionNames = new HashSet(20);
+
+ public final static String CP_VARIABLE_PREFERENCES_PREFIX = PHPeclipsePlugin.PLUGIN_ID
+ + ".classpathVariable."; //$NON-NLS-1$
+
+ public final static String CP_CONTAINER_PREFERENCES_PREFIX = PHPeclipsePlugin.PLUGIN_ID
+ + ".classpathContainer."; //$NON-NLS-1$
+
+ public final static String CP_ENTRY_IGNORE = "##<cp entry ignore>##"; //$NON-NLS-1$
+
+ /**
+ * Classpath containers pool
+ */
+ public static HashMap containers = new HashMap(5);
+
+ public static HashMap PreviousSessionContainers = new HashMap(5);
+
+ /**
+ * Name of the extension point for contributing classpath variable
+ * initializers
+ */
+ // public static final String CPVARIABLE_INITIALIZER_EXTPOINT_ID =
+ // "classpathVariableInitializer" ; //$NON-NLS-1$
+ /**
+ * Name of the extension point for contributing classpath container
+ * initializers
+ */
+ // public static final String CPCONTAINER_INITIALIZER_EXTPOINT_ID =
+ // "classpathContainerInitializer" ; //$NON-NLS-1$
+ /**
+ * Name of the extension point for contributing a source code formatter
+ */
+ public static final String FORMATTER_EXTPOINT_ID = "codeFormatter"; // $/**
+
+ /**
+ * Value of the content-type for Java source files
+ */
+ public static final String JAVA_SOURCE_CONTENT_TYPE = PHPeclipsePlugin.PLUGIN_ID
+ + ".phpSource"; //$NON-NLS-1$NON-NLS-1$
+
+ /**
+ * Special value used for recognizing ongoing initialization and breaking
+ * initialization cycles
+ */
+ public final static IPath VariableInitializationInProgress = new Path(
+ "Variable Initialization In Progress"); //$NON-NLS-1$
+ // public final static IClasspathContainer ContainerInitializationInProgress
+ // = new IClasspathContainer() {
+ // public IClasspathEntry[] getClasspathEntries() { return null; }
+ // public String getDescription() { return "Container Initialization In
+ // Progress"; } //$NON-NLS-1$
+ // public int getKind() { return 0; }
+ // public IPath getPath() { return null; }
+ // public String toString() { return getDescription(); }
+ // };
+
+ private static final String INDEX_MANAGER_DEBUG = PHPeclipsePlugin.PLUGIN_ID
+ + "/debug/indexmanager"; //$NON-NLS-1$
+
+ private static final String COMPILER_DEBUG = PHPeclipsePlugin.PLUGIN_ID
+ + "/debug/compiler"; //$NON-NLS-1$
+
+ private static final String JAVAMODEL_DEBUG = PHPeclipsePlugin.PLUGIN_ID
+ + "/debug/javamodel"; //$NON-NLS-1$
+
+ private static final String CP_RESOLVE_DEBUG = PHPeclipsePlugin.PLUGIN_ID
+ + "/debug/cpresolution"; //$NON-NLS-1$
+
+ private static final String ZIP_ACCESS_DEBUG = PHPeclipsePlugin.PLUGIN_ID
+ + "/debug/zipaccess"; //$NON-NLS-1$
+
+ private static final String DELTA_DEBUG = PHPeclipsePlugin.PLUGIN_ID
+ + "/debug/javadelta"; //$NON-NLS-1$
+
+ private static final String HIERARCHY_DEBUG = PHPeclipsePlugin.PLUGIN_ID
+ + "/debug/hierarchy"; //$NON-NLS-1$
+
+ private static final String POST_ACTION_DEBUG = PHPeclipsePlugin.PLUGIN_ID
+ + "/debug/postaction"; //$NON-NLS-1$
+
+ private static final String BUILDER_DEBUG = PHPeclipsePlugin.PLUGIN_ID
+ + "/debug/builder"; //$NON-NLS-1$
+
+ private static final String COMPLETION_DEBUG = PHPeclipsePlugin.PLUGIN_ID
+ + "/debug/completion"; //$NON-NLS-1$
+
+ private static final String SELECTION_DEBUG = PHPeclipsePlugin.PLUGIN_ID
+ + "/debug/selection"; //$NON-NLS-1$
+
+ private static final String SHARED_WC_DEBUG = PHPeclipsePlugin.PLUGIN_ID
+ + "/debug/sharedworkingcopy"; //$NON-NLS-1$
+
+ private static final String SEARCH_DEBUG = PHPeclipsePlugin.PLUGIN_ID
+ + "/debug/search"; //$NON-NLS-1$
+
+ public final static IWorkingCopy[] NoWorkingCopy = new IWorkingCopy[0];
+
+ /**
+ * Table from WorkingCopyOwner to a table of ICompilationUnit (working copy
+ * handle) to PerWorkingCopyInfo. NOTE: this object itself is used as a lock
+ * to synchronize creation/removal of per working copy infos
+ */
+ protected Map perWorkingCopyInfos = new HashMap(5);
+
+ /**
+ * Returns whether the given full path (for a package) conflicts with the
+ * output location of the given project.
+ */
+ public static boolean conflictsWithOutputLocation(IPath folderPath,
+ JavaProject project) {
+ try {
+ IPath outputLocation = project.getOutputLocation();
+ if (outputLocation == null) {
+ // in doubt, there is a conflict
+ return true;
+ }
+ if (outputLocation.isPrefixOf(folderPath)) {
+ // only allow nesting in project's output if there is a
+ // corresponding source folder
+ // or if the project's output is not used (in other words, if
+ // all source folders have their custom output)
+ IClasspathEntry[] classpath = project
+ .getResolvedClasspath(true);
+ boolean isOutputUsed = false;
+ for (int i = 0, length = classpath.length; i < length; i++) {
+ IClasspathEntry entry = classpath[i];
+ if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
+ if (entry.getPath().equals(outputLocation)) {
+ return false;
+ }
+ if (entry.getOutputLocation() == null) {
+ isOutputUsed = true;
+ }
+ }
+ }
+ return isOutputUsed;
+ }
+ return false;
+ } catch (JavaModelException e) {
+ // in doubt, there is a conflict
+ return true;
+ }
+ }
+
+ // public static IClasspathContainer containerGet(IJavaProject project,
+ // IPath containerPath) {
+ // Map projectContainers = (Map)Containers.get(project);
+ // if (projectContainers == null){
+ // return null;
+ // }
+ // IClasspathContainer container =
+ // (IClasspathContainer)projectContainers.get(containerPath);
+ // return container;
+ // }
+
+ // public static void containerPut(IJavaProject project, IPath
+ // containerPath, IClasspathContainer container){
+ //
+ // Map projectContainers = (Map)Containers.get(project);
+ // if (projectContainers == null){
+ // projectContainers = new HashMap(1);
+ // Containers.put(project, projectContainers);
+ // }
+ //
+ // if (container == null) {
+ // projectContainers.remove(containerPath);
+ // Map previousContainers = (Map)PreviousSessionContainers.get(project);
+ // if (previousContainers != null){
+ // previousContainers.remove(containerPath);
+ // }
+ // } else {
+ // projectContainers.put(containerPath, container);
+ // }
+ //
+ // // do not write out intermediate initialization value
+ // if (container == JavaModelManager.ContainerInitializationInProgress) {
+ // return;
+ // }
+ // Preferences preferences =
+ // PHPeclipsePlugin.getPlugin().getPluginPreferences();
+ // String containerKey =
+ // CP_CONTAINER_PREFERENCES_PREFIX+project.getElementName()
+ // +"|"+containerPath;//$NON-NLS-1$
+ // String containerString = CP_ENTRY_IGNORE;
+ // try {
+ // if (container != null) {
+ // containerString =
+ // ((JavaProject)project).encodeClasspath(container.getClasspathEntries(),
+ // null, false);
+ // }
+ // } catch(JavaModelException e){
+ // }
+ // preferences.setDefault(containerKey, CP_ENTRY_IGNORE); // use this
+ // default to get rid of removed ones
+ // preferences.setValue(containerKey, containerString);
+ // PHPeclipsePlugin.getPlugin().savePluginPreferences();
+ // }
+
+ /**
+ * Returns the Java element corresponding to the given resource, or
+ * <code>null</code> if unable to associate the given resource with a Java
+ * element.
+ * <p>
+ * The resource must be one of:
+ * <ul>
+ * <li>a project - the element returned is the corresponding
+ * <code>IJavaProject</code></li>
+ * <li>a <code>.java</code> file - the element returned is the
+ * corresponding <code>ICompilationUnit</code></li>
+ * <li>a <code>.class</code> file - the element returned is the
+ * corresponding <code>IClassFile</code></li>
+ * <li>a <code>.jar</code> file - the element returned is the
+ * corresponding <code>IPackageFragmentRoot</code></li>
+ * <li>a folder - the element returned is the corresponding
+ * <code>IPackageFragmentRoot</code> or <code>IPackageFragment</code></li>
+ * <li>the workspace root resource - the element returned is the
+ * <code>IJavaModel</code></li>
+ * </ul>
+ * <p>
+ * Creating a Java element has the side effect of creating and opening all
+ * of the element's parents if they are not yet open.
+ */
+ public static IJavaElement create(IResource resource, IJavaProject project) {
+ if (resource == null) {
+ return null;
+ }
+ int type = resource.getType();
+ switch (type) {
+ case IResource.PROJECT:
+ return JavaCore.create((IProject) resource);
+ case IResource.FILE:
+ return create((IFile) resource, project);
+ case IResource.FOLDER:
+ return create((IFolder) resource, project);
+ case IResource.ROOT:
+ return JavaCore.create((IWorkspaceRoot) resource);
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Returns the Java element corresponding to the given file, its project
+ * being the given project. Returns <code>null</code> if unable to
+ * associate the given file with a Java element.
+ *
+ * <p>
+ * The file must be one of:
+ * <ul>
+ * <li>a <code>.java</code> file - the element returned is the
+ * corresponding <code>ICompilationUnit</code></li>
+ * <li>a <code>.class</code> file - the element returned is the
+ * corresponding <code>IClassFile</code></li>
+ * <li>a <code>.jar</code> file - the element returned is the
+ * corresponding <code>IPackageFragmentRoot</code></li>
+ * </ul>
+ * <p>
+ * Creating a Java element has the side effect of creating and opening all
+ * of the element's parents if they are not yet open.
+ */
+ public static IJavaElement create(IFile file, IJavaProject project) {
+ if (file == null) {
+ return null;
+ }
+ if (project == null) {
+ project = JavaCore.create(file.getProject());
+ }
+
+ if (file.getFileExtension() != null) {
+ String name = file.getName();
+ if (PHPFileUtil.isValidPHPUnitName(name))
+ // if (PHPFileUtil.isPHPFile(file))
+ return createCompilationUnitFrom(file, project);
+ // if (ProjectPrefUtil.isValidClassFileName(name))
+ // return createClassFileFrom(file, project);
+ // if (ProjectPrefUtil.isArchiveFileName(name))
+ // return createJarPackageFragmentRootFrom(file, project);
+ }
+ return null;
+ }
+
+ /**
+ * Returns the package fragment or package fragment root corresponding to
+ * the given folder, its parent or great parent being the given project. or
+ * <code>null</code> if unable to associate the given folder with a Java
+ * element.
+ * <p>
+ * Note that a package fragment root is returned rather than a default
+ * package.
+ * <p>
+ * Creating a Java element has the side effect of creating and opening all
+ * of the element's parents if they are not yet open.
+ */
+ public static IJavaElement create(IFolder folder, IJavaProject project) {
+ if (folder == null) {
+ return null;
+ }
+ if (project == null) {
+ project = JavaCore.create(folder.getProject());
+ }
+ IJavaElement element = determineIfOnClasspath(folder, project);
+ if (conflictsWithOutputLocation(folder.getFullPath(),
+ (JavaProject) project)
+ || (folder.getName().indexOf('.') >= 0 && !(element instanceof IPackageFragmentRoot))) {
+ return null; // only package fragment roots are allowed with dot
+ // names
+ } else {
+ return element;
+ }
+ }
+
+ /**
+ * Creates and returns a class file element for the given
+ * <code>.class</code> file, its project being the given project. Returns
+ * <code>null</code> if unable to recognize the class file.
+ */
+ // public static IClassFile createClassFileFrom(IFile file, IJavaProject
+ // project ) {
+ // if (file == null) {
+ // return null;
+ // }
+ // if (project == null) {
+ // project = PHPCore.create(file.getProject());
+ // }
+ // IPackageFragment pkg = (IPackageFragment) determineIfOnClasspath(file,
+ // project);
+ // if (pkg == null) {
+ // // fix for 1FVS7WE
+ // // not on classpath - make the root its folder, and a default package
+ // IPackageFragmentRoot root =
+ // project.getPackageFragmentRoot(file.getParent());
+ // pkg = root.getPackageFragment(IPackageFragment.DEFAULT_PACKAGE_NAME);
+ // }
+ // return pkg.getClassFile(file.getName());
+ // }
+ /**
+ * Creates and returns a compilation unit element for the given
+ * <code>.java</code> file, its project being the given project. Returns
+ * <code>null</code> if unable to recognize the compilation unit.
+ */
+ public static ICompilationUnit createCompilationUnitFrom(IFile file,
+ IJavaProject project) {
+
+ if (file == null)
+ return null;
+
+ if (project == null) {
+ project = JavaCore.create(file.getProject());
+ }
+ IPackageFragment pkg = (IPackageFragment) determineIfOnClasspath(file,
+ project);
+ if (pkg == null) {
+ // not on classpath - make the root its folder, and a default
+ // package
+ IPackageFragmentRoot root = project.getPackageFragmentRoot(file
+ .getParent());
+ pkg = root
+ .getPackageFragment(IPackageFragment.DEFAULT_PACKAGE_NAME);
+
+ if (VERBOSE) {
+ System.out
+ .println("WARNING : creating unit element outside classpath (" + Thread.currentThread() + "): " + file.getFullPath()); //$NON-NLS-1$//$NON-NLS-2$
+ }
+ }
+ return pkg.getCompilationUnit(file.getName());
+ }
+
+ /**
+ * Creates and returns a handle for the given JAR file, its project being
+ * the given project. The Java model associated with the JAR's project may
+ * be created as a side effect. Returns <code>null</code> if unable to
+ * create a JAR package fragment root. (for example, if the JAR file
+ * represents a non-Java resource)
+ */
+ // public static IPackageFragmentRoot createJarPackageFragmentRootFrom(IFile
+ // file, IJavaProject project) {
+ // if (file == null) {
+ // return null;
+ // }
+ // if (project == null) {
+ // project = PHPCore.create(file.getProject());
+ // }
+ //
+ // // Create a jar package fragment root only if on the classpath
+ // IPath resourcePath = file.getFullPath();
+ // try {
+ // IClasspathEntry[] entries =
+ // ((JavaProject)project).getResolvedClasspath(true);
+ // for (int i = 0, length = entries.length; i < length; i++) {
+ // IClasspathEntry entry = entries[i];
+ // IPath rootPath = entry.getPath();
+ // if (rootPath.equals(resourcePath)) {
+ // return project.getPackageFragmentRoot(file);
+ // }
+ // }
+ // } catch (JavaModelException e) {
+ // }
+ // return null;
+ // }
+ /**
+ * Returns the package fragment root represented by the resource, or the
+ * package fragment the given resource is located in, or <code>null</code>
+ * if the given resource is not on the classpath of the given project.
+ */
+ public static IJavaElement determineIfOnClasspath(IResource resource,
+ IJavaProject project) {
+
+ IPath resourcePath = resource.getFullPath();
+ try {
+ IClasspathEntry[] entries = net.sourceforge.phpdt.internal.compiler.util.Util
+ .isJavaFileName(resourcePath.lastSegment()) ? project
+ .getRawClasspath() // JAVA file can only live inside SRC
+ // folder (on the raw path)
+ : ((JavaProject) project).getResolvedClasspath(true);
+
+ for (int i = 0; i < entries.length; i++) {
+ IClasspathEntry entry = entries[i];
+ if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT)
+ continue;
+ IPath rootPath = entry.getPath();
+ if (rootPath.equals(resourcePath)) {
+ return project.getPackageFragmentRoot(resource);
+ } else if (rootPath.isPrefixOf(resourcePath)
+ && !Util.isExcluded(resource, null,
+ ((ClasspathEntry) entry)
+ .fullExclusionPatternChars())) {
+ // given we have a resource child of the root, it cannot be
+ // a JAR pkg root
+ IPackageFragmentRoot root = ((JavaProject) project)
+ .getFolderPackageFragmentRoot(rootPath);
+ if (root == null)
+ return null;
+ IPath pkgPath = resourcePath.removeFirstSegments(rootPath
+ .segmentCount());
+ if (resource.getType() == IResource.FILE) {
+ // if the resource is a file, then remove the last
+ // segment which
+ // is the file name in the package
+ pkgPath = pkgPath.removeLastSegments(1);
+
+ // don't check validity of package name (see
+ // http://bugs.eclipse.org/bugs/show_bug.cgi?id=26706)
+ // String pkgName = pkgPath.toString().replace('/',
+ // '.');
+ String pkgName = pkgPath.toString();
+ return root.getPackageFragment(pkgName);
+ } else {
+ String pkgName = Util.packageName(pkgPath);
+ if (pkgName == null) {// ||
+ // JavaConventions.validatePackageName(pkgName).getSeverity()
+ // == IStatus.ERROR) {
+ return null;
+ }
+ return root.getPackageFragment(pkgName);
+ }
+ }
+ }
+ } catch (JavaModelException npe) {
+ return null;
+ }
+ return null;
+ }
+
+ /**
+ * The singleton manager
+ */
+ private final static JavaModelManager Manager = new JavaModelManager();
+
+ /**
+ * Infos cache.
+ */
+ protected JavaModelCache cache = new JavaModelCache();
+
+ /*
+ * Temporary cache of newly opened elements
+ */
+ private ThreadLocal temporaryCache = new ThreadLocal();
+
+ /**
+ * Set of elements which are out of sync with their buffers.
+ */
+ protected Map elementsOutOfSynchWithBuffers = new HashMap(11);
+
+ /**
+ * Holds the state used for delta processing.
+ */
+ public DeltaProcessingState deltaState = new DeltaProcessingState();
+
+ /**
+ * Turns delta firing on/off. By default it is on.
+ */
+ private boolean isFiring = true;
+
+ /**
+ * Queue of deltas created explicily by the Java Model that have yet to be
+ * fired.
+ */
+ ArrayList javaModelDeltas = new ArrayList();
+
+ /**
+ * Queue of reconcile deltas on working copies that have yet to be fired.
+ * This is a table form IWorkingCopy to IJavaElementDelta
+ */
+ HashMap reconcileDeltas = new HashMap();
+
+ /**
+ * Collection of listeners for Java element deltas
+ */
+ private IElementChangedListener[] elementChangedListeners = new IElementChangedListener[5];
+
+ private int[] elementChangedListenerMasks = new int[5];
+
+ private int elementChangedListenerCount = 0;
+
+ public int currentChangeEventType = ElementChangedEvent.PRE_AUTO_BUILD;
+
+ public static final int DEFAULT_CHANGE_EVENT = 0; // must not collide with
+ // ElementChangedEvent
+ // event masks
+
+ /**
+ * Used to convert <code>IResourceDelta</code>s into
+ * <code>IJavaElementDelta</code>s.
+ */
+ // public final DeltaProcessor deltaProcessor = new DeltaProcessor(this);
+ /**
+ * Used to update the JavaModel for <code>IJavaElementDelta</code>s.
+ */
+ private final ModelUpdater modelUpdater = new ModelUpdater();
+
+ /**
+ * Workaround for bug 15168 circular errors not reported This is a cache of
+ * the projects before any project addition/deletion has started.
+ */
+ public IJavaProject[] javaProjectsCache;
+
+ /**
+ * Table from IProject to PerProjectInfo. NOTE: this object itself is used
+ * as a lock to synchronize creation/removal of per project infos
+ */
+ protected Map perProjectInfo = new HashMap(5);
+
+ /**
+ * A map from ICompilationUnit to IWorkingCopy of the shared working copies.
+ */
+ public Map sharedWorkingCopies = new HashMap();
+
+ /**
+ * A weak set of the known scopes.
+ */
+ protected WeakHashMap searchScopes = new WeakHashMap();
+
+ // public static class PerProjectInfo {
+ // public IProject project;
+ // public Object savedState;
+ // public boolean triedRead;
+ // public IClasspathEntry[] classpath;
+ // public IClasspathEntry[] lastResolvedClasspath;
+ // public Map resolvedPathToRawEntries; // reverse map from resolved path to
+ // raw entries
+ // public IPath outputLocation;
+ // public Preferences preferences;
+ // public PerProjectInfo(IProject project) {
+ //
+ // this.triedRead = false;
+ // this.savedState = null;
+ // this.project = project;
+ // }
+ // }
+
+ public static class PerProjectInfo {
+
+ public IProject project;
+
+ public Object savedState;
+
+ public boolean triedRead;
+
+ public IClasspathEntry[] rawClasspath;
+
+ public IClasspathEntry[] resolvedClasspath;
+
+ public Map resolvedPathToRawEntries; // reverse map from resolved
+ // path to raw entries
+
+ public IPath outputLocation;
+
+ public Preferences preferences;
+
+ public PerProjectInfo(IProject project) {
+
+ this.triedRead = false;
+ this.savedState = null;
+ this.project = project;
+ }
+
+ // updating raw classpath need to flush obsoleted cached information
+ // about resolved entries
+ public synchronized void updateClasspathInformation(
+ IClasspathEntry[] newRawClasspath) {
+
+ this.rawClasspath = newRawClasspath;
+ this.resolvedClasspath = null;
+ this.resolvedPathToRawEntries = null;
+ }
+
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("Info for "); //$NON-NLS-1$
+ buffer.append(this.project.getFullPath());
+ buffer.append("\nRaw classpath:\n"); //$NON-NLS-1$
+ if (this.rawClasspath == null) {
+ buffer.append(" <null>\n"); //$NON-NLS-1$
+ } else {
+ for (int i = 0, length = this.rawClasspath.length; i < length; i++) {
+ buffer.append(" "); //$NON-NLS-1$
+ buffer.append(this.rawClasspath[i]);
+ buffer.append('\n');
+ }
+ }
+ buffer.append("Resolved classpath:\n"); //$NON-NLS-1$
+ IClasspathEntry[] resolvedCP = this.resolvedClasspath;
+ if (resolvedCP == null) {
+ buffer.append(" <null>\n"); //$NON-NLS-1$
+ } else {
+ for (int i = 0, length = resolvedCP.length; i < length; i++) {
+ buffer.append(" "); //$NON-NLS-1$
+ buffer.append(resolvedCP[i]);
+ buffer.append('\n');
+ }
+ }
+ buffer.append("Output location:\n "); //$NON-NLS-1$
+ if (this.outputLocation == null) {
+ buffer.append("<null>"); //$NON-NLS-1$
+ } else {
+ buffer.append(this.outputLocation);
+ }
+ return buffer.toString();
+ }
+ }
+
+ public static class PerWorkingCopyInfo implements IProblemRequestor {
+ int useCount = 0;
+
+ IProblemRequestor problemRequestor;
+
+ ICompilationUnit workingCopy;
+
+ public PerWorkingCopyInfo(ICompilationUnit workingCopy,
+ IProblemRequestor problemRequestor) {
+ this.workingCopy = workingCopy;
+ this.problemRequestor = problemRequestor;
+ }
+
+ public void acceptProblem(IProblem problem) {
+ if (this.problemRequestor == null)
+ return;
+ this.problemRequestor.acceptProblem(problem);
+ }
+
+ public void beginReporting() {
+ if (this.problemRequestor == null)
+ return;
+ this.problemRequestor.beginReporting();
+ }
+
+ public void endReporting() {
+ if (this.problemRequestor == null)
+ return;
+ this.problemRequestor.endReporting();
+ }
+
+ public ICompilationUnit getWorkingCopy() {
+ return this.workingCopy;
+ }
+
+ public boolean isActive() {
+ return this.problemRequestor != null
+ && this.problemRequestor.isActive();
+ }
+
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("Info for "); //$NON-NLS-1$
+ buffer.append(((JavaElement) workingCopy).toStringWithAncestors());
+ buffer.append("\nUse count = "); //$NON-NLS-1$
+ buffer.append(this.useCount);
+ buffer.append("\nProblem requestor:\n "); //$NON-NLS-1$
+ buffer.append(this.problemRequestor);
+ return buffer.toString();
+ }
+ }
+
+ public static boolean VERBOSE = false;
+
+ public static boolean CP_RESOLVE_VERBOSE = false;
+
+ public static boolean ZIP_ACCESS_VERBOSE = false;
+
+ /**
+ * A cache of opened zip files per thread. (map from Thread to map of IPath
+ * to java.io.ZipFile) NOTE: this object itself is used as a lock to
+ * synchronize creation/removal of entries
+ */
+ private HashMap zipFiles = new HashMap();
+
+ /**
+ * Update the classpath variable cache
+ */
+ public static class PluginPreferencesListener implements
+ Preferences.IPropertyChangeListener {
+ /**
+ * @see org.eclipse.core.runtime.Preferences.IPropertyChangeListener#propertyChange(PropertyChangeEvent)
+ */
+ public void propertyChange(Preferences.PropertyChangeEvent event) {
+ // TODO : jsurfer temp-del
+ // String propertyName = event.getProperty();
+ // if (propertyName.startsWith(CP_VARIABLE_PREFERENCES_PREFIX)) {
+ // String varName =
+ // propertyName.substring(CP_VARIABLE_PREFERENCES_PREFIX.length());
+ // String newValue = (String)event.getNewValue();
+ // if (newValue != null && !(newValue =
+ // newValue.trim()).equals(CP_ENTRY_IGNORE)) {
+ // Variables.put(varName, new Path(newValue));
+ // } else {
+ // Variables.remove(varName);
+ // }
+ // }
+ // if (propertyName.startsWith(CP_CONTAINER_PREFERENCES_PREFIX)) {
+ // recreatePersistedContainer(propertyName,
+ // (String)event.getNewValue(), false);
+ // }
+ }
+ }
+
+ /**
+ * Line separator to use throughout the JavaModel for any source edit
+ * operation
+ */
+ public static String LINE_SEPARATOR = System.getProperty("line.separator"); //$NON-NLS-1$
+
+ /**
+ * Constructs a new JavaModelManager
+ */
+ private JavaModelManager() {
+ }
+
+ /**
+ * @deprecated - discard once debug has converted to not using it
+ */
+ public void addElementChangedListener(IElementChangedListener listener) {
+ this.addElementChangedListener(listener,
+ ElementChangedEvent.POST_CHANGE
+ | ElementChangedEvent.POST_RECONCILE);
+ }
+
+ /**
+ * addElementChangedListener method comment. Need to clone defensively the
+ * listener information, in case some listener is reacting to some
+ * notification iteration by adding/changing/removing any of the other (for
+ * example, if it deregisters itself).
+ */
+ public void addElementChangedListener(IElementChangedListener listener,
+ int eventMask) {
+ for (int i = 0; i < this.elementChangedListenerCount; i++) {
+ if (this.elementChangedListeners[i].equals(listener)) {
+
+ // only clone the masks, since we could be in the middle of
+ // notifications and one listener decide to change
+ // any event mask of another listeners (yet not notified).
+ int cloneLength = this.elementChangedListenerMasks.length;
+ System
+ .arraycopy(
+ this.elementChangedListenerMasks,
+ 0,
+ this.elementChangedListenerMasks = new int[cloneLength],
+ 0, cloneLength);
+ this.elementChangedListenerMasks[i] = eventMask; // could be
+ // different
+ return;
+ }
+ }
+ // may need to grow, no need to clone, since iterators will have cached
+ // original arrays and max boundary and we only add to the end.
+ int length;
+ if ((length = this.elementChangedListeners.length) == this.elementChangedListenerCount) {
+ System
+ .arraycopy(
+ this.elementChangedListeners,
+ 0,
+ this.elementChangedListeners = new IElementChangedListener[length * 2],
+ 0, length);
+ System.arraycopy(this.elementChangedListenerMasks, 0,
+ this.elementChangedListenerMasks = new int[length * 2], 0,
+ length);
+ }
+ this.elementChangedListeners[this.elementChangedListenerCount] = listener;
+ this.elementChangedListenerMasks[this.elementChangedListenerCount] = eventMask;
+ this.elementChangedListenerCount++;
+ }
+
+ /**
+ * Starts caching ZipFiles. Ignores if there are already clients.
+ */
+ public void cacheZipFiles() {
+ synchronized (this.zipFiles) {
+ Thread currentThread = Thread.currentThread();
+ if (this.zipFiles.get(currentThread) != null)
+ return;
+ this.zipFiles.put(currentThread, new HashMap());
+ }
+ }
+
+ public void closeZipFile(ZipFile zipFile) {
+ if (zipFile == null)
+ return;
+ synchronized (this.zipFiles) {
+ if (this.zipFiles.get(Thread.currentThread()) != null) {
+ return; // zip file will be closed by call to flushZipFiles
+ }
+ try {
+ if (JavaModelManager.ZIP_ACCESS_VERBOSE) {
+ System.out
+ .println("(" + Thread.currentThread() + ") [JavaModelManager.closeZipFile(ZipFile)] Closing ZipFile on " + zipFile.getName()); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ zipFile.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ /**
+ * Configure the plugin with respect to option settings defined in
+ * ".options" file
+ */
+ public void configurePluginDebugOptions() {
+ if (JavaCore.getPlugin().isDebugging()) {
+ // TODO jsurfer temp-del
+
+ String option = Platform.getDebugOption(BUILDER_DEBUG);
+ // if(option != null) JavaBuilder.DEBUG =
+ // option.equalsIgnoreCase("true") ; //$NON-NLS-1$
+ //
+ // option = Platform.getDebugOption(COMPILER_DEBUG);
+ // if(option != null) Compiler.DEBUG =
+ // option.equalsIgnoreCase("true") ; //$NON-NLS-1$
+ //
+ // option = Platform.getDebugOption(COMPLETION_DEBUG);
+ // if(option != null) CompletionEngine.DEBUG =
+ // option.equalsIgnoreCase("true") ; //$NON-NLS-1$
+ //
+ option = Platform.getDebugOption(CP_RESOLVE_DEBUG);
+ if (option != null)
+ JavaModelManager.CP_RESOLVE_VERBOSE = option
+ .equalsIgnoreCase("true"); //$NON-NLS-1$
+
+ option = Platform.getDebugOption(DELTA_DEBUG);
+ if (option != null)
+ DeltaProcessor.VERBOSE = option.equalsIgnoreCase("true"); //$NON-NLS-1$
+
+ // option = Platform.getDebugOption(HIERARCHY_DEBUG);
+ // if(option != null) TypeHierarchy.DEBUG =
+ // option.equalsIgnoreCase("true") ; //$NON-NLS-1$
+ //
+ // option = Platform.getDebugOption(INDEX_MANAGER_DEBUG);
+ // if(option != null) IndexManager.VERBOSE =
+ // option.equalsIgnoreCase("true") ; //$NON-NLS-1$
+
+ option = Platform.getDebugOption(JAVAMODEL_DEBUG);
+ if (option != null)
+ JavaModelManager.VERBOSE = option.equalsIgnoreCase("true"); //$NON-NLS-1$
+
+ option = Platform.getDebugOption(POST_ACTION_DEBUG);
+ if (option != null)
+ JavaModelOperation.POST_ACTION_VERBOSE = option
+ .equalsIgnoreCase("true"); //$NON-NLS-1$
+
+ // option = Platform.getDebugOption(SEARCH_DEBUG);
+ // if(option != null) SearchEngine.VERBOSE =
+ // option.equalsIgnoreCase("true") ; //$NON-NLS-1$
+ //
+ // option = Platform.getDebugOption(SELECTION_DEBUG);
+ // if(option != null) SelectionEngine.DEBUG =
+ // option.equalsIgnoreCase("true") ; //$NON-NLS-1$
+
+ option = Platform.getDebugOption(ZIP_ACCESS_DEBUG);
+ if (option != null)
+ JavaModelManager.ZIP_ACCESS_VERBOSE = option
+ .equalsIgnoreCase("true"); //$NON-NLS-1$
+ }
+ }
+
+ /*
+ * Discards the per working copy info for the given working copy (making it
+ * a compilation unit) if its use count was 1. Otherwise, just decrement the
+ * use count. If the working copy is primary, computes the delta between its
+ * state and the original compilation unit and register it. Close the
+ * working copy, its buffer and remove it from the shared working copy
+ * table. Ignore if no per-working copy info existed. NOTE: it must be
+ * synchronized as it may interact with the element info cache (if useCount
+ * is decremented to 0), see bug 50667. Returns the new use count (or -1 if
+ * it didn't exist).
+ */
+ public synchronized int discardPerWorkingCopyInfo(
+ CompilationUnit workingCopy) throws JavaModelException {
+ synchronized (perWorkingCopyInfos) {
+ WorkingCopyOwner owner = workingCopy.owner;
+ Map workingCopyToInfos = (Map) this.perWorkingCopyInfos.get(owner);
+ if (workingCopyToInfos == null)
+ return -1;
+
+ PerWorkingCopyInfo info = (PerWorkingCopyInfo) workingCopyToInfos
+ .get(workingCopy);
+ if (info == null)
+ return -1;
+
+ if (--info.useCount == 0) {
+ // create the delta builder (this remembers the current content
+ // of the working copy)
+ JavaElementDeltaBuilder deltaBuilder = null;
+ if (workingCopy.isPrimary()) {
+ deltaBuilder = new JavaElementDeltaBuilder(workingCopy);
+ }
+
+ // remove per working copy info
+ workingCopyToInfos.remove(workingCopy);
+ if (workingCopyToInfos.isEmpty()) {
+ this.perWorkingCopyInfos.remove(owner);
+ }
+
+ // remove infos + close buffer (since no longer working copy)
+ removeInfoAndChildren(workingCopy);
+ workingCopy.closeBuffer();
+
+ // compute the delta if needed and register it if there are
+ // changes
+ if (deltaBuilder != null) {
+ deltaBuilder.buildDeltas();
+ if ((deltaBuilder.delta != null)
+ && (deltaBuilder.delta.getAffectedChildren().length > 0)) {
+ getDeltaProcessor().registerJavaModelDelta(
+ deltaBuilder.delta);
+ }
+ }
+
+ }
+ return info.useCount;
+ }
+ }
+
+ /**
+ * @see ISaveParticipant
+ */
+ public void doneSaving(ISaveContext context) {
+ }
+
+ /**
+ * Fire Java Model delta, flushing them after the fact after post_change
+ * notification. If the firing mode has been turned off, this has no effect.
+ */
+ public void fire(IJavaElementDelta customDelta, int eventType) {
+
+ if (!this.isFiring)
+ return;
+
+ if (DeltaProcessor.VERBOSE
+ && (eventType == DEFAULT_CHANGE_EVENT || eventType == ElementChangedEvent.PRE_AUTO_BUILD)) {
+ System.out
+ .println("-----------------------------------------------------------------------------------------------------------------------");//$NON-NLS-1$
+ }
+
+ IJavaElementDelta deltaToNotify;
+ if (customDelta == null) {
+ deltaToNotify = this.mergeDeltas(this.javaModelDeltas);
+ } else {
+ deltaToNotify = customDelta;
+ }
+
+ // Refresh internal scopes
+ if (deltaToNotify != null) {
+ // TODO temp-del
+ // Iterator scopes = this.scopes.keySet().iterator();
+ // while (scopes.hasNext()) {
+ // AbstractSearchScope scope = (AbstractSearchScope)scopes.next();
+ // scope.processDelta(deltaToNotify);
+ // }
+ }
+
+ // Notification
+
+ // Important: if any listener reacts to notification by updating the
+ // listeners list or mask, these lists will
+ // be duplicated, so it is necessary to remember original lists in a
+ // variable (since field values may change under us)
+ IElementChangedListener[] listeners = this.elementChangedListeners;
+ int[] listenerMask = this.elementChangedListenerMasks;
+ int listenerCount = this.elementChangedListenerCount;
+
+ switch (eventType) {
+ case DEFAULT_CHANGE_EVENT:
+ firePreAutoBuildDelta(deltaToNotify, listeners, listenerMask,
+ listenerCount);
+ firePostChangeDelta(deltaToNotify, listeners, listenerMask,
+ listenerCount);
+ fireReconcileDelta(listeners, listenerMask, listenerCount);
+ break;
+ case ElementChangedEvent.PRE_AUTO_BUILD:
+ firePreAutoBuildDelta(deltaToNotify, listeners, listenerMask,
+ listenerCount);
+ break;
+ case ElementChangedEvent.POST_CHANGE:
+ firePostChangeDelta(deltaToNotify, listeners, listenerMask,
+ listenerCount);
+ fireReconcileDelta(listeners, listenerMask, listenerCount);
+ break;
+ }
+
+ }
+
+ private void firePreAutoBuildDelta(IJavaElementDelta deltaToNotify,
+ IElementChangedListener[] listeners, int[] listenerMask,
+ int listenerCount) {
+
+ if (DeltaProcessor.VERBOSE) {
+ System.out
+ .println("FIRING PRE_AUTO_BUILD Delta [" + Thread.currentThread() + "]:"); //$NON-NLS-1$//$NON-NLS-2$
+ System.out
+ .println(deltaToNotify == null ? "<NONE>" : deltaToNotify.toString()); //$NON-NLS-1$
+ }
+ if (deltaToNotify != null) {
+ notifyListeners(deltaToNotify, ElementChangedEvent.PRE_AUTO_BUILD,
+ listeners, listenerMask, listenerCount);
+ }
+ }
+
+ private void firePostChangeDelta(IJavaElementDelta deltaToNotify,
+ IElementChangedListener[] listeners, int[] listenerMask,
+ int listenerCount) {
+
+ // post change deltas
+ if (DeltaProcessor.VERBOSE) {
+ System.out
+ .println("FIRING POST_CHANGE Delta [" + Thread.currentThread() + "]:"); //$NON-NLS-1$//$NON-NLS-2$
+ System.out
+ .println(deltaToNotify == null ? "<NONE>" : deltaToNotify.toString()); //$NON-NLS-1$
+ }
+ if (deltaToNotify != null) {
+ // flush now so as to keep listener reactions to post their own
+ // deltas for subsequent iteration
+ this.flush();
+
+ notifyListeners(deltaToNotify, ElementChangedEvent.POST_CHANGE,
+ listeners, listenerMask, listenerCount);
+ }
+ }
+
+ private void fireReconcileDelta(IElementChangedListener[] listeners,
+ int[] listenerMask, int listenerCount) {
+
+ IJavaElementDelta deltaToNotify = mergeDeltas(this.reconcileDeltas
+ .values());
+ if (DeltaProcessor.VERBOSE) {
+ System.out
+ .println("FIRING POST_RECONCILE Delta [" + Thread.currentThread() + "]:"); //$NON-NLS-1$//$NON-NLS-2$
+ System.out
+ .println(deltaToNotify == null ? "<NONE>" : deltaToNotify.toString()); //$NON-NLS-1$
+ }
+ if (deltaToNotify != null) {
+ // flush now so as to keep listener reactions to post their own
+ // deltas for subsequent iteration
+ this.reconcileDeltas = new HashMap();
+
+ notifyListeners(deltaToNotify, ElementChangedEvent.POST_RECONCILE,
+ listeners, listenerMask, listenerCount);
+ }
+ }
+
+ public void notifyListeners(IJavaElementDelta deltaToNotify, int eventType,
+ IElementChangedListener[] listeners, int[] listenerMask,
+ int listenerCount) {
+ final ElementChangedEvent extraEvent = new ElementChangedEvent(
+ deltaToNotify, eventType);
+ for (int i = 0; i < listenerCount; i++) {
+ if ((listenerMask[i] & eventType) != 0) {
+ final IElementChangedListener listener = listeners[i];
+ long start = -1;
+ if (DeltaProcessor.VERBOSE) {
+ System.out
+ .print("Listener #" + (i + 1) + "=" + listener.toString());//$NON-NLS-1$//$NON-NLS-2$
+ start = System.currentTimeMillis();
+ }
+ // wrap callbacks with Safe runnable for subsequent listeners to
+ // be called when some are causing grief
+ Platform.run(new ISafeRunnable() {
+ public void handleException(Throwable exception) {
+ Util
+ .log(exception,
+ "Exception occurred in listener of Java element change notification"); //$NON-NLS-1$
+ }
+
+ public void run() throws Exception {
+ listener.elementChanged(extraEvent);
+ }
+ });
+ if (DeltaProcessor.VERBOSE) {
+ System.out
+ .println(" -> " + (System.currentTimeMillis() - start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+ }
+ }
+
+ /**
+ * Flushes all deltas without firing them.
+ */
+ protected void flush() {
+ this.javaModelDeltas = new ArrayList();
+ }
+
+ /**
+ * Flushes ZipFiles cache if there are no more clients.
+ */
+ public void flushZipFiles() {
+ synchronized (this.zipFiles) {
+ Thread currentThread = Thread.currentThread();
+ HashMap map = (HashMap) this.zipFiles.remove(currentThread);
+ if (map == null)
+ return;
+ Iterator iterator = map.values().iterator();
+ while (iterator.hasNext()) {
+ try {
+ ZipFile zipFile = (ZipFile) iterator.next();
+ if (JavaModelManager.ZIP_ACCESS_VERBOSE) {
+ System.out
+ .println("(" + currentThread + ") [JavaModelManager.flushZipFiles()] Closing ZipFile on " + zipFile.getName()); //$NON-NLS-1$//$NON-NLS-2$
+ }
+ zipFile.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+ }
+
+ public DeltaProcessor getDeltaProcessor() {
+ return this.deltaState.getDeltaProcessor();
+ }
+
+ /**
+ * Returns the set of elements which are out of synch with their buffers.
+ */
+ protected Map getElementsOutOfSynchWithBuffers() {
+ return this.elementsOutOfSynchWithBuffers;
+ }
+
+ // public IndexManager getIndexManager() {
+ // return this.indexManager;
+ // }
+ /**
+ * Returns the <code>IJavaElement</code> represented by the
+ * <code>String</code> memento.
+ */
+ public IJavaElement getHandleFromMemento(String memento)
+ throws JavaModelException {
+ if (memento == null) {
+ return null;
+ }
+ JavaModel model = (JavaModel) getJavaModel();
+ if (memento.equals("")) { // workspace memento //$NON-NLS-1$
+ return model;
+ }
+ int modelEnd = memento.indexOf(JavaElement.JEM_JAVAPROJECT);
+ if (modelEnd == -1) {
+ return null;
+ }
+ boolean returnProject = false;
+ int projectEnd = memento.indexOf(JavaElement.JEM_PACKAGEFRAGMENTROOT,
+ modelEnd);
+ if (projectEnd == -1) {
+ projectEnd = memento.length();
+ returnProject = true;
+ }
+ String projectName = memento.substring(modelEnd + 1, projectEnd);
+ JavaProject proj = (JavaProject) model.getJavaProject(projectName);
+ if (returnProject) {
+ return proj;
+ }
+ int rootEnd = memento.indexOf(JavaElement.JEM_PACKAGEFRAGMENT,
+ projectEnd + 1);
+ // TODO temp-del
+ // if (rootEnd == -1) {
+ // return model.getHandleFromMementoForRoot(memento, proj, projectEnd,
+ // memento.length());
+ // }
+ // IPackageFragmentRoot root =
+ // model.getHandleFromMementoForRoot(memento, proj, projectEnd,
+ // rootEnd);
+ // if (root == null)
+ // return null;
+ //
+ // int end= memento.indexOf(JavaElement.JEM_COMPILATIONUNIT, rootEnd);
+ // if (end == -1) {
+ // end= memento.indexOf(JavaElement.JEM_CLASSFILE, rootEnd);
+ // if (end == -1) {
+ // if (rootEnd + 1 == memento.length()) {
+ // return
+ // root.getPackageFragment(IPackageFragment.DEFAULT_PACKAGE_NAME);
+ // } else {
+ // return root.getPackageFragment(memento.substring(rootEnd + 1));
+ // }
+ // }
+ // //deal with class file and binary members
+ // return model.getHandleFromMementoForBinaryMembers(memento, root,
+ // rootEnd, end);
+ // }
+ //
+ // //deal with compilation units and source members
+ // return model.getHandleFromMementoForSourceMembers(memento, root,
+ // rootEnd, end);
+ return null;
+ }
+
+ // public IndexManager getIndexManager() {
+ // return this.deltaProcessor.indexManager;
+ // }
+
+ /**
+ * Returns the info for the element.
+ */
+ public Object getInfo(IJavaElement element) {
+ return this.cache.getInfo(element);
+ }
+
+ /**
+ * Returns the handle to the active Java Model.
+ */
+ public final JavaModel getJavaModel() {
+ return javaModel;
+ }
+
+ /**
+ * Returns the singleton JavaModelManager
+ */
+ public final static JavaModelManager getJavaModelManager() {
+ return Manager;
+ }
+
+ /**
+ * Returns the last built state for the given project, or null if there is
+ * none. Deserializes the state if necessary.
+ *
+ * For use by image builder and evaluation support only
+ */
+ public Object getLastBuiltState(IProject project, IProgressMonitor monitor) {
+ if (!JavaProject.hasJavaNature(project))
+ return null; // should never be requested on non-Java projects
+ PerProjectInfo info = getPerProjectInfo(project, true/*
+ * create if
+ * missing
+ */);
+ if (!info.triedRead) {
+ info.triedRead = true;
+ try {
+ if (monitor != null)
+ monitor.subTask(Util.bind(
+ "build.readStateProgress", project.getName())); //$NON-NLS-1$
+ info.savedState = readState(project);
+ } catch (CoreException e) {
+ e.printStackTrace();
+ }
+ }
+ return info.savedState;
+ }
+
+ /*
+ * Returns the per-project info for the given project. If specified, create
+ * the info if the info doesn't exist.
+ */
+ public PerProjectInfo getPerProjectInfo(IProject project, boolean create) {
+ synchronized (perProjectInfo) { // use the perProjectInfo collection as
+ // its own lock
+ PerProjectInfo info = (PerProjectInfo) perProjectInfo.get(project);
+ if (info == null && create) {
+ info = new PerProjectInfo(project);
+ perProjectInfo.put(project, info);
+ }
+ return info;
+ }
+ }
+
+ /*
+ * Returns the per-project info for the given project. If the info doesn't
+ * exist, check for the project existence and create the info. @throws
+ * JavaModelException if the project doesn't exist.
+ */
+ public PerProjectInfo getPerProjectInfoCheckExistence(IProject project)
+ throws JavaModelException {
+ JavaModelManager.PerProjectInfo info = getPerProjectInfo(project, false /*
+ * don't
+ * create
+ * info
+ */);
+ if (info == null) {
+ if (!JavaProject.hasJavaNature(project)) {
+ throw ((JavaProject) JavaCore.create(project))
+ .newNotPresentException();
+ }
+ info = getPerProjectInfo(project, true /* create info */);
+ }
+ return info;
+ }
+
+ /*
+ * Returns the per-working copy info for the given working copy at the given
+ * path. If it doesn't exist and if create, add a new per-working copy info
+ * with the given problem requestor. If recordUsage, increment the
+ * per-working copy info's use count. Returns null if it doesn't exist and
+ * not create.
+ */
+ public PerWorkingCopyInfo getPerWorkingCopyInfo(
+ CompilationUnit workingCopy, boolean create, boolean recordUsage,
+ IProblemRequestor problemRequestor) {
+ synchronized (perWorkingCopyInfos) { // use the perWorkingCopyInfo
+ // collection as its own lock
+ WorkingCopyOwner owner = workingCopy.owner;
+ Map workingCopyToInfos = (Map) this.perWorkingCopyInfos.get(owner);
+ if (workingCopyToInfos == null && create) {
+ workingCopyToInfos = new HashMap();
+ this.perWorkingCopyInfos.put(owner, workingCopyToInfos);
+ }
+
+ PerWorkingCopyInfo info = workingCopyToInfos == null ? null
+ : (PerWorkingCopyInfo) workingCopyToInfos.get(workingCopy);
+ if (info == null && create) {
+ info = new PerWorkingCopyInfo(workingCopy, problemRequestor);
+ workingCopyToInfos.put(workingCopy, info);
+ }
+ if (info != null && recordUsage)
+ info.useCount++;
+ return info;
+ }
+ }
+
+ /**
+ * Returns the name of the variables for which an CP variable initializer is
+ * registered through an extension point
+ */
+ public static String[] getRegisteredVariableNames() {
+
+ Plugin jdtCorePlugin = JavaCore.getPlugin();
+ if (jdtCorePlugin == null)
+ return null;
+
+ ArrayList variableList = new ArrayList(5);
+ // IExtensionPoint extension =
+ // jdtCorePlugin.getDescriptor().getExtensionPoint(JavaModelManager.CPVARIABLE_INITIALIZER_EXTPOINT_ID);
+ // if (extension != null) {
+ // IExtension[] extensions = extension.getExtensions();
+ // for(int i = 0; i < extensions.length; i++){
+ // IConfigurationElement [] configElements =
+ // extensions[i].getConfigurationElements();
+ // for(int j = 0; j < configElements.length; j++){
+ // String varAttribute = configElements[j].getAttribute("variable");
+ // //$NON-NLS-1$
+ // if (varAttribute != null) variableList.add(varAttribute);
+ // }
+ // }
+ // }
+ String[] variableNames = new String[variableList.size()];
+ variableList.toArray(variableNames);
+ return variableNames;
+ }
+
+ /**
+ * Returns the name of the container IDs for which an CP container
+ * initializer is registered through an extension point
+ */
+ // public static String[] getRegisteredContainerIDs(){
+ //
+ // Plugin jdtCorePlugin = PHPCore.getPlugin();
+ // if (jdtCorePlugin == null) return null;
+ //
+ // ArrayList containerIDList = new ArrayList(5);
+ // IExtensionPoint extension =
+ // jdtCorePlugin.getDescriptor().getExtensionPoint(JavaModelManager.CPCONTAINER_INITIALIZER_EXTPOINT_ID);
+ // if (extension != null) {
+ // IExtension[] extensions = extension.getExtensions();
+ // for(int i = 0; i < extensions.length; i++){
+ // IConfigurationElement [] configElements =
+ // extensions[i].getConfigurationElements();
+ // for(int j = 0; j < configElements.length; j++){
+ // String idAttribute = configElements[j].getAttribute("id"); //$NON-NLS-1$
+ // if (idAttribute != null) containerIDList.add(idAttribute);
+ // }
+ // }
+ // }
+ // String[] containerIDs = new String[containerIDList.size()];
+ // containerIDList.toArray(containerIDs);
+ // return containerIDs;
+ // }
+ /**
+ * Returns the File to use for saving and restoring the last built state for
+ * the given project.
+ */
+ private File getSerializationFile(IProject project) {
+ if (!project.exists())
+ return null;
+ IPath workingLocation = project.getWorkingLocation(JavaCore.PLUGIN_ID);
+ return workingLocation.append("state.dat").toFile(); //$NON-NLS-1$
+ }
+
+ /*
+ * Returns the temporary cache for newly opened elements for the current
+ * thread. Creates it if not already created.
+ */
+ public HashMap getTemporaryCache() {
+ HashMap result = (HashMap) this.temporaryCache.get();
+ if (result == null) {
+ result = new HashMap();
+ this.temporaryCache.set(result);
+ }
+ return result;
+ }
+
+ /**
+ * Returns the open ZipFile at the given location. If the ZipFile does not
+ * yet exist, it is created, opened, and added to the cache of open
+ * ZipFiles. The location must be a absolute path.
+ *
+ * @exception CoreException
+ * If unable to create/open the ZipFile
+ */
+ public ZipFile getZipFile(IPath path) throws CoreException {
+
+ synchronized (this.zipFiles) { // TODO: use PeThreadObject which does
+ // synchronization
+ Thread currentThread = Thread.currentThread();
+ HashMap map = null;
+ ZipFile zipFile;
+ if ((map = (HashMap) this.zipFiles.get(currentThread)) != null
+ && (zipFile = (ZipFile) map.get(path)) != null) {
+
+ return zipFile;
+ }
+ String fileSystemPath = null;
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ IResource file = root.findMember(path);
+ if (path.isAbsolute() && file != null) {
+ if (file == null) { // external file
+ fileSystemPath = path.toOSString();
+ } else { // internal resource (not an IFile or not existing)
+ IPath location;
+ if (file.getType() != IResource.FILE
+ || (location = file.getLocation()) == null) {
+ throw new CoreException(
+ new Status(
+ IStatus.ERROR,
+ JavaCore.PLUGIN_ID,
+ -1,
+ Util
+ .bind(
+ "file.notFound", path.toString()), null)); //$NON-NLS-1$
+ }
+ fileSystemPath = location.toOSString();
+ }
+ } else if (!path.isAbsolute()) {
+ file = root.getFile(path);
+ if (file == null || file.getType() != IResource.FILE) {
+ throw new CoreException(new Status(IStatus.ERROR,
+ JavaCore.PLUGIN_ID, -1, Util.bind(
+ "file.notFound", path.toString()), null)); //$NON-NLS-1$
+ }
+ IPath location = file.getLocation();
+ if (location == null) {
+ throw new CoreException(new Status(IStatus.ERROR,
+ JavaCore.PLUGIN_ID, -1, Util.bind(
+ "file.notFound", path.toString()), null)); //$NON-NLS-1$
+ }
+ fileSystemPath = location.toOSString();
+ } else {
+ fileSystemPath = path.toOSString();
+ }
+
+ try {
+ if (ZIP_ACCESS_VERBOSE) {
+ System.out
+ .println("(" + currentThread + ") [JavaModelManager.getZipFile(IPath)] Creating ZipFile on " + fileSystemPath); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ zipFile = new ZipFile(fileSystemPath);
+ if (map != null) {
+ map.put(path, zipFile);
+ }
+ return zipFile;
+ } catch (IOException e) {
+ throw new CoreException(new Status(Status.ERROR,
+ JavaCore.PLUGIN_ID, -1,
+ Util.bind("status.IOException"), e)); //$NON-NLS-1$
+ }
+ }
+ }
+
+ /*
+ * Returns whether there is a temporary cache for the current thread.
+ */
+ public boolean hasTemporaryCache() {
+ return this.temporaryCache.get() != null;
+ }
+
+ // public void loadVariablesAndContainers() throws CoreException {
+ //
+ // // backward compatibility, consider persistent property
+ // QualifiedName qName = new QualifiedName(PHPCore.PLUGIN_ID, "variables");
+ // //$NON-NLS-1$
+ // String xmlString =
+ // ResourcesPlugin.getWorkspace().getRoot().getPersistentProperty(qName);
+ //
+ // try {
+ // if (xmlString != null){
+ // StringReader reader = new StringReader(xmlString);
+ // Element cpElement;
+ // try {
+ // DocumentBuilder parser =
+ // DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ // cpElement = parser.parse(new InputSource(reader)).getDocumentElement();
+ // } catch(SAXException e) {
+ // return;
+ // } catch(ParserConfigurationException e){
+ // return;
+ // } finally {
+ // reader.close();
+ // }
+ // if (cpElement == null) return;
+ // if (!cpElement.getNodeName().equalsIgnoreCase("variables")) {
+ // //$NON-NLS-1$
+ // return;
+ // }
+ //
+ // NodeList list= cpElement.getChildNodes();
+ // int length= list.getLength();
+ // for (int i= 0; i < length; ++i) {
+ // Node node= list.item(i);
+ // short type= node.getNodeType();
+ // if (type == Node.ELEMENT_NODE) {
+ // Element element= (Element) node;
+ // if (element.getNodeName().equalsIgnoreCase("variable")) { //$NON-NLS-1$
+ // variablePut(
+ // element.getAttribute("name"), //$NON-NLS-1$
+ // new Path(element.getAttribute("path"))); //$NON-NLS-1$
+ // }
+ // }
+ // }
+ // }
+ // } catch(IOException e){
+ // } finally {
+ // if (xmlString != null){
+ // ResourcesPlugin.getWorkspace().getRoot().setPersistentProperty(qName,
+ // null); // flush old one
+ // }
+ //
+ // }
+ //
+ // // load variables and containers from preferences into cache
+ // Preferences preferences =
+ // PHPeclipsePlugin.getDefault().getPluginPreferences();
+
+ // // only get variable from preferences not set to their default
+ // String[] propertyNames = preferences.propertyNames();
+ // int variablePrefixLength = CP_VARIABLE_PREFERENCES_PREFIX.length();
+ // for (int i = 0; i < propertyNames.length; i++){
+ // String propertyName = propertyNames[i];
+ // if (propertyName.startsWith(CP_VARIABLE_PREFERENCES_PREFIX)){
+ // String varName = propertyName.substring(variablePrefixLength);
+ // IPath varPath = new Path(preferences.getString(propertyName).trim());
+ //
+ // Variables.put(varName, varPath);
+ // PreviousSessionVariables.put(varName, varPath);
+ // }
+ // if (propertyName.startsWith(CP_CONTAINER_PREFERENCES_PREFIX)){
+ // recreatePersistedContainer(propertyName,
+ // preferences.getString(propertyName), true/*add to container values*/);
+ // }
+ // }
+ // // override persisted values for variables which have a registered
+ // initializer
+ // String[] registeredVariables = getRegisteredVariableNames();
+ // for (int i = 0; i < registeredVariables.length; i++) {
+ // String varName = registeredVariables[i];
+ // Variables.put(varName, null); // reset variable, but leave its entry in
+ // the Map, so it will be part of variable names.
+ // }
+ // // override persisted values for containers which have a registered
+ // initializer
+ // String[] registeredContainerIDs = getRegisteredContainerIDs();
+ // for (int i = 0; i < registeredContainerIDs.length; i++) {
+ // String containerID = registeredContainerIDs[i];
+ // Iterator projectIterator = Containers.keySet().iterator();
+ // while (projectIterator.hasNext()){
+ // IJavaProject project = (IJavaProject)projectIterator.next();
+ // Map projectContainers = (Map)Containers.get(project);
+ // if (projectContainers != null){
+ // Iterator containerIterator = projectContainers.keySet().iterator();
+ // while (containerIterator.hasNext()){
+ // IPath containerPath = (IPath)containerIterator.next();
+ // if (containerPath.segment(0).equals(containerID)) { // registered
+ // container
+ // projectContainers.put(containerPath, null); // reset container value, but
+ // leave entry in Map
+ // }
+ // }
+ // }
+ // }
+ // }
+ // }
+
+ /**
+ * Merged all awaiting deltas.
+ */
+ public IJavaElementDelta mergeDeltas(Collection deltas) {
+ if (deltas.size() == 0)
+ return null;
+ if (deltas.size() == 1)
+ return (IJavaElementDelta) deltas.iterator().next();
+
+ if (DeltaProcessor.VERBOSE) {
+ System.out
+ .println("MERGING " + deltas.size() + " DELTAS [" + Thread.currentThread() + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ Iterator iterator = deltas.iterator();
+ IJavaElement javaModel = this.getJavaModel();
+ JavaElementDelta rootDelta = new JavaElementDelta(javaModel);
+ boolean insertedTree = false;
+ while (iterator.hasNext()) {
+ JavaElementDelta delta = (JavaElementDelta) iterator.next();
+ if (DeltaProcessor.VERBOSE) {
+ System.out.println(delta.toString());
+ }
+ IJavaElement element = delta.getElement();
+ if (javaModel.equals(element)) {
+ IJavaElementDelta[] children = delta.getAffectedChildren();
+ for (int j = 0; j < children.length; j++) {
+ JavaElementDelta projectDelta = (JavaElementDelta) children[j];
+ rootDelta.insertDeltaTree(projectDelta.getElement(),
+ projectDelta);
+ insertedTree = true;
+ }
+ IResourceDelta[] resourceDeltas = delta.getResourceDeltas();
+ if (resourceDeltas != null) {
+ for (int i = 0, length = resourceDeltas.length; i < length; i++) {
+ rootDelta.addResourceDelta(resourceDeltas[i]);
+ insertedTree = true;
+ }
+ }
+ } else {
+ rootDelta.insertDeltaTree(element, delta);
+ insertedTree = true;
+ }
+ }
+ if (insertedTree) {
+ return rootDelta;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the info for this element without disturbing the cache ordering.
+ */
+ // TODO: should be synchronized, could answer unitialized info or if cache
+ // is in middle of rehash, could even answer distinct element info
+ protected Object peekAtInfo(IJavaElement element) {
+ return this.cache.peekAtInfo(element);
+ }
+
+ /**
+ * @see ISaveParticipant
+ */
+ public void prepareToSave(ISaveContext context) throws CoreException {
+ }
+
+ protected void putInfo(IJavaElement element, Object info) {
+ this.cache.putInfo(element, info);
+ }
+
+ /*
+ * Puts the infos in the given map (keys are IJavaElements and values are
+ * JavaElementInfos) in the Java model cache in an atomic way. First checks
+ * that the info for the opened element (or one of its ancestors) has not
+ * been added to the cache. If it is the case, another thread has opened the
+ * element (or one of its ancestors). So returns without updating the cache.
+ */
+ protected synchronized void putInfos(IJavaElement openedElement,
+ Map newElements) {
+ // remove children
+ Object existingInfo = this.cache.peekAtInfo(openedElement);
+ if (openedElement instanceof IParent
+ && existingInfo instanceof JavaElementInfo) {
+ IJavaElement[] children = ((JavaElementInfo) existingInfo)
+ .getChildren();
+ for (int i = 0, size = children.length; i < size; ++i) {
+ JavaElement child = (JavaElement) children[i];
+ try {
+ child.close();
+ } catch (JavaModelException e) {
+ // ignore
+ }
+ }
+ }
+
+ Iterator iterator = newElements.keySet().iterator();
+ while (iterator.hasNext()) {
+ IJavaElement element = (IJavaElement) iterator.next();
+ Object info = newElements.get(element);
+ this.cache.putInfo(element, info);
+ }
+ }
+
+ /**
+ * Reads the build state for the relevant project.
+ */
+ protected Object readState(IProject project) throws CoreException {
+ File file = getSerializationFile(project);
+ if (file != null && file.exists()) {
+ try {
+ DataInputStream in = new DataInputStream(
+ new BufferedInputStream(new FileInputStream(file)));
+ try {
+ String pluginID = in.readUTF();
+ if (!pluginID.equals(JavaCore.PLUGIN_ID))
+ throw new IOException(Util
+ .bind("build.wrongFileFormat")); //$NON-NLS-1$
+ String kind = in.readUTF();
+ if (!kind.equals("STATE")) //$NON-NLS-1$
+ throw new IOException(Util
+ .bind("build.wrongFileFormat")); //$NON-NLS-1$
+ if (in.readBoolean())
+ return PHPBuilder.readState(project, in);
+ if (PHPBuilder.DEBUG)
+ System.out
+ .println("Saved state thinks last build failed for " + project.getName()); //$NON-NLS-1$
+ } finally {
+ in.close();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new CoreException(
+ new Status(
+ IStatus.ERROR,
+ JavaCore.PLUGIN_ID,
+ Platform.PLUGIN_ERROR,
+ "Error reading last build state for project " + project.getName(), e)); //$NON-NLS-1$
+ }
+ }
+ return null;
+ }
+
+ // public static void recreatePersistedContainer(String propertyName, String
+ // containerString, boolean addToContainerValues) {
+ // int containerPrefixLength = CP_CONTAINER_PREFERENCES_PREFIX.length();
+ // int index = propertyName.indexOf('|', containerPrefixLength);
+ // if (containerString != null) containerString = containerString.trim();
+ // if (index > 0) {
+ // final String projectName = propertyName.substring(containerPrefixLength,
+ // index).trim();
+ // JavaProject project =
+ // (JavaProject)getJavaModelManager().getJavaModel().getJavaProject(projectName);
+ // final IPath containerPath = new
+ // Path(propertyName.substring(index+1).trim());
+ //
+ // if (containerString == null || containerString.equals(CP_ENTRY_IGNORE)) {
+ // containerPut(project, containerPath, null);
+ // } else {
+ // final IClasspathEntry[] containerEntries =
+ // project.decodeClasspath(containerString, false, false);
+ // if (containerEntries != null && containerEntries !=
+ // JavaProject.INVALID_CLASSPATH) {
+ // IClasspathContainer container = new IClasspathContainer() {
+ // public IClasspathEntry[] getClasspathEntries() {
+ // return containerEntries;
+ // }
+ // public String getDescription() {
+ // return "Persisted container ["+containerPath+" for project ["+
+ // projectName+"]"; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+ // }
+ // public int getKind() {
+ // return 0;
+ // }
+ // public IPath getPath() {
+ // return containerPath;
+ // }
+ // public String toString() {
+ // return getDescription();
+ // }
+ //
+ // };
+ // if (addToContainerValues) {
+ // containerPut(project, containerPath, container);
+ // }
+ // Map projectContainers = (Map)PreviousSessionContainers.get(project);
+ // if (projectContainers == null){
+ // projectContainers = new HashMap(1);
+ // PreviousSessionContainers.put(project, projectContainers);
+ // }
+ // projectContainers.put(containerPath, container);
+ // }
+ // }
+ // }
+ // }
+
+ /**
+ * Registers the given delta with this manager.
+ */
+ protected void registerJavaModelDelta(IJavaElementDelta delta) {
+ this.javaModelDeltas.add(delta);
+ }
+
+ /**
+ * Remembers the given scope in a weak set (so no need to remove it: it will
+ * be removed by the garbage collector)
+ */
+ // public void rememberScope(AbstractSearchScope scope) {
+ // // NB: The value has to be null so as to not create a strong reference on
+ // the scope
+ // this.scopes.put(scope, null);
+ // }
+ /**
+ * removeElementChangedListener method comment.
+ */
+ public void removeElementChangedListener(IElementChangedListener listener) {
+
+ for (int i = 0; i < this.elementChangedListenerCount; i++) {
+
+ if (this.elementChangedListeners[i].equals(listener)) {
+
+ // need to clone defensively since we might be in the middle of
+ // listener notifications (#fire)
+ int length = this.elementChangedListeners.length;
+ IElementChangedListener[] newListeners = new IElementChangedListener[length];
+ System.arraycopy(this.elementChangedListeners, 0, newListeners,
+ 0, i);
+ int[] newMasks = new int[length];
+ System.arraycopy(this.elementChangedListenerMasks, 0, newMasks,
+ 0, i);
+
+ // copy trailing listeners
+ int trailingLength = this.elementChangedListenerCount - i - 1;
+ if (trailingLength > 0) {
+ System.arraycopy(this.elementChangedListeners, i + 1,
+ newListeners, i, trailingLength);
+ System.arraycopy(this.elementChangedListenerMasks, i + 1,
+ newMasks, i, trailingLength);
+ }
+
+ // update manager listener state (#fire need to iterate over
+ // original listeners through a local variable to hold onto
+ // the original ones)
+ this.elementChangedListeners = newListeners;
+ this.elementChangedListenerMasks = newMasks;
+ this.elementChangedListenerCount--;
+ return;
+ }
+ }
+ }
+
+ /**
+ * Remembers the given scope in a weak set (so no need to remove it: it will
+ * be removed by the garbage collector)
+ */
+ // public void rememberScope(AbstractSearchScope scope) {
+ // // NB: The value has to be null so as to not create a strong reference on
+ // the scope
+ // this.searchScopes.put(scope, null);
+ // }
+ /*
+ * Removes all cached info for the given element (including all children)
+ * from the cache. Returns the info for the given element, or null if it was
+ * closed.
+ */
+ public synchronized Object removeInfoAndChildren(JavaElement element)
+ throws JavaModelException {
+ Object info = this.cache.peekAtInfo(element);
+ if (info != null) {
+ boolean wasVerbose = false;
+ try {
+ if (VERBOSE) {
+ System.out
+ .println("CLOSING Element (" + Thread.currentThread() + "): " + element.toStringWithAncestors()); //$NON-NLS-1$//$NON-NLS-2$
+ wasVerbose = true;
+ VERBOSE = false;
+ }
+ element.closing(info);
+ if (element instanceof IParent
+ && info instanceof JavaElementInfo) {
+ IJavaElement[] children = ((JavaElementInfo) info)
+ .getChildren();
+ for (int i = 0, size = children.length; i < size; ++i) {
+ JavaElement child = (JavaElement) children[i];
+ child.close();
+ }
+ }
+ this.cache.removeInfo(element);
+ if (wasVerbose) {
+ System.out
+ .println("-> Package cache size = " + this.cache.pkgSize()); //$NON-NLS-1$
+ System.out
+ .println("-> Openable cache filling ratio = " + NumberFormat.getInstance().format(this.cache.openableFillingRatio()) + "%"); //$NON-NLS-1$//$NON-NLS-2$
+ }
+ } finally {
+ JavaModelManager.VERBOSE = wasVerbose;
+ }
+ return info;
+ }
+ return null;
+ }
+
+ public void removePerProjectInfo(JavaProject javaProject) {
+ synchronized (perProjectInfo) { // use the perProjectInfo collection as
+ // its own lock
+ IProject project = javaProject.getProject();
+ PerProjectInfo info = (PerProjectInfo) perProjectInfo.get(project);
+ if (info != null) {
+ perProjectInfo.remove(project);
+ }
+ }
+ }
+
+ /*
+ * Resets the temporary cache for newly created elements to null.
+ */
+ public void resetTemporaryCache() {
+ this.temporaryCache.set(null);
+ }
+
+ /**
+ * @see ISaveParticipant
+ */
+ public void rollback(ISaveContext context) {
+ }
+
+ private void saveState(PerProjectInfo info, ISaveContext context)
+ throws CoreException {
+
+ // passed this point, save actions are non trivial
+ if (context.getKind() == ISaveContext.SNAPSHOT)
+ return;
+
+ // save built state
+ if (info.triedRead)
+ saveBuiltState(info);
+ }
+
+ /**
+ * Saves the built state for the project.
+ */
+ private void saveBuiltState(PerProjectInfo info) throws CoreException {
+ if (PHPBuilder.DEBUG)
+ System.out.println(Util.bind(
+ "build.saveStateProgress", info.project.getName())); //$NON-NLS-1$
+ File file = getSerializationFile(info.project);
+ if (file == null)
+ return;
+ long t = System.currentTimeMillis();
+ try {
+ DataOutputStream out = new DataOutputStream(
+ new BufferedOutputStream(new FileOutputStream(file)));
+ try {
+ out.writeUTF(JavaCore.PLUGIN_ID);
+ out.writeUTF("STATE"); //$NON-NLS-1$
+ if (info.savedState == null) {
+ out.writeBoolean(false);
+ } else {
+ out.writeBoolean(true);
+ PHPBuilder.writeState(info.savedState, out);
+ }
+ } finally {
+ out.close();
+ }
+ } catch (RuntimeException e) {
+ try {
+ file.delete();
+ } catch (SecurityException se) {
+ }
+ throw new CoreException(
+ new Status(
+ IStatus.ERROR,
+ JavaCore.PLUGIN_ID,
+ Platform.PLUGIN_ERROR,
+ Util
+ .bind(
+ "build.cannotSaveState", info.project.getName()), e)); //$NON-NLS-1$
+ } catch (IOException e) {
+ try {
+ file.delete();
+ } catch (SecurityException se) {
+ }
+ throw new CoreException(
+ new Status(
+ IStatus.ERROR,
+ JavaCore.PLUGIN_ID,
+ Platform.PLUGIN_ERROR,
+ Util
+ .bind(
+ "build.cannotSaveState", info.project.getName()), e)); //$NON-NLS-1$
+ }
+ if (PHPBuilder.DEBUG) {
+ t = System.currentTimeMillis() - t;
+ System.out.println(Util.bind(
+ "build.saveStateComplete", String.valueOf(t))); //$NON-NLS-1$
+ }
+ }
+
+ private synchronized Map containerClone(IJavaProject project) {
+ Map originalProjectContainers = (Map) this.containers.get(project);
+ if (originalProjectContainers == null)
+ return null;
+ Map projectContainers = new HashMap(originalProjectContainers.size());
+ projectContainers.putAll(originalProjectContainers);
+ return projectContainers;
+ }
+
+ /**
+ * @see ISaveParticipant
+ */
+ public void saving(ISaveContext context) throws CoreException {
+
+ // save container values on snapshot/full save
+ Preferences preferences = JavaCore.getPlugin().getPluginPreferences();
+ IJavaProject[] projects = getJavaModel().getJavaProjects();
+ for (int i = 0, length = projects.length; i < length; i++) {
+ IJavaProject project = projects[i];
+ // clone while iterating (see
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=59638)
+ Map projectContainers = containerClone(project);
+ if (projectContainers == null)
+ continue;
+ for (Iterator keys = projectContainers.keySet().iterator(); keys
+ .hasNext();) {
+ IPath containerPath = (IPath) keys.next();
+ // IClasspathContainer container = (IClasspathContainer)
+ // projectContainers.get(containerPath);
+ String containerKey = CP_CONTAINER_PREFERENCES_PREFIX
+ + project.getElementName() + "|" + containerPath;//$NON-NLS-1$
+ String containerString = CP_ENTRY_IGNORE;
+ // try {
+ // if (container != null) {
+ // containerString =
+ // ((JavaProject)project).encodeClasspath(container.getClasspathEntries(),
+ // null, false);
+ // }
+ // } catch(JavaModelException e){
+ // // could not encode entry: leave it as CP_ENTRY_IGNORE
+ // }
+ preferences.setDefault(containerKey, CP_ENTRY_IGNORE); // use
+ // this
+ // default
+ // to
+ // get
+ // rid
+ // of
+ // removed
+ // ones
+ preferences.setValue(containerKey, containerString);
+ }
+ }
+ JavaCore.getPlugin().savePluginPreferences();
+
+ // if (context.getKind() == ISaveContext.FULL_SAVE) {
+ // // will need delta since this save (see
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=38658)
+ // context.needDelta();
+ //
+ // // clean up indexes on workspace full save
+ // // (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=52347)
+ // IndexManager manager = this.indexManager;
+ // if (manager != null) {
+ // manager.cleanUpIndexes();
+ // }
+ // }
+
+ IProject savedProject = context.getProject();
+ if (savedProject != null) {
+ if (!JavaProject.hasJavaNature(savedProject))
+ return; // ignore
+ PerProjectInfo info = getPerProjectInfo(savedProject, true /*
+ * create
+ * info
+ */);
+ saveState(info, context);
+ return;
+ }
+
+ ArrayList vStats = null; // lazy initialized
+ for (Iterator iter = perProjectInfo.values().iterator(); iter.hasNext();) {
+ try {
+ PerProjectInfo info = (PerProjectInfo) iter.next();
+ saveState(info, context);
+ } catch (CoreException e) {
+ if (vStats == null)
+ vStats = new ArrayList();
+ vStats.add(e.getStatus());
+ }
+ }
+ if (vStats != null) {
+ IStatus[] stats = new IStatus[vStats.size()];
+ vStats.toArray(stats);
+ throw new CoreException(new MultiStatus(JavaCore.PLUGIN_ID,
+ IStatus.ERROR, stats,
+ Util.bind("build.cannotSaveStates"), null)); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * @see ISaveParticipant
+ */
+ // public void saving(ISaveContext context) throws CoreException {
+ //
+ // IProject savedProject = context.getProject();
+ // if (savedProject != null) {
+ // if (!JavaProject.hasJavaNature(savedProject)) return; // ignore
+ // PerProjectInfo info = getPerProjectInfo(savedProject, true /* create info
+ // */);
+ // saveState(info, context);
+ // return;
+ // }
+ //
+ // ArrayList vStats= null; // lazy initialized
+ // for (Iterator iter = perProjectInfo.values().iterator(); iter.hasNext();)
+ // {
+ // try {
+ // PerProjectInfo info = (PerProjectInfo) iter.next();
+ // saveState(info, context);
+ // } catch (CoreException e) {
+ // if (vStats == null)
+ // vStats= new ArrayList();
+ // vStats.add(e.getStatus());
+ // }
+ // }
+ // if (vStats != null) {
+ // IStatus[] stats= new IStatus[vStats.size()];
+ // vStats.toArray(stats);
+ // throw new CoreException(new MultiStatus(JavaCore.PLUGIN_ID,
+ // IStatus.ERROR, stats, Util.bind("build.cannotSaveStates"), null));
+ // //$NON-NLS-1$
+ // }
+ // }
+ /**
+ * Record the order in which to build the java projects (batch build). This
+ * order is based on the projects classpath settings.
+ */
+ protected void setBuildOrder(String[] javaBuildOrder)
+ throws JavaModelException {
+
+ // optional behaviour
+ // possible value of index 0 is Compute
+ if (!JavaCore.COMPUTE.equals(JavaCore
+ .getOption(JavaCore.CORE_JAVA_BUILD_ORDER)))
+ return; // cannot be customized at project level
+
+ if (javaBuildOrder == null || javaBuildOrder.length <= 1)
+ return;
+
+ IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ IWorkspaceDescription description = workspace.getDescription();
+ String[] wksBuildOrder = description.getBuildOrder();
+
+ String[] newOrder;
+ if (wksBuildOrder == null) {
+ newOrder = javaBuildOrder;
+ } else {
+ // remove projects which are already mentionned in java builder
+ // order
+ int javaCount = javaBuildOrder.length;
+ HashMap newSet = new HashMap(javaCount); // create a set for fast
+ // check
+ for (int i = 0; i < javaCount; i++) {
+ newSet.put(javaBuildOrder[i], javaBuildOrder[i]);
+ }
+ int removed = 0;
+ int oldCount = wksBuildOrder.length;
+ for (int i = 0; i < oldCount; i++) {
+ if (newSet.containsKey(wksBuildOrder[i])) {
+ wksBuildOrder[i] = null;
+ removed++;
+ }
+ }
+ // add Java ones first
+ newOrder = new String[oldCount - removed + javaCount];
+ System.arraycopy(javaBuildOrder, 0, newOrder, 0, javaCount); // java
+ // projects
+ // are
+ // built
+ // first
+
+ // copy previous items in their respective order
+ int index = javaCount;
+ for (int i = 0; i < oldCount; i++) {
+ if (wksBuildOrder[i] != null) {
+ newOrder[index++] = wksBuildOrder[i];
+ }
+ }
+ }
+ // commit the new build order out
+ description.setBuildOrder(newOrder);
+ try {
+ workspace.setDescription(description);
+ } catch (CoreException e) {
+ throw new JavaModelException(e);
+ }
+ }
+
+ /**
+ * Sets the last built state for the given project, or null to reset it.
+ */
+ public void setLastBuiltState(IProject project, Object state) {
+ if (!JavaProject.hasJavaNature(project))
+ return; // should never be requested on non-Java projects
+ PerProjectInfo info = getPerProjectInfo(project, true /*
+ * create if
+ * missing
+ */);
+ info.triedRead = true; // no point trying to re-read once using setter
+ info.savedState = state;
+ if (state == null) { // delete state file to ensure a full build
+ // happens if the workspace crashes
+ try {
+ File file = getSerializationFile(project);
+ if (file != null && file.exists())
+ file.delete();
+ } catch (SecurityException se) {
+ }
+ }
+ }
+
+ public void shutdown() {
+ // TODO temp-del
+ // if (this.deltaProcessor.indexManager != null){ // no more indexing
+ // this.deltaProcessor.indexManager.shutdown();
+ // }
+ try {
+ IJavaModel model = this.getJavaModel();
+ if (model != null) {
+
+ model.close();
+ }
+ } catch (JavaModelException e) {
+ }
+ }
+
+ /**
+ * Turns the firing mode to on. That is, deltas that are/have been
+ * registered will be fired.
+ */
+ public void startDeltas() {
+ this.isFiring = true;
+ }
+
+ /**
+ * Turns the firing mode to off. That is, deltas that are/have been
+ * registered will not be fired until deltas are started again.
+ */
+ public void stopDeltas() {
+ this.isFiring = false;
+ }
+
+ /**
+ * Update Java Model given some delta
+ */
+ public void updateJavaModel(IJavaElementDelta customDelta) {
+
+ if (customDelta == null) {
+ for (int i = 0, length = this.javaModelDeltas.size(); i < length; i++) {
+ IJavaElementDelta delta = (IJavaElementDelta) this.javaModelDeltas
+ .get(i);
+ this.modelUpdater.processJavaDelta(delta);
+ }
+ } else {
+ this.modelUpdater.processJavaDelta(customDelta);
+ }
+ }
+
+ public static IPath variableGet(String variableName) {
+ return (IPath) Variables.get(variableName);
+ }
+
+ public static String[] variableNames() {
+ int length = Variables.size();
+ String[] result = new String[length];
+ Iterator vars = Variables.keySet().iterator();
+ int index = 0;
+ while (vars.hasNext()) {
+ result[index++] = (String) vars.next();
+ }
+ return result;
+ }
+
+ public static void variablePut(String variableName, IPath variablePath) {
+
+ // update cache - do not only rely on listener refresh
+ if (variablePath == null) {
+ Variables.remove(variableName);
+ PreviousSessionVariables.remove(variableName);
+ } else {
+ Variables.put(variableName, variablePath);
+ }
+
+ // do not write out intermediate initialization value
+ if (variablePath == JavaModelManager.VariableInitializationInProgress) {
+ return;
+ }
+ Preferences preferences = JavaCore.getPlugin().getPluginPreferences();
+ String variableKey = CP_VARIABLE_PREFERENCES_PREFIX + variableName;
+ String variableString = variablePath == null ? CP_ENTRY_IGNORE
+ : variablePath.toString();
+ preferences.setDefault(variableKey, CP_ENTRY_IGNORE); // use this
+ // default to
+ // get rid of
+ // removed ones
+ preferences.setValue(variableKey, variableString);
+ JavaCore.getPlugin().savePluginPreferences();
+ }
+
+ /*
+ * Returns all the working copies which have the given owner. Adds the
+ * working copies of the primary owner if specified. Returns null if it has
+ * none.
+ */
+ public ICompilationUnit[] getWorkingCopies(WorkingCopyOwner owner,
+ boolean addPrimary) {
+ synchronized (perWorkingCopyInfos) {
+ ICompilationUnit[] primaryWCs = addPrimary
+ && owner != DefaultWorkingCopyOwner.PRIMARY ? getWorkingCopies(
+ DefaultWorkingCopyOwner.PRIMARY, false)
+ : null;
+ Map workingCopyToInfos = (Map) perWorkingCopyInfos.get(owner);
+ if (workingCopyToInfos == null)
+ return primaryWCs;
+ int primaryLength = primaryWCs == null ? 0 : primaryWCs.length;
+ int size = workingCopyToInfos.size(); // note size is > 0
+ // otherwise
+ // pathToPerWorkingCopyInfos
+ // would be null
+ ICompilationUnit[] result = new ICompilationUnit[primaryLength
+ + size];
+ if (primaryWCs != null) {
+ System.arraycopy(primaryWCs, 0, result, 0, primaryLength);
+ }
+ Iterator iterator = workingCopyToInfos.values().iterator();
+ int index = primaryLength;
+ while (iterator.hasNext()) {
+ result[index++] = ((JavaModelManager.PerWorkingCopyInfo) iterator
+ .next()).getWorkingCopy();
+ }
+ return result;
+ }
+ }
+
+ /*
+ * A HashSet that contains the IJavaProject whose classpath is being
+ * resolved.
+ */
+ private ThreadLocal classpathsBeingResolved = new ThreadLocal();
+
+ private HashSet getClasspathBeingResolved() {
+ HashSet result = (HashSet) this.classpathsBeingResolved.get();
+ if (result == null) {
+ result = new HashSet();
+ this.classpathsBeingResolved.set(result);
+ }
+ return result;
+ }
+
+ public boolean isClasspathBeingResolved(IJavaProject project) {
+ return getClasspathBeingResolved().contains(project);
+ }
+
+ public void setClasspathBeingResolved(IJavaProject project,
+ boolean classpathIsResolved) {
+ if (classpathIsResolved) {
+ getClasspathBeingResolved().add(project);
+ } else {
+ getClasspathBeingResolved().remove(project);
+ }
+ }
+}
--- /dev/null
+package net.sourceforge.phpdt.internal.corext.phpdoc;
+
+import java.io.FileReader;
+import java.io.IOException;
+
+import net.sourceforge.phpeclipse.builder.PHPIdentifierLocation;
+
+/**
+ * Utility class for static PHPdoc helper mehods
+ */
+public class PHPDocUtil {
+
+ /**
+ * Generate a PHPDoc hover text if possible
+ *
+ * @param hoverInfoBuffer
+ * @param filename
+ * @param location
+ */
+ public static void appendPHPDoc(StringBuffer hoverInfoBuffer,
+ String filename, PHPIdentifierLocation location) {
+ FileReader phpFileReader;
+ hoverInfoBuffer.append(location.toString());
+ hoverInfoBuffer.append(" - <b>");
+ try {
+ hoverInfoBuffer.append(getUsage(filename, location));
+ hoverInfoBuffer.append("</b><br>");
+
+ // read the phpdoc for the function
+ if (location.getPHPDocOffset() >= 0) {
+ phpFileReader = new FileReader(filename);
+ char[] phpDocDeclarationCharArray = new char[location
+ .getPHPDocLength()];
+ phpFileReader.skip(location.getPHPDocOffset());
+ phpFileReader.read(phpDocDeclarationCharArray, 0, location
+ .getPHPDocLength());
+ PHPDocCharArrayCommentReader phpdocConverter = new PHPDocCharArrayCommentReader(
+ phpDocDeclarationCharArray);
+ hoverInfoBuffer.append(phpdocConverter.getString());
+ // hoverInfoBuffer.append("<br><br>");
+ phpFileReader.close();
+ }
+
+ } catch (IOException e) {
+ return;
+ }
+ }
+
+ public static String getUsage(String filename,
+ PHPIdentifierLocation location) {
+ FileReader phpFileReader;
+ String usage = location.getUsage();
+ if (usage != null) {
+ return usage;
+ }
+ usage = "";
+ try {
+
+ phpFileReader = new FileReader(filename);
+ // read the function declaration
+ if (location.getOffset() >= 0
+ && (location.isMethod() || location.isConstructor()
+ || location.isFunction() || location.isDefine())) {
+ char[] functionDeclarationCharArray = new char[256];
+ int offset = location.getOffset();
+ phpFileReader.skip(offset);
+ int length = phpFileReader.read(functionDeclarationCharArray,
+ 0, 256);
+ if (length == -1) {
+ length = 256;
+ }
+ for (int i = 0; i < length; i++) {
+ if (functionDeclarationCharArray[i] == ')') {
+ length = i + 1;
+ break;
+ }
+ if (functionDeclarationCharArray[i] == '{'
+ || functionDeclarationCharArray[i] == '}') {
+ length = i;
+ break;
+ }
+ }
+ usage = new String(functionDeclarationCharArray, 0, length);
+ }
+ phpFileReader.close();
+ } catch (IOException e) {
+ // do nothing
+ }
+ // cache the usage string:
+ location.setUsage(usage);
+ return usage;
+ }
+}
--- /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.corext.util;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import net.sourceforge.phpdt.internal.corext.CorextMessages;
+import net.sourceforge.phpdt.internal.ui.IJavaStatusConstants;
+import net.sourceforge.phpdt.internal.ui.PHPUIStatus;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceStatus;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Status;
+
+public class Resources {
+
+ private Resources() {
+ }
+
+ /**
+ * Checks if the given resource is in sync with the underlying file system.
+ *
+ * @param resource
+ * the resource to be checked
+ * @return IStatus status describing the check's result. If <code>status.
+ * isOK()</code>
+ * returns <code>true</code> then the resource is in sync
+ */
+ public static IStatus checkInSync(IResource resource) {
+ return checkInSync(new IResource[] { resource });
+ }
+
+ /**
+ * Checks if the given resources are in sync with the underlying file
+ * system.
+ *
+ * @param resources
+ * the resources to be checked
+ * @return IStatus status describing the check's result. If <code>status.
+ * isOK() </code>
+ * returns <code>true</code> then the resources are in sync
+ */
+ public static IStatus checkInSync(IResource[] resources) {
+ IStatus result = null;
+ for (int i = 0; i < resources.length; i++) {
+ IResource resource = resources[i];
+ if (!resource.isSynchronized(IResource.DEPTH_INFINITE)) {
+ result = addOutOfSync(result, resource);
+ }
+ }
+ if (result != null)
+ return result;
+ return new Status(IStatus.OK, PHPeclipsePlugin.getPluginId(),
+ IStatus.OK, "", null); //$NON-NLS-1$
+ }
+
+ /**
+ * Makes the given resource committable. Committable means that it is
+ * writeable and that its content hasn't changed by calling
+ * <code>validateEdit</code> for the given resource on <tt>IWorkspace</tt>.
+ *
+ * @param resource
+ * the resource to be checked
+ * @param context
+ * the context passed to <code>validateEdit</code>
+ * @return status describing the method's result. If
+ * <code>status.isOK()</code> returns <code>true</code> then the
+ * resources are committable.
+ *
+ * @see org.eclipse.core.resources.IWorkspace#validateEdit(org.eclipse.core.resources.IFile[],
+ * java.lang.Object)
+ */
+ public static IStatus makeCommittable(IResource resource, Object context) {
+ return makeCommittable(new IResource[] { resource }, context);
+ }
+
+ /**
+ * Makes the given resources committable. Committable means that all
+ * resources are writeable and that the content of the resources hasn't
+ * changed by calling <code>validateEdit</code> for a given file on
+ * <tt>IWorkspace</tt>.
+ *
+ * @param resources
+ * the resources to be checked
+ * @param context
+ * the context passed to <code>validateEdit</code>
+ * @return IStatus status describing the method's result. If <code>status.
+ * isOK()</code>
+ * returns <code>true</code> then the add resources are
+ * committable
+ *
+ * @see org.eclipse.core.resources.IWorkspace#validateEdit(org.eclipse.core.resources.IFile[],
+ * java.lang.Object)
+ */
+ public static IStatus makeCommittable(IResource[] resources, Object context) {
+ List readOnlyFiles = new ArrayList();
+ for (int i = 0; i < resources.length; i++) {
+ IResource resource = resources[i];
+ if (resource.getType() == IResource.FILE
+ && resource.getResourceAttributes().isReadOnly())
+ readOnlyFiles.add(resource);
+ }
+ if (readOnlyFiles.size() == 0)
+ return new Status(IStatus.OK, PHPeclipsePlugin.getPluginId(),
+ IStatus.OK, "", null); //$NON-NLS-1$
+
+ Map oldTimeStamps = createModificationStampMap(readOnlyFiles);
+ IStatus status = ResourcesPlugin.getWorkspace().validateEdit(
+ (IFile[]) readOnlyFiles
+ .toArray(new IFile[readOnlyFiles.size()]), context);
+ if (!status.isOK())
+ return status;
+
+ IStatus modified = null;
+ Map newTimeStamps = createModificationStampMap(readOnlyFiles);
+ for (Iterator iter = oldTimeStamps.keySet().iterator(); iter.hasNext();) {
+ IFile file = (IFile) iter.next();
+ if (!oldTimeStamps.get(file).equals(newTimeStamps.get(file)))
+ modified = addModified(modified, file);
+ }
+ if (modified != null)
+ return modified;
+ return new Status(IStatus.OK, PHPeclipsePlugin.getPluginId(),
+ IStatus.OK, "", null); //$NON-NLS-1$
+ }
+
+ private static Map createModificationStampMap(List files) {
+ Map map = new HashMap();
+ for (Iterator iter = files.iterator(); iter.hasNext();) {
+ IFile file = (IFile) iter.next();
+ map.put(file, new Long(file.getModificationStamp()));
+ }
+ return map;
+ }
+
+ private static IStatus addModified(IStatus status, IFile file) {
+ IStatus entry = PHPUIStatus
+ .createError(
+ IJavaStatusConstants.VALIDATE_EDIT_CHANGED_CONTENT,
+ CorextMessages
+ .getFormattedString(
+ "Resources.fileModified", file.getFullPath().toString()), //$NON-NLS-1$
+ null);
+ if (status == null) {
+ return entry;
+ } else if (status.isMultiStatus()) {
+ ((MultiStatus) status).add(entry);
+ return status;
+ } else {
+ MultiStatus result = new MultiStatus(
+ PHPeclipsePlugin.getPluginId(),
+ IJavaStatusConstants.VALIDATE_EDIT_CHANGED_CONTENT,
+ CorextMessages.getString("Resources.modifiedResources"), null); //$NON-NLS-1$
+ result.add(status);
+ result.add(entry);
+ return result;
+ }
+ }
+
+ private static IStatus addOutOfSync(IStatus status, IResource resource) {
+ IStatus entry = new Status(
+ IStatus.ERROR,
+ ResourcesPlugin.PI_RESOURCES,
+ IResourceStatus.OUT_OF_SYNC_LOCAL,
+ CorextMessages
+ .getFormattedString(
+ "Resources.outOfSync", resource.getFullPath().toString()), //$NON-NLS-1$
+ null);
+ if (status == null) {
+ return entry;
+ } else if (status.isMultiStatus()) {
+ ((MultiStatus) status).add(entry);
+ return status;
+ } else {
+ MultiStatus result = new MultiStatus(ResourcesPlugin.PI_RESOURCES,
+ IResourceStatus.OUT_OF_SYNC_LOCAL, CorextMessages
+ .getString("Resources.outOfSyncResources"), null); //$NON-NLS-1$
+ result.add(status);
+ result.add(entry);
+ return result;
+ }
+ }
+
+ public static String[] getLocationOSStrings(IResource[] resources) {
+ List result = new ArrayList(resources.length);
+ for (int i = 0; i < resources.length; i++) {
+ IPath location = resources[i].getLocation();
+ if (location != null)
+ result.add(location.toOSString());
+ }
+ return (String[]) result.toArray(new String[result.size()]);
+ }
+}
--- /dev/null
+/***********************************************************************************************************************************
+ * Copyright (c) 2000, 2002 IBM Corp. 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 implementation Vicente Fernando - www.alfersoft.com.ar Christian Perkonig - remote debug
+ **********************************************************************************************************************************/
+package net.sourceforge.phpdt.internal.debug.core;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketTimeoutException;
+import java.util.Map;
+import java.util.Vector;
+
+import net.sourceforge.phpdt.internal.debug.core.breakpoints.PHPLineBreakpoint;
+import net.sourceforge.phpdt.internal.debug.core.model.PHPDebugTarget;
+import net.sourceforge.phpdt.internal.debug.core.model.PHPStackFrame;
+import net.sourceforge.phpdt.internal.debug.core.model.PHPThread;
+import net.sourceforge.phpdt.internal.debug.core.model.PHPVariable;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.model.IBreakpoint;
+
+public class PHPDBGProxy {
+
+ private ServerSocket server = null;
+ private BufferedReader reader = null;
+ private PHPDBGInterface DBGInt = null; // The DBG interface which is linked with the proxy
+ private PHPDebugTarget debugTarget = null;
+ private PHPDBGProxy thisProxy = null;
+ private PHPLoop phpLoop;
+ private PHPThread PHPMainThread;
+ private Socket socket;
+ private int port;
+ private boolean remote;
+ private boolean pathtranslation;
+ private Map pathmap;
+ private IPath remoteSourcePath;
+
+ /**
+ */
+ public PHPDBGProxy () {
+ thisProxy = this;
+ }
+
+ /**
+ * @param remote
+ * @param remoteSourcePath
+ * @param pathTranslate
+ * @param paths
+ */
+ public PHPDBGProxy (boolean remote, String remoteSourcePath, boolean pathTranslate, Map paths) {
+ thisProxy = this;
+ this.remote = remote;
+ this.remoteSourcePath = new Path (remoteSourcePath);
+ this.pathmap = paths;
+ this.pathtranslation = pathTranslate;
+ }
+
+ /**
+ *
+ */
+ public void start () {
+ createServerSocket (); // Create a server socket for communicatio with DBG
+
+ this.startPHPLoop (); //
+ }
+
+ /**
+ *
+ */
+ public void stop () {
+ phpLoop.setShouldStop (); // Notify the thread's 'run loop' to stop
+
+ if (DBGInt != null) { // If we have a DBG interface linked with this proxy
+ DBGInt.setShouldStop (); // Notify the DBG interface to stop the waiting for response
+ }
+
+ if (!remote) { // If it's not a remote proxy session
+ try {
+ getDebugTarget ().getProcess ().terminate (); //
+ } catch (DebugException e) {
+ e.printStackTrace ();
+ }
+ }
+
+ phpLoop.notifyWait ();
+ }
+
+ public void setTerminated () {
+ try {
+ PHPMainThread.terminate ();
+ }
+ catch (DebugException e) {
+ }
+ }
+
+ /**
+ * TODO Is this method called from anywhere?
+ *
+ * Returns a already created server socket, or
+ * creates a server socket if none exists, and
+ * returns the newly created one.
+ *
+ * @return A server socket
+ */
+ protected ServerSocket getServerSocket () throws IOException {
+ if (server == null) { // Do we have already a server socket
+ createServerSocket (); // No, then create one
+ }
+
+ return server; // Return the server socket
+ }
+
+ /**
+ * Find a free unused port between 10001 and 10101 if the current debug session
+ * is for remote debugging, and a unused port 7869 if it is used as non remote debugging.
+ *
+ * For remote debugging the used port is submitted with the URL.
+ * E.g. http://localhost/index.php?DBGSESSID=1@localhost:10001
+ * For non remote debugging (if PHPeclipse used e.g. php cli directly) no port
+ * can be submitted by parameter, and only the default port (7869) can be used.
+ *
+ * @note: The free dbg version doesn't allow to set the appropriate port within php.ini!
+ *
+ *
+ */
+ protected void createServerSocket () {
+ if (this.remote) {
+ port = SocketUtil.findUnusedLocalPort ("localhost", 10001, 10101); // Get the first free port in the range from 10001 to 10101
+ }
+ else {
+ port = SocketUtil.findUnusedLocalPort ("localhost", 7869, 7869); // Get the first free port in the range from 7869 to 7869
+ }
+
+ if (port == -1) { // Did we get a free port?
+ PHPDebugCorePlugin.log (5, "Cannot find free port!!!!"); // No, output a error message
+
+ return; // And return
+ }
+ try {
+ if (server == null) { // If there is no server socket yet
+ server = new ServerSocket (port); // create a server socket for the free port
+ //System.out.println("ServerSocket on port: " + port);
+ }
+ } catch (IOException e) {
+ PHPDebugCorePlugin.log (e);
+ stop ();
+ }
+ }
+
+ /**
+ *
+ */
+ public Socket getSocket () throws IOException {
+ return socket; // Return the socket
+ }
+
+ /**
+ * Set the DBG interface which is linked to this proxy
+ *
+ * @paran DBGInt The DGB interface which is linked with this proxy
+ */
+ protected void setDBGInterface (PHPDBGInterface DBGInt) {
+ this.DBGInt = DBGInt;
+ }
+
+ /**
+ * Get the DBG interface which is linked to this proxy
+ *
+ * @paran DBGInt The DGB interface which is linked with this proxy
+ */
+ public PHPDBGInterface getDBGInterface () {
+ return DBGInt;
+ }
+
+ /**
+ * Give back a buffered input stream for the socket which is
+ * linked with this proxy
+ */
+ public BufferedReader getReader () throws IOException {
+ if (reader == null) { // Do we already have a buffered input stream
+ reader = new BufferedReader (new InputStreamReader (this.getSocket ().getInputStream (),
+ "ISO8859_1"));
+ }
+
+ return reader; // Return the buffered input stream
+ }
+
+ /**
+ *
+ */
+ public BufferedReader getReader (Socket socket) throws IOException {
+ if (socket != null) { // Is a socket provided
+ return new BufferedReader (new InputStreamReader (socket.getInputStream (),
+ "ISO8859_1")); // Then create a buffered input stream
+ }
+ else {
+ return null; // Without a socket we can't create a input stream
+ }
+ }
+
+ /**
+ *
+ * @return The output stream for this proxy's socket
+ */
+ public OutputStream getOutputStream () throws IOException {
+ return this.getSocket ().getOutputStream ();
+ }
+
+ /**
+ *
+ */
+ protected void setBreakPoints () throws IOException, CoreException {
+ IBreakpoint[] breakpoints = DebugPlugin.getDefault ().getBreakpointManager ().getBreakpoints ();
+
+ for (int i = 0; i < breakpoints.length; i++) {
+ if (breakpoints[i].isEnabled ()) {
+ addBreakpoint (breakpoints[i]);
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ private String MapPath (PHPLineBreakpoint phpLBP) {
+ IPath filename;
+ IPath remotePath;
+ IPath newpath;
+ IPath localPath;
+ String local;
+
+ if (remote) {
+ filename = phpLBP.getMarker().getResource().getProjectRelativePath();
+ filename = remoteSourcePath.append (filename);
+ } else {
+ filename = phpLBP.getMarker().getResource().getLocation();
+ }
+
+ String path = filename.toOSString();
+
+ if ((pathmap != null) && remote) {
+ java.util.Iterator i = pathmap.keySet().iterator();
+
+ while (i.hasNext()) {
+ String k = (String) i.next();
+ if (path.startsWith(k)) {
+ path = pathmap.get(k) + path.substring(k.length());
+ break;
+ }
+ }
+ }
+
+ if (remoteSourcePath.isEmpty ()) {
+ if ((pathmap != null) && remote) {
+ java.util.Iterator iterator = pathmap.keySet().iterator();
+
+ while (iterator.hasNext ()) {
+ local = (String) iterator.next (); // Get the local/client side path of the mapping
+ remotePath = new Path ((String) pathmap.get (local)); // Get the remote/server side path of the mapping
+ localPath = new Path (local); // Get the remote/server side path of the mapping
+
+ if (localPath.isPrefixOf (filename)) { // Starts the remote/server side file path with the remote/server side mapping path
+ // dann prefix abhängen und den remote path davorhägen
+ newpath = filename.removeFirstSegments (localPath.matchingFirstSegments (filename));
+ newpath = remotePath.append (newpath);
+ path = newpath.toString ();
+
+ if (path.substring (0, 1).equals ("/")) {
+ path = path.replace ('\\', '/');
+ }
+ else {
+ path = path.replace ('/', '\\');
+ }
+
+ return path;
+ }
+ }
+ }
+ }
+ else {
+ if (pathtranslation && remote) {
+ if (remoteSourcePath.toString ().substring (0, 1).equals ("/")) {
+ path = path.replace ('\\', '/');
+ }
+ else {
+ path = path.replace ('/', '\\');
+ }
+ }
+ }
+
+ return path;
+ }
+
+ /**
+ *
+ */
+ public void addBreakpoint (IBreakpoint breakpoint) {
+ if (DBGInt == null) {
+ return;
+ }
+
+ int bpNo = 0;
+
+ try {
+ PHPLineBreakpoint phpLBP;
+
+ if (breakpoint.getModelIdentifier() == PHPDebugCorePlugin.getUniqueIdentifier()) {
+ phpLBP = (PHPLineBreakpoint) breakpoint;
+
+ // bpNo= DBGInt.addBreakpoint(phpLBP.getMarker().getResource().getLocation().toOSString(), phpLBP.getLineNumber());
+ if (phpLBP.isConditionEnabled ()) {
+ bpNo = DBGInt.addBreakpoint (MapPath(phpLBP),
+ phpLBP.getLineNumber(),
+ phpLBP.getHitCount(),
+ phpLBP.getCondition ());
+ }
+ else {
+ bpNo = DBGInt.addBreakpoint (MapPath(phpLBP),
+ phpLBP.getLineNumber(),
+ phpLBP.getHitCount(),
+ "");
+ }
+
+ phpLBP.setDBGBpNo(bpNo);
+ }
+ } catch (IOException e) {
+ PHPDebugCorePlugin.log(e);
+ stop();
+ } catch (CoreException e) {
+ PHPDebugCorePlugin.log(e);
+ stop();
+ }
+ }
+
+ /**
+ *
+ */
+ public void removeBreakpoint (IBreakpoint breakpoint) {
+ if (DBGInt == null) {
+ return;
+ }
+
+ try {
+ PHPLineBreakpoint phpLBP;
+
+ if (breakpoint.getModelIdentifier() == PHPDebugCorePlugin.getUniqueIdentifier ()) {
+ phpLBP = (PHPLineBreakpoint) breakpoint;
+
+ // bpNo= DBGInt.addBreakpoint(filename.toOSString(), phpLBP.getLineNumber());
+
+ DBGInt.removeBreakpoint(MapPath(phpLBP), phpLBP.getLineNumber(), phpLBP.getDBGBpNo());
+ }
+ } catch (IOException e) {
+ PHPDebugCorePlugin.log (e);
+ stop ();
+ } catch (CoreException e) {
+ PHPDebugCorePlugin.log (e);
+ stop ();
+ }
+ }
+
+ /**
+ *
+ */
+ public void phpLoopNotify () {
+ phpLoop.notifyWait ();
+ }
+
+ /**
+ *
+ */
+ public void startPHPLoop () {
+ phpLoop = new PHPLoop (); // Create a DBG communication loop object
+
+ phpLoop.start (); // And start the communication loop
+ }
+
+ /**
+ *
+ */
+ public void resume () {
+ try {
+ DBGInt.continueExecution();
+ phpLoop.notifyWait();
+ } catch (IOException e) {
+ PHPeclipsePlugin.log("Debugging session ended.", e);
+ stop();
+ }
+ }
+
+ /**
+ *
+ */
+ public void pause () {
+ try {
+ if (null != DBGInt) {
+ DBGInt.pauseExecution();
+ }
+ else {
+ // TODO Make sure the Suspend action is grayed out
+ // when DBGInt is null
+ }
+ } catch (IOException e) {
+ PHPDebugCorePlugin.log (e);
+ stop ();
+ }
+ }
+
+ /**
+ *
+ */
+ protected PHPDebugTarget getDebugTarget() {
+ return debugTarget;
+ }
+
+ /**
+ * Is called by the DebuggerRunner
+ *
+ * @param debugTarget
+ */
+ public void setDebugTarget (PHPDebugTarget debugTarget) {
+ this.debugTarget = debugTarget;
+ debugTarget.setPHPDBGProxy(this);
+ }
+
+ /**
+ * This method is called by a stackframe.
+ * It reads the variables from PHP via DBG
+ *
+ * @param frame The stackframe which wants the variables.
+ * @return The list of variables for this stackframe.
+ */
+ public Vector readVariables (PHPStackFrame frame) {
+ try {
+ return DBGInt.getVariables (frame); // Get the variables from DBG interface
+ } catch (IOException ioex) {
+ ioex.printStackTrace ();
+ throw new RuntimeException (ioex.getMessage ());
+ } catch (DebugException ex) {
+ ex.printStackTrace ();
+ throw new RuntimeException (ex.getMessage ());
+ }
+ }
+
+ /**
+ *
+ * @param frame
+ * @param evalString
+ * @return
+ */
+ public PHPVariable[] eval (PHPStackFrame frame, String evalString) {
+ try {
+ return DBGInt.evalBlock (frame, evalString);
+ //return DBGInt.getVariables(frame);
+ } catch (IOException ioex) {
+ ioex.printStackTrace();
+ throw new RuntimeException(ioex.getMessage());
+ } catch (DebugException ex) {
+ ex.printStackTrace();
+ throw new RuntimeException(ex.getMessage());
+ }
+ }
+
+ public void readStepOverEnd (PHPStackFrame stackFrame) {
+ try {
+ DBGInt.stepOver();
+ phpLoop.notifyWait();
+ } catch (Exception e) {
+ PHPDebugCorePlugin.log(e);
+ }
+ }
+
+ public void readStepReturnEnd (PHPStackFrame stackFrame) {
+ try {
+ DBGInt.stepOut();
+ phpLoop.notifyWait();
+ } catch (Exception e) {
+ PHPDebugCorePlugin.log(e);
+ }
+ }
+
+ public void readStepIntoEnd (PHPStackFrame stackFrame) {
+ try {
+ DBGInt.stepInto();
+ phpLoop.notifyWait();
+ } catch (Exception e) {
+ PHPDebugCorePlugin.log(e);
+ }
+ }
+
+ /*
+ * public PHPStackFrame[] readFrames(PHPThread thread) { //try { //this.println("th " + thread.getId() + " ; f "); //return new
+ * FramesReader(getMultiReaderStrategy()).readFrames(thread); return null; //} catch (IOException e) { //
+ * PHPDebugCorePlugin.log(e); // return null; //}
+ * }
+ */
+
+ public void closeSocket() throws IOException {
+ if (socket != null) {
+ socket.close();
+ }
+ }
+
+ public void closeServerSocket() throws IOException {
+ if (server != null) {
+ server.close();
+ }
+ }
+
+ public int getPort() {
+ return port;
+ }
+
+ /**
+ *
+ *
+ */
+ class PHPLoop extends Thread {
+ private boolean shouldStop;
+
+ public PHPLoop () {
+ shouldStop = false;
+ this.setName ("PHPDebuggerLoop");
+ }
+
+ /**
+ *
+ */
+ public synchronized void setShouldStop () {
+ shouldStop = true; // The run loop should stop
+
+ try {
+ // If the loop thread is blocked on the server socket,
+ // forcibly unblock it to avoid leaking the thread,
+ // the socket and the port
+ closeServerSocket ();
+ } catch (IOException x) {
+ // Log this as a warning?
+ PHPDebugCorePlugin.log (x);
+ }
+ }
+
+ /**
+ *
+ */
+ public synchronized void notifyWait () {
+ notify ();
+ }
+
+ /**
+ *
+ *
+ */
+ public void run () {
+ try {
+ int i;
+ int timeout;
+ long interval = 200; // Wait 200 ms maximum for a DBG response
+ boolean newconnect = false; //
+ Socket newSocket = null;
+ PHPStackFrame[] StackList;
+ PHPDBGInterface newDBGInt;
+
+ // synchronized (this) {
+ // wait();
+ // }
+
+ PHPMainThread = new PHPThread (getDebugTarget (), getPort ());
+ PHPMainThread.setName ("Thread [main]");
+ timeout = 0;
+
+ // while ((getDebugTarget() == null) && (timeout < 100)) {
+ // sleep(100);
+ // timeout++;
+ // }
+ // Be sure debug target is set
+ // PHPMainThread.setDebugTarget(getDebugTarget());
+
+ getDebugTarget ().addThread (PHPMainThread);
+
+ //System.out.println("Waiting for breakpoints.");
+
+ while (!shouldStop) { // As long as nobody will stop us
+ newconnect = true; // The first time
+
+ try {
+ newSocket = server.accept(); // Waits until DBG want to connect
+ //System.out.println("Accepted! : " + socket.toString());
+ } catch (SocketTimeoutException e) {
+ newconnect = false; // No one wants to connect (connection already done)
+ } catch (IOException e) {
+ PHPDebugCorePlugin.log(e);
+ return;
+ }
+
+ if (newconnect) { // Is it just after a new connection
+ if (DBGInt == null) { // Do we have a DBG interface?
+ server.setSoTimeout(1); // ???
+ }
+
+ newDBGInt = new PHPDBGInterface (getReader (newSocket), // Create a new interface
+ newSocket.getOutputStream (),
+ thisProxy);
+ newDBGInt.waitResponse (1000); // Wait for the initial DBG response
+ newDBGInt.flushAllPackets (); // Read and process the DBG response
+
+ // Check version and session ID
+ if ((DBGInt == null) || // If we have no interface
+ (DBGInt.getSID () == newDBGInt.getSID ())) {// or the new session ID is different to the old one
+ DBGInt = newDBGInt; // Set the new interface as current one
+
+ try {
+ closeSocket ();
+ }
+ catch (IOException e) {
+ PHPDebugCorePlugin.log (e);
+ shouldStop = true;
+ }
+
+ socket = newSocket;
+ setBreakPoints ();
+ DBGInt.continueExecution (); // Notify DBG that PHP should continue
+ }
+ else {
+ newDBGInt.continueExecution (); // Notify DBG that PHP should continue
+ newSocket.close ();
+ }
+ }
+
+ if (DBGInt.waitResponse (interval)) { // Wait for a DBG response (200 ms)
+ DBGInt.flushAllPackets (); // If we got something, read and process it
+
+ if (DBGInt.BPUnderHit != 0) { // ???
+ StackList = DBGInt.getStackList (); // Get the stack list from DBGInterface
+
+ if (StackList.length > 0) { // If there is something in stack list
+ for (i = 0; i < StackList.length; i++) { // For all stack list
+ StackList[i].setThread (PHPMainThread); // Set the PHPTread for all PHPStackFrames
+
+ if (DBGInt.getModByNo (StackList[i].getModNo ()).equals ("")) {
+ DBGInt.getSourceTree ();
+ }
+
+ StackList[i].setFile (DBGInt.getModByNo (StackList[i].getModNo ()));
+ }
+
+ PHPMainThread.setStackFrames (StackList);
+ }
+
+ PHPMainThread.suspend (); // Fire debug event
+
+ synchronized (this) {
+ wait ();
+ }
+ }
+ }
+
+ if (remote) {
+ if (PHPMainThread.isTerminated ()) {
+ shouldStop = true;
+
+ break; // Go for terminating the thread
+ }
+ } else {
+ if (PHPMainThread.isTerminated () ||
+ getDebugTarget ().getProcess ().isTerminated ()) {
+ shouldStop = true;
+
+ break; // Go for terminating the thread
+ }
+ }
+ }
+ } catch (Exception ex) {
+ PHPDebugCorePlugin.log (ex);
+ System.out.println (ex);
+ } finally {
+ try {
+ getDebugTarget ().terminate ();
+ closeSocket();
+ closeServerSocket ();
+ } catch (IOException e) {
+ PHPDebugCorePlugin.log (e);
+
+ return;
+ }
+
+ //System.out.println("Socket loop finished.");
+ }
+ }
+ }
+}
--- /dev/null
+package net.sourceforge.phpdt.internal.debug.ui.launcher;
+
+import net.sourceforge.phpdt.internal.debug.ui.PHPDebugUiPlugin;
+import net.sourceforge.phpeclipse.LoadPathEntry;
+
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * @author xp4
+ *
+ * To change this generated comment edit the template variable "typecomment":
+ * Window>Preferences>Java>Templates.
+ */
+public class LoadPathEntryLabelProvider implements ILabelProvider {
+
+ /**
+ * @see ILabelProvider#getImage(Object)
+ */
+ public Image getImage(Object element) {
+ return null;
+ }
+
+ /**
+ * @see ILabelProvider#getText(Object)
+ */
+ public String getText(Object element) {
+ if (element != null && element.getClass() == LoadPathEntry.class)
+ return ((LoadPathEntry) element).getProject().getLocation()
+ .toOSString();
+
+ PHPDebugUiPlugin
+ .log(new RuntimeException("Unable to render load path."));
+ return null;
+ }
+
+ /**
+ * @see IBaseLabelProvider#addListener(ILabelProviderListener)
+ */
+ public void addListener(ILabelProviderListener listener) {
+ }
+
+ /**
+ * @see IBaseLabelProvider#dispose()
+ */
+ public void dispose() {
+ }
+
+ /**
+ * @see IBaseLabelProvider#isLabelProperty(Object, String)
+ */
+ public boolean isLabelProperty(Object element, String property) {
+ return false;
+ }
+
+ /**
+ * @see IBaseLabelProvider#removeListener(ILabelProviderListener)
+ */
+ public void removeListener(ILabelProviderListener listener) {
+ }
+
+}
--- /dev/null
+package net.sourceforge.phpdt.internal.debug.ui.launcher;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import net.sourceforge.phpdt.internal.debug.ui.PHPDebugUiMessages;
+import net.sourceforge.phpdt.internal.debug.ui.PHPDebugUiPlugin;
+import net.sourceforge.phpdt.internal.debug.ui.preferences.EditPathMapDialog;
+import net.sourceforge.phpdt.internal.debug.ui.preferences.PHPInterpreterPreferencePage;
+import net.sourceforge.phpdt.internal.launching.PHPInterpreter;
+import net.sourceforge.phpdt.internal.launching.PHPLaunchConfigurationAttribute;
+import net.sourceforge.phpdt.internal.launching.PHPRuntime;
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
+import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.ListViewer;
+import org.eclipse.jface.viewers.TableLayout;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.Text;
+
+public class PHPEnvironmentTab extends AbstractLaunchConfigurationTab {
+ protected ListViewer loadPathListViewer;
+
+ protected java.util.List installedInterpretersWorkingCopy;
+
+ protected Combo interpreterCombo;
+
+ // protected Button loadPathDefaultButton;
+ protected Button fRemoteDebugCheckBox;
+
+ protected Button fRemoteDebugTranslate;
+
+ protected Button fOpenDBGSessionInBrowserCheckBox;
+
+ protected Button fPathMapRemoveButton;
+
+ protected Button fPathMapAddButton;
+
+ protected Button fPathMapEditButton;
+
+ protected Text fRemoteSourcePath;
+
+ protected Table fRemoteDebugPathMapTable;
+
+ protected TabFolder tabFolder;
+
+ private class RemoteDebugTabListener extends SelectionAdapter implements
+ ModifyListener {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent)
+ */
+ public void modifyText(ModifyEvent e) {
+ updateLaunchConfigurationDialog();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ public void widgetSelected(SelectionEvent e) {
+ Object source = e.getSource();
+ if (source == fRemoteDebugPathMapTable) {
+ setPathMapButtonsEnableState();
+ } else if (source == fPathMapAddButton) {
+ handlePathMapAddButtonSelected();
+ } else if (source == fPathMapEditButton) {
+ handlePathMapEditButtonSelected();
+ } else if (source == fPathMapRemoveButton) {
+ handlePathMapRemoveButtonSelected();
+ } else if (source == fRemoteDebugCheckBox) {
+ setRemoteTabEnableState();
+ } else if (source == fRemoteDebugTranslate) {
+ setRemoteTabEnableState();
+ } else {
+ updateLaunchConfigurationDialog();
+ ;
+ }
+
+ }
+
+ }
+
+ private static final String EMPTY_STRING = ""; //$NON-NLS-1$
+
+ private RemoteDebugTabListener fListener = new RemoteDebugTabListener();
+
+ private static final boolean DEFAULT_REMOTE_DEBUG = false;
+
+ private static final boolean DEFAULT_REMOTE_DEBUG_TRANSLATE = false;
+
+ private static final boolean DEFAULT_OPEN_DBGSESSION_IN_BROWSER = true;
+
+ static String[] columnTitles = {
+ PHPDebugUiMessages
+ .getString("LaunchConfigurationTab.PHPEnvironment.remoteDebugTab.PathMapTableTitle.local"),
+ PHPDebugUiMessages
+ .getString("LaunchConfigurationTab.PHPEnvironment.remoteDebugTab.PathMapTableTitle.remote") };
+
+ public PHPEnvironmentTab() {
+ super();
+ }
+
+ public void createControl(Composite parent) {
+ Composite composite = createPageRoot(parent);
+
+ tabFolder = new TabFolder(composite, SWT.NONE);
+ GridData gridData = new GridData(GridData.FILL_BOTH);
+ tabFolder.setLayoutData(gridData);
+
+ // addLoadPathTab(tabFolder);
+ addInterpreterTab(tabFolder);
+ addRemoteDebugTab(tabFolder);
+ }
+
+ protected void addRemoteDebugTab(TabFolder tabFolder) {
+ Label label;
+
+ TabItem remoteDebugTab = new TabItem(tabFolder, SWT.NONE, 0);
+ remoteDebugTab
+ .setText(PHPDebugUiMessages
+ .getString("LaunchConfigurationTab.PHPEnvironment.remoteDebugTab.label"));
+
+ Composite comp = new Composite(tabFolder, SWT.NONE);
+ comp.setLayout(new GridLayout());
+ remoteDebugTab.setControl(comp);
+ GridData gd;
+
+ fRemoteDebugCheckBox = new Button(comp, SWT.CHECK);
+ fRemoteDebugCheckBox
+ .setText(PHPDebugUiMessages
+ .getString("LaunchConfigurationTab.PHPEnvironment.remoteDebugTab.RemoteCheckBox.label"));
+ fRemoteDebugCheckBox.setLayoutData(new GridData(
+ GridData.HORIZONTAL_ALIGN_BEGINNING));
+ fRemoteDebugCheckBox.addSelectionListener(fListener);
+
+ fRemoteDebugTranslate = new Button(comp, SWT.CHECK);
+ fRemoteDebugTranslate
+ .setText(PHPDebugUiMessages
+ .getString("LaunchConfigurationTab.PHPEnvironment.remoteDebugTab.RemoteTranslate.label"));
+ fRemoteDebugTranslate.setLayoutData(new GridData(
+ GridData.HORIZONTAL_ALIGN_BEGINNING));
+ fRemoteDebugTranslate.addSelectionListener(fListener);
+
+ fOpenDBGSessionInBrowserCheckBox = new Button(comp, SWT.CHECK);
+ fOpenDBGSessionInBrowserCheckBox
+ .setText(PHPDebugUiMessages
+ .getString("LaunchConfigurationTab.PHPEnvironment.remoteDebugTab.OpenDBGSessionInBrowserCheckBox.label"));
+ fOpenDBGSessionInBrowserCheckBox.setLayoutData(new GridData(
+ GridData.HORIZONTAL_ALIGN_BEGINNING));
+ fOpenDBGSessionInBrowserCheckBox.addSelectionListener(fListener);
+
+ label = new Label(comp, SWT.NONE);
+ label
+ .setText(PHPDebugUiMessages
+ .getString("LaunchConfigurationTab.PHPEnvironment.remoteDebugTab.RemoteSourcePath.label"));
+ fRemoteSourcePath = new Text(comp, SWT.BORDER | SWT.SINGLE);
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ fRemoteSourcePath.setLayoutData(gd);
+ fRemoteSourcePath.addModifyListener(fListener);
+
+ createVerticalSpacer(comp, 1);
+
+ Composite pathMapComp = new Composite(comp, SWT.NONE);
+ gd = new GridData(GridData.FILL_BOTH);
+ pathMapComp.setLayoutData(gd);
+ GridLayout parametersLayout = new GridLayout();
+ parametersLayout.numColumns = 2;
+ parametersLayout.marginHeight = 0;
+ parametersLayout.marginWidth = 0;
+ pathMapComp.setLayout(parametersLayout);
+
+ Label pathMapLabel = new Label(pathMapComp, SWT.NONE);
+ pathMapLabel
+ .setText(PHPDebugUiMessages
+ .getString("LaunchConfigurationTab.PHPEnvironment.remoteDebugTab.PathMap.label"));
+ gd = new GridData();
+ gd.horizontalSpan = 2;
+ pathMapLabel.setLayoutData(gd);
+
+ fRemoteDebugPathMapTable = new Table(pathMapComp, SWT.BORDER
+ | SWT.MULTI);
+ TableLayout tableLayout = new TableLayout();
+ fRemoteDebugPathMapTable.setLayout(tableLayout);
+
+ gd = new GridData(GridData.FILL_BOTH);
+ fRemoteDebugPathMapTable.setLayoutData(gd);
+ TableColumn column1 = new TableColumn(this.fRemoteDebugPathMapTable,
+ SWT.NONE);
+ column1
+ .setText(PHPDebugUiMessages
+ .getString("LaunchConfigurationTab.PHPEnvironment.remoteDebugTab.PathMap.Table.Title.local")); //$NON-NLS-1$
+ TableColumn column2 = new TableColumn(this.fRemoteDebugPathMapTable,
+ SWT.NONE);
+ column2
+ .setText(PHPDebugUiMessages
+ .getString("LaunchConfigurationTab.PHPEnvironment.remoteDebugTab.PathMap.Table.Title.remote")); //$NON-NLS-1$
+ tableLayout.addColumnData(new ColumnWeightData(100));
+ tableLayout.addColumnData(new ColumnWeightData(100));
+ fRemoteDebugPathMapTable.setHeaderVisible(true);
+ fRemoteDebugPathMapTable.setLinesVisible(true);
+ fRemoteDebugPathMapTable.addSelectionListener(fListener);
+ fRemoteDebugPathMapTable.addMouseListener(new MouseAdapter() {
+ public void mouseDoubleClick(MouseEvent e) {
+ setPathMapButtonsEnableState();
+ if (fPathMapEditButton.isEnabled()) {
+ handlePathMapEditButtonSelected();
+ }
+ }
+ });
+ // fRemoteDebugPathMapTable.setEnabled(false);
+
+ Composite envButtonComp = new Composite(pathMapComp, SWT.NONE);
+ GridLayout envButtonLayout = new GridLayout();
+ envButtonLayout.marginHeight = 0;
+ envButtonLayout.marginWidth = 0;
+ envButtonComp.setLayout(envButtonLayout);
+ gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING
+ | GridData.HORIZONTAL_ALIGN_FILL);
+ envButtonComp.setLayoutData(gd);
+
+ fPathMapAddButton = createPushButton(
+ envButtonComp,
+ PHPDebugUiMessages
+ .getString("LaunchConfigurationTab.PHPEnvironment.remoteDebugTab.PathMap.Button.Add.label"), null); //$NON-NLS-1$
+ fPathMapAddButton.addSelectionListener(fListener);
+ // fPathMapAddButton.setEnabled(false);
+
+ fPathMapEditButton = createPushButton(
+ envButtonComp,
+ PHPDebugUiMessages
+ .getString("LaunchConfigurationTab.PHPEnvironment.remoteDebugTab.PathMap.Button.Edit.label"), null); //$NON-NLS-1$
+ fPathMapEditButton.addSelectionListener(fListener);
+ // fPathMapEditButton.setEnabled(false);
+
+ fPathMapRemoveButton = createPushButton(
+ envButtonComp,
+ PHPDebugUiMessages
+ .getString("LaunchConfigurationTab.PHPEnvironment.remoteDebugTab.PathMap.Button.Remove.label"), null); //$NON-NLS-1$
+ fPathMapRemoveButton.addSelectionListener(fListener);
+ // fPathMapRemoveButton.setEnabled(false);
+
+ }
+
+ void handlePathMapAddButtonSelected() {
+ EditPathMapDialog dialog = new EditPathMapDialog(getShell(),
+ "Edit File Map", new String[] { EMPTY_STRING, EMPTY_STRING });
+ openNewPathMapDialog(dialog, null);
+ // dialog.create();
+ // if (dialog.open()==EditPathMapDialog.OK)
+ // {
+ // TableItem item = new TableItem (fRemoteDebugPathMapTable, SWT.NONE);
+ // item.setText(0,dialog.getLocalPath());
+ // item.setText(1,dialog.getRemotePath());
+ // updateLaunchConfigurationDialog();
+ // }
+ // updateLaunchConfigurationDialog();
+ setPathMapButtonsEnableState();
+ }
+
+ void handlePathMapRemoveButtonSelected() {
+ int[] selectedIndices = this.fRemoteDebugPathMapTable
+ .getSelectionIndices();
+ this.fRemoteDebugPathMapTable.remove(selectedIndices);
+ setPathMapButtonsEnableState();
+ updateLaunchConfigurationDialog();
+ }
+
+ void handlePathMapEditButtonSelected() {
+ TableItem selectedItem = this.fRemoteDebugPathMapTable.getSelection()[0];
+ String local = selectedItem.getText(0);
+ String remote = selectedItem.getText(1);
+ EditPathMapDialog dialog = new EditPathMapDialog(getShell(),
+ "Edit File Map", new String[] { local, remote });
+ openNewPathMapDialog(dialog, selectedItem);
+ }
+
+ /**
+ * Set the enabled state of whole tab.
+ */
+ private void setRemoteTabEnableState() {
+ boolean state = fRemoteDebugCheckBox.getSelection();
+ fRemoteSourcePath.setEnabled(state);
+ fRemoteDebugTranslate.setEnabled(state);
+
+ fRemoteDebugPathMapTable.setEnabled(state);
+ if (!state) {
+ fPathMapEditButton.setEnabled(false);
+ fPathMapRemoveButton.setEnabled(false);
+ fPathMapAddButton.setEnabled(false);
+ fOpenDBGSessionInBrowserCheckBox.setEnabled(false);
+ } else {
+ setPathMapButtonsEnableState();
+ }
+
+ updateLaunchConfigurationDialog();
+ }
+
+ /**
+ * Set the enabled state of the three environment variable-related buttons
+ * based on the selection in the PathMapTable widget.
+ */
+ private void setPathMapButtonsEnableState() {
+ // just do nothing for now
+ //
+ if (fRemoteDebugCheckBox.getSelection()) {
+ fOpenDBGSessionInBrowserCheckBox.setEnabled(true);
+ fRemoteDebugTranslate.setEnabled(true);
+ int selectCount = this.fRemoteDebugPathMapTable
+ .getSelectionIndices().length;
+ if (selectCount < 1) {
+ fPathMapEditButton.setEnabled(false);
+ fPathMapRemoveButton.setEnabled(false);
+ } else {
+ fPathMapRemoveButton.setEnabled(true);
+ if (selectCount == 1) {
+ fPathMapEditButton.setEnabled(true);
+ } else {
+ fPathMapEditButton.setEnabled(false);
+ }
+ }
+ fPathMapAddButton.setEnabled(true);
+ }
+ }
+
+ /**
+ * Show the specified dialog and update the pathMapTable table based on its
+ * results.
+ *
+ * @param updateItem
+ * the item to update, or <code>null</code> if adding a new
+ * item
+ */
+ private void openNewPathMapDialog(EditPathMapDialog dialog,
+ TableItem updateItem) {
+ if (dialog.open() != EditPathMapDialog.OK) {
+ return;
+ }
+ String[] pathPair = dialog.getPathPair();
+ TableItem tableItem = updateItem;
+ if (tableItem == null) {
+ tableItem = getTableItemForName(pathPair[0]);
+ if (tableItem == null) {
+ tableItem = new TableItem(this.fRemoteDebugPathMapTable,
+ SWT.NONE);
+ }
+ }
+ tableItem.setText(pathPair);
+ this.fRemoteDebugPathMapTable
+ .setSelection(new TableItem[] { tableItem });
+ updateLaunchConfigurationDialog();
+ }
+
+ /**
+ * Helper method that indicates whether the specified parameter name is
+ * already present in the parameters table.
+ */
+ private TableItem getTableItemForName(String candidateName) {
+ TableItem[] items = this.fRemoteDebugPathMapTable.getItems();
+ for (int i = 0; i < items.length; i++) {
+ String name = items[i].getText(0);
+ if (name.equals(candidateName)) {
+ return items[i];
+ }
+ }
+ return null;
+ }
+
+ // protected void addLoadPathTab(TabFolder tabFolder) {
+ // Composite loadPathComposite = new Composite(tabFolder, SWT.NONE);
+ // loadPathComposite.setLayout(new GridLayout());
+ //
+ // loadPathListViewer = new ListViewer(loadPathComposite, SWT.BORDER |
+ // SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL);
+ // loadPathListViewer.setContentProvider(new ListContentProvider());
+ // loadPathListViewer.setLabelProvider(new LoadPathEntryLabelProvider());
+ // loadPathListViewer.getList().setLayoutData(new
+ // GridData(GridData.FILL_BOTH));
+ //
+ // TabItem loadPathTab = new TabItem(tabFolder, SWT.NONE, 0);
+ // loadPathTab.setText(PHPDebugUiMessages.getString("LaunchConfigurationTab.PHPEnvironment.loadPathTab.label"));
+ // loadPathTab.setControl(loadPathComposite);
+ // loadPathTab.setData(loadPathListViewer);
+
+ // loadPathDefaultButton = new Button(loadPathComposite, SWT.CHECK);
+ // loadPathDefaultButton.setText(PHPDebugUiMessages.getString("LaunchConfigurationTab.PHPEnvironment.loadPathDefaultButton.label"));
+ // loadPathDefaultButton.setLayoutData(new
+ // GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+ // loadPathDefaultButton.addSelectionListener(getLoadPathDefaultButtonSelectionListener());
+ //
+ // loadPathDefaultButton.setEnabled(false); //for now, until the load path
+ // is customizable on the configuration
+ // }
+
+ protected SelectionListener getLoadPathSelectionListener() {
+ return new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ System.out.println("Loadpath list selection occurred: "
+ + e.getSource());
+ }
+ };
+ }
+
+ protected SelectionListener getLoadPathDefaultButtonSelectionListener() {
+ return new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ setUseLoadPathDefaults(((Button) e.getSource()).getSelection());
+ }
+ };
+ }
+
+ protected void addInterpreterTab(TabFolder tabFolder) {
+ Composite interpreterComposite = new Composite(tabFolder, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 2;
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ interpreterComposite.setLayout(layout);
+ interpreterComposite.setLayoutData(new GridData(
+ GridData.FILL_HORIZONTAL));
+
+ createVerticalSpacer(interpreterComposite, 2);
+
+ interpreterCombo = new Combo(interpreterComposite, SWT.READ_ONLY);
+ interpreterCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ initializeInterpreterCombo(interpreterCombo);
+ interpreterCombo.addModifyListener(getInterpreterComboModifyListener());
+
+ Button interpreterAddButton = new Button(interpreterComposite, SWT.PUSH);
+ interpreterAddButton
+ .setText(PHPDebugUiMessages
+ .getString("LaunchConfigurationTab.PHPEnvironment.interpreterAddButton.label"));
+ interpreterAddButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ PHPInterpreter newInterpreter = new PHPInterpreter(null);
+ File phpRuntime = PHPInterpreterPreferencePage.getFile(
+ getShell(), null);
+ if (phpRuntime != null) {
+ newInterpreter.setInstallLocation(phpRuntime);
+ PHPRuntime.getDefault().addInstalledInterpreter(
+ newInterpreter);
+ interpreterCombo.add(newInterpreter.getInstallLocation()
+ .toString());
+ interpreterCombo.select(interpreterCombo
+ .indexOf(newInterpreter.getInstallLocation()
+ .toString()));
+ }
+ }
+ });
+
+ TabItem interpreterTab = new TabItem(tabFolder, SWT.NONE);
+ interpreterTab
+ .setText(PHPDebugUiMessages
+ .getString("LaunchConfigurationTab.PHPEnvironment.interpreterTab.label"));
+ interpreterTab.setControl(interpreterComposite);
+ }
+
+ protected ModifyListener getInterpreterComboModifyListener() {
+ return new ModifyListener() {
+ public void modifyText(ModifyEvent evt) {
+ updateLaunchConfigurationDialog();
+ }
+ };
+ }
+
+ protected void createVerticalSpacer(Composite comp, int colSpan) {
+ Label label = new Label(comp, SWT.NONE);
+ GridData gd = new GridData();
+ gd.horizontalSpan = colSpan;
+ label.setLayoutData(gd);
+ }
+
+ public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
+ PHPInterpreter selectedInterpreter = PHPRuntime.getDefault()
+ .getSelectedInterpreter();
+ if (selectedInterpreter != null) {
+ String interpreterLocation = selectedInterpreter
+ .getInstallLocation().toString();
+ configuration.setAttribute(
+ PHPLaunchConfigurationAttribute.SELECTED_INTERPRETER,
+ interpreterLocation);
+ }
+ try {
+ String projectName = configuration.getAttribute(
+ PHPLaunchConfigurationAttribute.PROJECT_NAME, "");
+ if (projectName != "") {
+ IProject project = ResourcesPlugin.getWorkspace().getRoot()
+ .getProject(projectName);
+ if (project != null) {
+ IPath remotePath = project.getLocation();
+ String fileName = configuration.getAttribute(
+ PHPLaunchConfigurationAttribute.FILE_NAME, "");
+ if (fileName != "") {
+ Path filePath = new Path(fileName);
+ remotePath = remotePath.append(filePath
+ .removeLastSegments(1));
+ }
+ configuration.setAttribute(
+ PHPLaunchConfigurationAttribute.REMOTE_PATH,
+ remotePath.toOSString());
+ }
+ }
+ } catch (CoreException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ public void initializeFrom(ILaunchConfiguration configuration) {
+ // initializeLoadPath(configuration);
+ initializeInterpreterSelection(configuration);
+ initializeRemoteDebug(configuration);
+ }
+
+ protected void initializeRemoteDebug(ILaunchConfiguration configuration) {
+ try {
+ fRemoteDebugCheckBox.setSelection(configuration.getAttribute(
+ PHPLaunchConfigurationAttribute.REMOTE_DEBUG,
+ DEFAULT_REMOTE_DEBUG));
+ } catch (CoreException ce) {
+ fRemoteDebugCheckBox.setSelection(DEFAULT_REMOTE_DEBUG);
+ }
+ try {
+ fRemoteDebugTranslate.setSelection(configuration.getAttribute(
+ PHPLaunchConfigurationAttribute.REMOTE_DEBUG_TRANSLATE,
+ DEFAULT_REMOTE_DEBUG_TRANSLATE));
+ } catch (CoreException ce) {
+ fRemoteDebugTranslate.setSelection(DEFAULT_REMOTE_DEBUG_TRANSLATE);
+ }
+ try {
+ fOpenDBGSessionInBrowserCheckBox
+ .setSelection(configuration
+ .getAttribute(
+ PHPLaunchConfigurationAttribute.OPEN_DBGSESSION_IN_BROWSER,
+ DEFAULT_OPEN_DBGSESSION_IN_BROWSER));
+ } catch (CoreException ce) {
+ fOpenDBGSessionInBrowserCheckBox
+ .setSelection(DEFAULT_OPEN_DBGSESSION_IN_BROWSER);
+ }
+ setRemoteTabEnableState();
+ try {
+ fRemoteSourcePath.setText(configuration.getAttribute(
+ PHPLaunchConfigurationAttribute.REMOTE_PATH, ""));
+ } catch (CoreException ce) {
+ fRemoteSourcePath.setText("");
+ }
+
+ updatePathMapFromConfig(configuration);
+
+ }
+
+ private void updatePathMapFromConfig(ILaunchConfiguration config) {
+ Map envVars = null;
+ try {
+ if (config != null) {
+ envVars = config.getAttribute(
+ PHPLaunchConfigurationAttribute.FILE_MAP, (Map) null);
+ }
+ updatePathMapTable(envVars, this.fRemoteDebugPathMapTable);
+ setPathMapButtonsEnableState();
+ } catch (CoreException ce) {
+ log(ce);
+ }
+ }
+
+ private void updatePathMapTable(Map map, Table tableWidget) {
+ tableWidget.removeAll();
+ if (map == null) {
+ return;
+ }
+ Iterator iterator = map.keySet().iterator();
+ while (iterator.hasNext()) {
+ String key = (String) iterator.next();
+ String value = (String) map.get(key);
+ TableItem tableItem = new TableItem(tableWidget, SWT.NONE);
+ tableItem.setText(new String[] { key, value });
+ }
+ }
+
+ // protected void initializeLoadPath(ILaunchConfiguration configuration) {
+ // boolean useDefaultLoadPath = true;
+ // try {
+ // useDefaultLoadPath =
+ // configuration.getAttribute(PHPLaunchConfigurationAttribute.USE_DEFAULT_LOAD_PATH,
+ // true);
+ // setUseLoadPathDefaults(useDefaultLoadPath);
+ // if (useDefaultLoadPath) {
+ // String projectName =
+ // configuration.getAttribute(PHPLaunchConfigurationAttribute.PROJECT_NAME,
+ // "");
+ // if (projectName != "") {
+ // IProject aProject =
+ // PHPeclipsePlugin.getWorkspace().getRoot().getProject(projectName);
+ // if ((aProject != null) && JavaCore.isPHPProject(aProject)) {
+ // JavaProject thePHPProject = new JavaProject();
+ // thePHPProject.setProject(aProject);
+ // List loadPathEntries = thePHPProject.getLoadPathEntries();
+ // loadPathListViewer.setInput(loadPathEntries);
+ // }
+ // }
+ // }
+ // } catch (CoreException e) {
+ // log(e);
+ // }
+ // }
+
+ protected void setUseLoadPathDefaults(boolean useDefaults) {
+ loadPathListViewer.getList().setEnabled(!useDefaults);
+ // loadPathDefaultButton.setSelection(useDefaults);
+ }
+
+ protected void initializeInterpreterSelection(
+ ILaunchConfiguration configuration) {
+ String interpreterName = null;
+ try {
+ interpreterName = configuration.getAttribute(
+ PHPLaunchConfigurationAttribute.SELECTED_INTERPRETER, "");
+ } catch (CoreException e) {
+ log(e);
+ }
+ if (interpreterName != null && !interpreterName.equals(""))
+ interpreterCombo.select(interpreterCombo.indexOf(interpreterName));
+ }
+
+ protected void initializeInterpreterCombo(Combo interpreterCombo) {
+ installedInterpretersWorkingCopy = new ArrayList();
+ installedInterpretersWorkingCopy.addAll(PHPRuntime.getDefault()
+ .getInstalledInterpreters());
+
+ String[] interpreterNames = new String[installedInterpretersWorkingCopy
+ .size()];
+ for (int interpreterIndex = 0; interpreterIndex < installedInterpretersWorkingCopy
+ .size(); interpreterIndex++) {
+ PHPInterpreter interpreter = (PHPInterpreter) installedInterpretersWorkingCopy
+ .get(interpreterIndex);
+ interpreterNames[interpreterIndex] = interpreter
+ .getInstallLocation().toString();
+ }
+ interpreterCombo.setItems(interpreterNames);
+
+ PHPInterpreter selectedInterpreter = PHPRuntime.getDefault()
+ .getSelectedInterpreter();
+ if (selectedInterpreter != null)
+ interpreterCombo.select(interpreterCombo
+ .indexOf(selectedInterpreter.getInstallLocation()
+ .toString()));
+ }
+
+ public void performApply(ILaunchConfigurationWorkingCopy configuration) {
+ int selectionIndex = interpreterCombo.getSelectionIndex();
+ if (selectionIndex >= 0)
+ configuration.setAttribute(
+ PHPLaunchConfigurationAttribute.SELECTED_INTERPRETER,
+ interpreterCombo.getItem(selectionIndex));
+
+ // configuration.setAttribute(PHPLaunchConfigurationAttribute.USE_DEFAULT_LOAD_PATH,
+ // loadPathDefaultButton.getSelection());
+
+ // if (!loadPathDefaultButton.getSelection()) {
+ // List loadPathEntries = (List) loadPathListViewer.getInput();
+ // List loadPathStrings = new ArrayList();
+ // for (Iterator iterator = loadPathEntries.iterator();
+ // iterator.hasNext();) {
+ // LoadPathEntry entry = (LoadPathEntry) iterator.next();
+ // loadPathStrings.add(entry.getPath().toString());
+ // }
+ // configuration.setAttribute(PHPLaunchConfigurationAttribute.CUSTOM_LOAD_PATH,
+ // loadPathStrings);
+ // }
+
+ configuration.setAttribute(
+ PHPLaunchConfigurationAttribute.REMOTE_DEBUG,
+ fRemoteDebugCheckBox.getSelection());
+ configuration.setAttribute(
+ PHPLaunchConfigurationAttribute.REMOTE_DEBUG_TRANSLATE,
+ fRemoteDebugTranslate.getSelection());
+ configuration.setAttribute(PHPLaunchConfigurationAttribute.FILE_MAP,
+ getMapFromPathMapTable());
+ configuration.setAttribute(PHPLaunchConfigurationAttribute.REMOTE_PATH,
+ fRemoteSourcePath.getText());
+ configuration.setAttribute(
+ PHPLaunchConfigurationAttribute.OPEN_DBGSESSION_IN_BROWSER,
+ fOpenDBGSessionInBrowserCheckBox.getSelection());
+ }
+
+ protected Composite createPageRoot(Composite parent) {
+ Composite composite = new Composite(parent, SWT.NULL);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 2;
+ composite.setLayout(layout);
+ createVerticalSpacer(composite, 2);
+ setControl(composite);
+
+ return composite;
+ }
+
+ private Map getMapFromPathMapTable() {
+ TableItem[] items = fRemoteDebugPathMapTable.getItems();
+ if (items.length == 0) {
+ return null;
+ }
+ Map map = new HashMap(items.length);
+ for (int i = 0; i < items.length; i++) {
+ TableItem item = items[i];
+ String key = item.getText(0);
+ String value = item.getText(1);
+ map.put(key, value);
+ }
+ return map;
+ }
+
+ public String getName() {
+ return PHPDebugUiMessages
+ .getString("LaunchConfigurationTab.PHPEnvironment.name");
+ }
+
+ public boolean isValid(ILaunchConfiguration launchConfig) {
+ try {
+ String selectedInterpreter = launchConfig.getAttribute(
+ PHPLaunchConfigurationAttribute.SELECTED_INTERPRETER, "");
+ if (selectedInterpreter.length() == 0) {
+ setErrorMessage(PHPDebugUiMessages
+ .getString("LaunchConfigurationTab.PHPEnvironment.interpreter_not_selected_error_message"));
+ return false;
+ }
+ } catch (CoreException e) {
+ log(e);
+ }
+
+ setErrorMessage(null);
+ return true;
+ }
+
+ protected void log(Throwable t) {
+ PHPDebugUiPlugin.log(t);
+ }
+
+ public Image getImage() {
+ return PHPUiImages.get(PHPUiImages.IMG_CTOOLS_PHP);
+ }
+
+}
\ No newline at end of file
--- /dev/null
+package net.sourceforge.phpdt.internal.launching;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
+
+import net.sourceforge.phpdt.internal.core.JavaProject;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.model.IProcess;
+
+public class InterpreterRunner {
+
+ public InterpreterRunner() {
+ }
+
+ public IProcess run(InterpreterRunnerConfiguration configuration,
+ ILaunch launch) {
+ String commandLine = renderCommandLine(configuration);
+ File workingDirectory = configuration.getAbsoluteWorkingDirectory();
+
+ setEnvironmentVariables(configuration);
+ String[] env = configuration.getEnvironment();
+ Process nativePHPProcess = null;
+ try {
+ nativePHPProcess = configuration.getInterpreter().exec(commandLine,
+ workingDirectory, env);
+ } catch (IOException e) {
+ throw new RuntimeException("Unable to execute interpreter: "
+ + commandLine + workingDirectory);
+ }
+
+ IProcess process = DebugPlugin.newProcess(launch, nativePHPProcess,
+ renderLabel(configuration));
+ process
+ .setAttribute(PHPLaunchingPlugin.PLUGIN_ID
+ + ".launcher.cmdline", commandLine);
+ process.setAttribute(IProcess.ATTR_PROCESS_TYPE,
+ PHPLaunchConfigurationAttribute.PHP_LAUNCH_PROCESS_TYPE);
+
+ return process;
+ }
+
+ protected String renderLabel(InterpreterRunnerConfiguration configuration) {
+ StringBuffer buffer = new StringBuffer();
+
+ PHPInterpreter interpreter = configuration.getInterpreter();
+ buffer.append("PHP ");
+ buffer.append(interpreter.getCommand());
+ buffer.append(" : ");
+ buffer.append(configuration.getFileName());
+
+ return buffer.toString();
+ }
+
+ protected String renderCommandLine(
+ InterpreterRunnerConfiguration configuration) {
+ PHPInterpreter interpreter = configuration.getInterpreter();
+
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(this.getDebugCommandLineArgument());
+ // buffer.append(renderLoadPath(configuration));
+ buffer.append(" " + configuration.getInterpreterArguments());
+ // buffer.append(interpreter.endOfOptionsDelimeter);
+ buffer.append(" "
+ + osDependentPath(configuration.getAbsoluteFileName()));
+ buffer.append(" " + configuration.getProgramArguments());
+
+ return buffer.toString();
+ }
+
+ protected void setEnvironmentVariables(
+ InterpreterRunnerConfiguration configuration) {
+ IPath FilePath = new Path(configuration.getAbsoluteFileName());
+ String OSFilePath = FilePath.toOSString();
+ configuration.addEnvironmentValue("REDIRECT_URL", OSFilePath, true);
+ configuration.addEnvironmentValue("REQUEST_URI", OSFilePath, true);
+ configuration.addEnvironmentValue("PATH_INFO", OSFilePath, true);
+ configuration.addEnvironmentValue("PATH_TRANSLATED", OSFilePath, true);
+ configuration.addEnvironmentValue("SCRIPT_FILENAME", configuration
+ .getInterpreter().getCommand(), true);
+ configuration
+ .addEnvironmentValue("SERVER_PROTOCOL", "HTTP / 1.1", true);
+
+ configuration.addEnvironmentValue("REDIRECT_QUERY_STRING", "", true);
+ configuration.addEnvironmentValue("REDIRECT_STATUS", "200", true);
+ configuration.addEnvironmentValue("SERVER_SOFTWARE", "DBG / 2.1", true);
+ configuration.addEnvironmentValue("SERVER_NAME", "localhost", true);
+ configuration.addEnvironmentValue("SERVER_ADDR", "127.0.0.1", true);
+ configuration.addEnvironmentValue("SERVER_PORT", "80", true);
+ configuration.addEnvironmentValue("REMOTE_ADDR", "127.0.0.1", true);
+
+ configuration.addEnvironmentValue("GATEWAY_INTERFACE", "CGI / 1.1",
+ true);
+ configuration.addEnvironmentValue("REQUEST_METHOD", "GET", true);
+
+ Map stringVars = DebugPlugin.getDefault().getLaunchManager()
+ .getNativeEnvironment();
+ if (stringVars.containsKey("SYSTEMROOT"))
+ configuration.addEnvironmentValue("SYSTEMROOT", (String) stringVars
+ .get("SYSTEMROOT"), true);
+
+ }
+
+ protected String renderLoadPath(InterpreterRunnerConfiguration configuration) {
+ StringBuffer loadPath = new StringBuffer();
+
+ JavaProject project = configuration.getProject();
+ addToLoadPath(loadPath, project.getProject());
+
+ Iterator referencedProjects = project.getReferencedProjects()
+ .iterator();
+ while (referencedProjects.hasNext())
+ addToLoadPath(loadPath, (IProject) referencedProjects.next());
+
+ return loadPath.toString();
+ }
+
+ protected void addToLoadPath(StringBuffer loadPath, IProject project) {
+ loadPath.append(" -I "
+ + osDependentPath(project.getLocation().toOSString()));
+ }
+
+ protected String osDependentPath(String aPath) {
+ if (Platform.getOS().equals(Platform.OS_WIN32))
+ aPath = "\"" + aPath + "\"";
+
+ return aPath;
+ }
+
+ protected String getDebugCommandLineArgument() {
+ return "";
+ }
+}
--- /dev/null
+package net.sourceforge.phpdt.internal.launching;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import net.sourceforge.phpdt.internal.core.JavaProject;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.internal.ui.launchConfigurations.EnvironmentVariable;
+
+public class InterpreterRunnerConfiguration {
+ protected ILaunchConfiguration configuration;
+
+ private HashMap fEnvironment;
+
+ public InterpreterRunnerConfiguration(ILaunchConfiguration aConfiguration) {
+ configuration = aConfiguration;
+ fEnvironment = new HashMap();
+ }
+
+ public String getAbsoluteFileName() {
+ IPath path = new Path(getFileName());
+ IProject project = getProject().getProject();
+
+ return project.getLocation().toOSString() + "/" + getFileName();
+ }
+
+ public String getFileName() {
+ String fileName = "";
+
+ try {
+ fileName = configuration.getAttribute(
+ PHPLaunchConfigurationAttribute.FILE_NAME,
+ "No file specified in configuration");
+ } catch (CoreException e) {
+ }
+
+ return fileName.replace('\\', '/');
+ }
+
+ public JavaProject getProject() {
+ String projectName = "";
+
+ try {
+ projectName = configuration.getAttribute(
+ PHPLaunchConfigurationAttribute.PROJECT_NAME, "");
+ } catch (CoreException e) {
+ PHPLaunchingPlugin.log(e);
+ }
+
+ IProject project = PHPLaunchingPlugin.getWorkspace().getRoot()
+ .getProject(projectName);
+
+ JavaProject phpProject = new JavaProject();
+ phpProject.setProject(project);
+ return phpProject;
+ }
+
+ public File getAbsoluteWorkingDirectory() {
+ String file = null;
+ try {
+ file = configuration.getAttribute(
+ PHPLaunchConfigurationAttribute.WORKING_DIRECTORY, "");
+ } catch (CoreException e) {
+ PHPLaunchingPlugin.log(e);
+ }
+ return new File(file);
+ }
+
+ public String getInterpreterArguments() {
+ try {
+ return configuration.getAttribute(
+ PHPLaunchConfigurationAttribute.INTERPRETER_ARGUMENTS, "");
+ } catch (CoreException e) {
+ }
+
+ return "";
+ }
+
+ public String getProgramArguments() {
+ try {
+ return configuration.getAttribute(
+ PHPLaunchConfigurationAttribute.PROGRAM_ARGUMENTS, "");
+ } catch (CoreException e) {
+ }
+
+ return "";
+ }
+
+ public PHPInterpreter getInterpreter() {
+ String selectedInterpreter = null;
+ try {
+ selectedInterpreter = configuration.getAttribute(
+ PHPLaunchConfigurationAttribute.SELECTED_INTERPRETER, "");
+ } catch (CoreException e) {
+ }
+
+ return PHPRuntime.getDefault().getInterpreter(selectedInterpreter);
+ }
+
+ public boolean useRemoteDebugger() {
+ try {
+ return configuration.getAttribute(
+ PHPLaunchConfigurationAttribute.REMOTE_DEBUG, false);
+ } catch (CoreException e) {
+ PHPLaunchingPlugin.log(e);
+ }
+ return false;
+ }
+
+ public boolean usePathTranslation() {
+ try {
+ return configuration.getAttribute(
+ PHPLaunchConfigurationAttribute.REMOTE_DEBUG_TRANSLATE,
+ false);
+ } catch (CoreException e) {
+ PHPLaunchingPlugin.log(e);
+ }
+ return false;
+ }
+
+ public Map getPathMap() {
+ try {
+ return configuration.getAttribute(
+ PHPLaunchConfigurationAttribute.FILE_MAP, (Map) null);
+ } catch (CoreException e) {
+ PHPLaunchingPlugin.log(e);
+ }
+ return (Map) null;
+ }
+
+ public boolean useDBGSessionInBrowser() {
+ try {
+ return configuration.getAttribute(
+ PHPLaunchConfigurationAttribute.OPEN_DBGSESSION_IN_BROWSER,
+ true);
+ } catch (CoreException e) {
+ PHPLaunchingPlugin.log(e);
+ }
+ return false;
+ }
+
+ public void setEnvironment(String[] envp) {
+ if (envp == null)
+ return;
+ for (int i = 0; i < envp.length; i++) {
+ addEnvironmentValue(envp[i], true);
+ }
+ }
+
+ public void addEnvironmentValue(String env, boolean replace) {
+ String value = env.substring(env.indexOf('=') + 1);
+ String key = env.substring(0, env.indexOf('='));
+ addEnvironmentValue(key, value, replace);
+ }
+
+ public void addEnvironmentValue(String key, String value, boolean replace) {
+ if (!replace && fEnvironment.containsKey(key)) {
+ EnvironmentVariable ev = (EnvironmentVariable) fEnvironment
+ .get(key);
+ ev.setValue(ev.getValue() + ";" + value);
+ fEnvironment.put(key, ev);
+ } else
+ this.fEnvironment.put(key, new EnvironmentVariable(key, value));
+ }
+
+ public String[] getEnvironment() {
+
+ Iterator iter = fEnvironment.entrySet().iterator();
+ List strings = new ArrayList(fEnvironment.size());
+ while (iter.hasNext()) {
+ Map.Entry entry = (Map.Entry) iter.next();
+ StringBuffer buffer = new StringBuffer((String) entry.getKey());
+ buffer.append('=').append(
+ ((EnvironmentVariable) entry.getValue()).getValue());
+ strings.add(buffer.toString());
+ }
+ return (String[]) strings.toArray(new String[strings.size()]);
+
+ }
+
+ public String getRemoteSourcePath() {
+
+ IProject project = getProject().getProject();
+ if (!useRemoteDebugger())
+ return project.getLocation().toOSString();
+ else {
+ try {
+ return configuration.getAttribute(
+ PHPLaunchConfigurationAttribute.REMOTE_PATH, "");
+ } catch (CoreException e) {
+ PHPLaunchingPlugin.log(e);
+ }
+ }
+
+ return "";
+ }
+
+}
--- /dev/null
+package net.sourceforge.phpdt.internal.launching;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import net.sourceforge.phpdt.internal.debug.core.model.PHPStackFrame;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.builder.ExternalEditorInput;
+import net.sourceforge.phpeclipse.builder.FileStorage;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.model.IPersistableSourceLocator;
+import org.eclipse.debug.core.model.IStackFrame;
+import org.eclipse.debug.ui.ISourcePresentation;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.FileEditorInput;
+
+public class PHPSourceLocator implements IPersistableSourceLocator, ISourcePresentation {
+ private String absoluteWorkingDirectory;
+ private Map pathMap = null;
+ private boolean remoteDebug;
+ private IPath remoteSourcePath;
+ private String projectName;
+
+ public PHPSourceLocator() {
+
+ }
+
+ public String getAbsoluteWorkingDirectory() {
+ return absoluteWorkingDirectory;
+ }
+
+ /**
+ * @see org.eclipse.debug.core.model.IPersistableSourceLocator#getMemento()
+ */
+ public String getMemento() throws CoreException {
+ return null;
+ }
+
+ /**
+ * @see org.eclipse.debug.core.model.IPersistableSourceLocator#initializeFromMemento(String)
+ */
+ public void initializeFromMemento(String memento) throws CoreException {
+ }
+
+ /**
+ * @see org.eclipse.debug.core.model.IPersistableSourceLocator#initializeDefaults(ILaunchConfiguration)
+ */
+ public void initializeDefaults (ILaunchConfiguration configuration) throws CoreException {
+ this.absoluteWorkingDirectory = configuration.getAttribute (PHPLaunchConfigurationAttribute.WORKING_DIRECTORY, "");
+ this.remoteDebug = configuration.getAttribute (PHPLaunchConfigurationAttribute.REMOTE_DEBUG,false);
+ this.pathMap = configuration.getAttribute (PHPLaunchConfigurationAttribute.FILE_MAP, (Map)null);
+ this.projectName = configuration.getAttribute (PHPLaunchConfigurationAttribute.PROJECT_NAME, "");
+
+ if (Platform.getOS().equals(Platform.OS_WIN32)) {
+ this.remoteSourcePath = new Path ((configuration.getAttribute (PHPLaunchConfigurationAttribute.REMOTE_PATH, "")).toLowerCase());
+ }
+ else {
+ this.remoteSourcePath = new Path (configuration.getAttribute (PHPLaunchConfigurationAttribute.REMOTE_PATH, ""));
+ }
+
+// system.os.name
+ }
+
+ /**
+ * @see org.eclipse.debug.core.model.ISourceLocator#getSourceElement(IStackFrame)
+ *
+ * Return the client side source filename for the server side source file.
+ * E.g. when cross debugging, the server side filename could be /var/www/index.php
+ * on the client side it is either a Eclipse_PHP_projectname\index.php (when it is a linked file)
+ *
+ *
+ * @param stackFrame The stackframe for which we want the client side source file name
+ * @return The filename as it appears on the client side
+ */
+ public Object getSourceElement (IStackFrame stackFrame) {
+ IPath projectPath;
+ IPath remotePath;
+ IPath path;
+ IPath localPath;
+ Iterator iterator;
+ String fileName;
+ String file;
+ String local;
+
+ fileName = ((PHPStackFrame) stackFrame).getFileName (); // Get the filename as it is submitted by DBG
+ file = "";
+
+ if (remoteDebug) { // Is it a remote debugging session
+ path = new Path (fileName); // Create a IPath object for the server side filename
+
+ if (!remoteSourcePath.isEmpty()) {
+ if (remoteSourcePath.isPrefixOf (path)) { // Is the server side filename with the remote source path
+ path = path.removeFirstSegments (remoteSourcePath.matchingFirstSegments (path)); // Remove the remote source path
+ file = path.toString (); // The filename without the remote source path
+ projectPath = (PHPeclipsePlugin.getWorkspace().getRoot().getProject(projectName).getLocation()); // Get the absolute project path
+
+ return (projectPath.append (path)).toOSString (); // Return the filename as absolute client side path
+ }
+ }
+ else {
+ if (pathMap == null) { // Do we have path mapping (e.g. for cross platform debugging)
+ return fileName; // No, then return the filename as it given by DBG (the full server side path)
+ }
+
+ iterator = pathMap.keySet().iterator();
+
+ while (iterator.hasNext ()) {
+ local = (String) iterator.next (); // Get the local/client side path of the mapping
+ remotePath = new Path ((String) pathMap.get (local)); // Get the remote/server side path of the mapping
+
+ if (remotePath.isPrefixOf (path)) { // Starts the remote/server side file path with the remote/server side mapping path
+ path = path.removeFirstSegments (remotePath.matchingFirstSegments (path)); // Remove the absolute path from filename
+ localPath = new Path (local); // Create new IPath object for the local/client side path
+ path = localPath.append (path); // Prepend the project relative path to filename
+
+ projectPath = (PHPeclipsePlugin.getWorkspace().getRoot().getProject(projectName).getLocation()); // Get the absolute project path
+
+ return (projectPath.append (path)).toOSString (); // Return the filename as absolute client side path
+ }
+ }
+ }
+
+ if (pathMap == null) { // Do we have path mapping (e.g. for cross platform debugging)
+ return fileName; // No, then return the filename as it given by DBG (the full server side path)
+ }
+
+ iterator = pathMap.keySet().iterator();
+
+ while (iterator.hasNext ()) {
+ local = (String) iterator.next (); // Get the local/client side path of the mapping
+ remotePath = new Path ((String) pathMap.get (local)); // Get the remote/server side path of the mapping
+
+ if (remotePath.isPrefixOf (path)) { // Starts the remote/server side file path with the remote/server side mapping path
+ path = path.removeFirstSegments (remotePath.matchingFirstSegments (path)); // Remove the absolute path from filename
+ localPath = new Path (local); // Create new IPath object for the local/client side path
+
+ return localPath.append (path).toOSString (); // Append the remote filename to the client side path (So we return the absolute path
+ // to the source file as the client side sees it.
+ }
+ }
+
+ return fileName;
+ } else {
+ return fileName;
+ }
+ }
+
+ /**
+ * @see org.eclipse.debug.ui.ISourcePresentation#getEditorId(IEditorInput, Object)
+ */
+ public String getEditorId(IEditorInput input, Object element) {
+ return PlatformUI.getWorkbench().getEditorRegistry().getDefaultEditor((String) element).getId();
+ }
+
+ /**
+ * @see org.eclipse.debug.ui.ISourcePresentation#getEditorInput(Object)
+ *
+ * @param element The absolute local/client side file path
+ */
+ public IEditorInput getEditorInput (Object element) {
+ String filename;
+ IWorkbench workbench;
+ IWorkbenchWindow window;
+ IWorkbenchPage page;
+ IPath path;
+ IFile eclipseFile;
+
+ filename = (String) element;
+ workbench = PlatformUI.getWorkbench ();
+ window = workbench.getWorkbenchWindows ()[0];
+ page = window.getActivePage ();
+ path = new Path (filename); // Create an IPath object of the absolute local/client side file name
+
+ // If the file exists in the workspace, open it
+ eclipseFile = PHPeclipsePlugin.getWorkspace().getRoot().getFileForLocation (path);
+
+ // IFile eclipseFile = PHPeclipsePlugin.getWorkspace().getRoot().getFileForLocation(new Path(filename));
+// if (eclipseFile == null) {
+// filename = this.getAbsoluteWorkingDirectory() + "/" + filename;
+// eclipseFile = PHPeclipsePlugin.getWorkspace().getRoot().getFileForLocation(new Path(filename));
+// if (eclipseFile == null) {
+// PHPeclipsePlugin.log(IStatus.INFO, "Could not find file \"" + element + "\".");
+// return null;
+// }
+// } else
+
+ if (eclipseFile == null || !eclipseFile.exists ()) {
+ // Otherwise open the stream directly
+ //
+ if (page == null) {
+ PHPeclipsePlugin.log(IStatus.INFO, "Could not find file \"" + element + "\".");
+ return null;
+ }
+
+ FileStorage storage = new FileStorage (path);
+ storage.setReadOnly ();
+
+ // IEditorRegistry registry = workbench.getEditorRegistry();
+ // IEditorDescriptor desc = registry.getDefaultEditor(filename);
+ // if (desc == null) {
+ // desc = registry.getDefaultEditor();
+ // }
+ return new ExternalEditorInput(storage);
+ }
+
+ return new FileEditorInput (eclipseFile);
+ }
+}
--- /dev/null
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.ui.text.template;
+
+import net.sourceforge.phpdt.internal.corext.phpdoc.PHPDocUtil;
+import net.sourceforge.phpdt.internal.corext.template.TemplateMessages;
+import net.sourceforge.phpdt.internal.corext.template.php.JavaContext;
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionManager;
+import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionUI;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.builder.PHPIdentifierLocation;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.contentassist.ContextInformation;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.jface.text.templates.TemplateContext;
+import org.eclipse.swt.graphics.Image;
+
+// import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionManager;
+// import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionUI;
+// import net.sourceforge.phpdt.internal.ui.util.ExceptionHandler;
+
+/**
+ * A PHP identifier proposal.
+ */
+public class DeclarationProposal extends AbstractProposal { // implements
+ // IPHPCompletionProposal
+ // {
+ private IProject fProject;
+
+ private final TemplateContext fContext;
+
+ private final PHPIdentifierLocation fLocation;
+
+ String fInfo;
+
+ // private TemplateBuffer fTemplateBuffer;
+ // private String fOldText;
+ // private final Image fImage_fun;
+ // private final Image fImage_var;
+ private final IRegion fRegion;
+
+ // private IRegion fSelectedRegion; // initialized by apply()
+
+ private final String fIdentifierName;
+
+ // private final ITextViewer fViewer;
+
+ /**
+ * Creates a template proposal with a template and its context.
+ *
+ * @param template
+ * the template
+ * @param context
+ * the context in which the template was requested.
+ * @param image
+ * the icon of the proposal.
+ */
+ public DeclarationProposal(IProject project, String identifierName,
+ PHPIdentifierLocation location, TemplateContext context,
+ IRegion region, ITextViewer viewer) {
+ super(viewer);
+ // Image image_fun,
+ // Image image_var) {
+ fProject = project;
+ fIdentifierName = identifierName;
+ fLocation = location;
+ fContext = context;
+ fRegion = region;
+ fInfo = null;
+ }
+
+ /*
+ * @see ICompletionProposal#apply(IDocument)
+ */
+ public void apply(IDocument document) {
+ try {
+ // if (fTemplateBuffer == null)
+ // fTemplateBuffer= fContext.evaluate(fTemplate);
+
+ int start = fRegion.getOffset();
+ int end = fRegion.getOffset() + fRegion.getLength();
+
+ switch (fLocation.getType()) {
+ case PHPIdentifierLocation.FUNCTION:
+ document.replace(start, end - start, fIdentifierName + "()");
+ break;
+ case PHPIdentifierLocation.CONSTRUCTOR:
+ document.replace(start, end - start, fIdentifierName + "()");
+ break;
+ case PHPIdentifierLocation.METHOD:
+ document.replace(start, end - start, fIdentifierName + "()");
+ break;
+
+ default:
+ document.replace(start, end - start, fIdentifierName);
+ }
+
+ // translate positions
+ LinkedPositionManager manager = new LinkedPositionManager(document);
+ // TemplatePosition[] variables= fTemplateBuffer.getVariables();
+ // for (int i= 0; i != variables.length; i++) {
+ // TemplatePosition variable= variables[i];
+ //
+ // if (variable.isResolved())
+ // continue;
+ //
+ // int[] offsets= variable.getOffsets();
+ // int length= variable.getLength();
+ //
+ // for (int j= 0; j != offsets.length; j++)
+ // manager.addPosition(offsets[j] + start, length);
+ // }
+
+ LinkedPositionUI editor = new LinkedPositionUI(fViewer, manager);
+ switch (fLocation.getType()) {
+ case PHPIdentifierLocation.FUNCTION:
+ editor
+ .setFinalCaretOffset(fIdentifierName.length() + start
+ + 1);
+ break;
+ case PHPIdentifierLocation.CONSTRUCTOR:
+ editor
+ .setFinalCaretOffset(fIdentifierName.length() + start
+ + 1);
+ break;
+ case PHPIdentifierLocation.METHOD:
+ editor
+ .setFinalCaretOffset(fIdentifierName.length() + start
+ + 1);
+ break;
+
+ default:
+ editor.setFinalCaretOffset(fIdentifierName.length() + start);
+ }
+ editor.enter();
+
+ fSelectedRegion = editor.getSelectedRegion();
+
+ } catch (BadLocationException e) {
+ PHPeclipsePlugin.log(e);
+ openErrorDialog(e);
+
+ }
+ // catch (CoreException e) {
+ // handleException(e);
+ // }
+ }
+
+ /*
+ * @see ICompletionProposal#getAdditionalProposalInfo()
+ */
+ public String getAdditionalProposalInfo() {
+ if (fInfo == null) {
+ fInfo = computeProposalInfo();
+ }
+ return fInfo;
+ }
+
+ private String computeProposalInfo() {
+ StringBuffer hoverInfoBuffer = new StringBuffer();
+ // String workspaceLocation =
+ // PHPeclipsePlugin.getWorkspace().getRoot().getLocation().toString();
+ String workspaceLocation;
+ if (fProject != null) {
+ workspaceLocation = fProject.getLocation().toString() + '/';
+ } else {
+ // should never happen?
+ workspaceLocation = PHPeclipsePlugin.getWorkspace().getRoot()
+ .getLocation().toString();
+ }
+ String filename = workspaceLocation + fLocation.getFilename();
+ PHPDocUtil.appendPHPDoc(hoverInfoBuffer, filename, fLocation);
+ return hoverInfoBuffer.toString();
+ }
+
+ public IContextInformation getContextInformation() {
+ if (fContextInfo == null) {
+ if (fLocation != null) {
+ fInfo = fLocation.getUsage();
+ if (fInfo != null) {
+ // extract the parameter context information for the
+ // function:
+ int i0 = fInfo.indexOf('(');
+ int newline = fInfo.indexOf('\n');
+ if (i0 >= 0 && (i0 < newline || newline < 0)) {
+ int i1 = fInfo.indexOf(')', i0 + 1);
+ if (i1 > 0) {
+
+ fContextInfo = new ContextInformation(null, fInfo
+ .substring(i0 + 1, i1));
+ } else {
+ fContextInfo = new ContextInformation(null, fInfo);
+ }
+ } else {
+ fContextInfo = new ContextInformation(null, fInfo);
+ }
+ }
+ }
+ }
+ return fContextInfo;
+ }
+
+ /*
+ * @see ICompletionProposal#getDisplayString()
+ */
+ public String getDisplayString() {
+ String workspaceLocation;
+ if (fProject != null) {
+ workspaceLocation = fProject.getName().toString() + '/';
+ } else {
+ // should never happen?
+ workspaceLocation = PHPeclipsePlugin.getWorkspace().getRoot()
+ .getLocation().toString();
+ }
+ String filename = workspaceLocation + fLocation.getFilename();
+ String usage = PHPDocUtil.getUsage(filename, fLocation);
+ String result = fIdentifierName
+ + TemplateMessages.getString("TemplateProposal.delimiter");
+ if (usage.length() > 0) {
+ result += usage
+ + TemplateMessages.getString("TemplateProposal.delimiter");
+ }
+ result += filename;
+ return result;
+ }
+
+ /*
+ * @see ICompletionProposal#getImage()
+ */
+ public Image getImage() {
+ switch (fLocation.getType()) {
+ case PHPIdentifierLocation.FUNCTION:
+ return PHPUiImages.get(PHPUiImages.IMG_FUN);
+ case PHPIdentifierLocation.CLASS:
+ return PHPUiImages.get(PHPUiImages.IMG_CLASS);
+ case PHPIdentifierLocation.CONSTRUCTOR:
+ return PHPUiImages.get(PHPUiImages.IMG_CLASS);
+ case PHPIdentifierLocation.METHOD:
+ return PHPUiImages.get(PHPUiImages.IMG_FUN);
+ case PHPIdentifierLocation.DEFINE:
+ return PHPUiImages.get(PHPUiImages.IMG_DEFINE);
+ case PHPIdentifierLocation.VARIABLE:
+ return PHPUiImages.get(PHPUiImages.IMG_VAR);
+ case PHPIdentifierLocation.GLOBAL_VARIABLE:
+ return PHPUiImages.get(PHPUiImages.IMG_VAR);
+ }
+ return PHPUiImages.get(PHPUiImages.IMG_FUN);
+ }
+
+ /*
+ * @see IJavaCompletionProposal#getRelevance()
+ */
+ public int getRelevance() {
+
+ if (fContext instanceof JavaContext) {
+ JavaContext context = (JavaContext) fContext;
+ switch (context.getCharacterBeforeStart()) {
+ // high relevance after whitespace
+ case ' ':
+ case '\r':
+ case '\n':
+ case '\t':
+ return 80;
+ case '>': // ->
+ case ':': // ::
+ return 85;
+ default:
+ return 0;
+ }
+ } else {
+ return 80;
+ }
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Created on 09.08.2003
+ *
+ */
+package net.sourceforge.phpdt.internal.ui.util;
+
+import java.io.File;
+import java.util.List;
+
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.overlaypages.ProjectPrefUtil;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.ui.IEditorDescriptor;
+import org.eclipse.ui.IEditorRegistry;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.PlatformUI;
+
+public class PHPFileUtil {
+ // private static String[] PHP_EXTENSIONS = null;
+
+ public final static String[] SMARTY_EXTENSIONS = { "tpl" };
+
+ public static boolean isPHPFile(IFile file) {
+ // String extension = file.getFileExtension();
+ return isPHPFileName(file.getLocation().toString());
+ }
+
+ // public final static String getFileExtension(String name) {
+ // int index = name.lastIndexOf('.');
+ // if (index == -1)
+ // return null;
+ // if (index == (name.length() - 1))
+ // return null; //$NON-NLS-1$
+ // return name.substring(index + 1);
+ // }
+
+ /**
+ * Returns true iff str.toLowerCase().endsWith(".php") implementation is not
+ * creating extra strings.
+ */
+ public final static boolean isPHPFileName(String name) {
+
+ // avoid handling a file without base name, e.g. ".php", which is a
+ // valid
+ // Eclipse resource name
+ File file = new File(name);
+ if (file.getName().startsWith(".")) {
+ return false;
+ }
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ IEditorRegistry registry = workbench.getEditorRegistry();
+ IEditorDescriptor[] descriptors = registry.getEditors(name);
+
+ for (int i = 0; i < descriptors.length; i++) {
+ if (descriptors[i].getId().equals(PHPeclipsePlugin.EDITOR_ID)) {
+ return true;
+ }
+ }
+ // String extension = getFileExtension(name);
+ // if (extension == null) {
+ // return false;
+ // }
+ // extension = extension.toLowerCase();
+ // PHP_EXTENSIONS = getExtensions();
+ // if (PHP_EXTENSIONS == null) {
+ // return false;
+ // }
+ // for (int i = 0; i < PHP_EXTENSIONS.length; i++) {
+ // if (extension.equals(PHP_EXTENSIONS[i])) {
+ // return true;
+ // }
+ // }
+ return false;
+ }
+
+ /**
+ * Returns true iff the file extension is a valid PHP Unit name
+ * implementation is not creating extra strings.
+ */
+ public final static boolean isValidPHPUnitName(String filename) {
+ return PHPFileUtil.isPHPFileName(filename);
+ }
+
+ /**
+ * @return Returns the PHP extensions.
+ */
+ // public static String[] getExtensions() {
+ // if (PHP_EXTENSIONS == null) {
+ // ArrayList list = new ArrayList();
+ // final IPreferenceStore store =
+ // PHPeclipsePlugin.getDefault().getPreferenceStore();
+ // String extensions =
+ // store.getString(PHPeclipsePlugin.PHP_EXTENSION_PREFS);
+ // extensions = extensions.trim();
+ // if (extensions.length() != 0) {
+ // StringTokenizer tokenizer = new StringTokenizer(extensions, " ,;:/-|");
+ // String token;
+ // while (tokenizer.hasMoreTokens()) {
+ // token = tokenizer.nextToken();
+ // if (token != null && token.length() >= 1) {
+ // list.add(token);
+ // }
+ // }
+ // if (list.size() != 0) {
+ // PHP_EXTENSIONS = new String[list.size()];
+ // for (int i = 0; i < list.size(); i++) {
+ // PHP_EXTENSIONS[i] = (String) list.get(i);
+ // }
+ // }
+ // }
+ // }
+ // return PHP_EXTENSIONS;
+ // }
+ /**
+ * @param php_extensions
+ * The PHP extensions to set.
+ */
+ // public static void setExtensions(String[] php_extensions) {
+ // PHP_EXTENSIONS = php_extensions;
+ // }
+ /**
+ * Creata the file for the given absolute file path
+ *
+ * @param absoluteFilePath
+ * @param project
+ * @return the file for the given absolute file path or <code>null</code>
+ * if no existing file can be found
+ */
+ public static IFile createFile(IPath absoluteFilePath, IProject project) {
+ if (absoluteFilePath == null || project == null) {
+ return null;
+ }
+
+ String projectPath = project.getLocation().toString();
+ String filePath = absoluteFilePath.toString().substring(
+ projectPath.length() + 1);
+ return project.getFile(filePath);
+
+ }
+
+ /**
+ * Determine the path of an include name string
+ *
+ * @param includeNameString
+ * @param resource
+ * @param project
+ * @return the path for the given include filename or <code>null</code> if
+ * no existing file can be found
+ */
+ public static IPath determineFilePath(String includeNameString,
+ IResource resource, IProject project) {
+ IPath documentRootPath = ProjectPrefUtil.getDocumentRoot(project);
+ IPath resourcePath = resource.getProjectRelativePath();
+
+ File file = null;
+ IPath path = null;
+ path = documentRootPath.append(includeNameString);
+ file = path.toFile();
+ if (file.exists()) {
+ return path;
+ }
+
+ if (includeNameString.startsWith("../")) {
+ path = project.getLocation().append(
+ resourcePath.removeLastSegments(1));
+ path = path.append(includeNameString);
+ file = path.toFile();
+ if (file.exists()) {
+ return path;
+ }
+ }
+
+ // includeNameString contains no path separator
+ path = project.getLocation().append(resourcePath.removeLastSegments(1));
+ path = path.append(includeNameString);
+ file = path.toFile();
+ if (file.exists()) {
+ return path;
+ }
+ // }
+
+ List includePaths = ProjectPrefUtil.getIncludePaths(project);
+ if (includePaths.size() > 0) {
+ for (int i = 0; i < includePaths.size(); i++) {
+ path = new Path(includePaths.get(i).toString())
+ .append(includeNameString);
+ file = path.toFile();
+ if (file.exists()) {
+ return path;
+ }
+ }
+ }
+ return null;
+ }
+
+}
\ No newline at end of file
--- /dev/null
+// Copyright (c) 2005 by Leif Frenzel. All rights reserved.
+// See http://leiffrenzel.de
+// modified for phpeclipse.de project by axelcl
+package net.sourceforge.phpdt.ltk.core;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
+import net.sourceforge.phpdt.core.compiler.InvalidInputException;
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+import net.sourceforge.phpdt.internal.compiler.parser.SyntaxError;
+import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.ltk.core.refactoring.Change;
+import org.eclipse.ltk.core.refactoring.CompositeChange;
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+import org.eclipse.ltk.core.refactoring.TextFileChange;
+import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
+import org.eclipse.ltk.core.refactoring.participants.IConditionChecker;
+import org.eclipse.ltk.core.refactoring.participants.ValidateEditChecker;
+import org.eclipse.text.edits.MultiTextEdit;
+import org.eclipse.text.edits.ReplaceEdit;
+
+/**
+ * <p>
+ * delegate object that contains the logic used by the processor.
+ * </p>
+ *
+ */
+public class RenameIdentifierDelegate {
+
+ // private static final String EXT_PROPERTIES = "properties"; //$NON-NLS-1$
+
+ protected final RenameIdentifierInfo info;
+
+ // PHP file with the identifier to rename -> offset of the key
+ protected final Map phpFiles;
+
+ public RenameIdentifierDelegate(final RenameIdentifierInfo info) {
+ this.info = info;
+ phpFiles = new HashMap();
+ }
+
+ RefactoringStatus checkInitialConditions() {
+ RefactoringStatus result = new RefactoringStatus();
+ IFile sourceFile = info.getSourceFile();
+ if (sourceFile == null || !sourceFile.exists()) {
+ result.addFatalError(CoreTexts.renamePropertyDelegate_noSourceFile);
+ } else if (info.getSourceFile().isReadOnly()) {
+ result.addFatalError(CoreTexts.renamePropertyDelegate_roFile);
+ } else if (isEmpty(info.getOldName())) {
+ // || !isPropertyKey( info.getSourceFile(), info.getOldName() ) ) {
+ result.addFatalError(CoreTexts.renamePropertyDelegate_noPHPKey);
+ }
+ return result;
+ }
+
+ RefactoringStatus checkFinalConditions(final IProgressMonitor pm,
+ final CheckConditionsContext ctxt) {
+ RefactoringStatus result = new RefactoringStatus();
+ pm.beginTask(CoreTexts.renamePropertyDelegate_checking, 100);
+ // do something long-running here: traverse the entire project (or even
+ // workspace) to look for all *.properties files with the same bundle
+ // base name
+ IContainer rootContainer;
+ ArrayList phpProjects = new ArrayList();
+ IProject project;
+ if (info.isAllProjects()) {
+ rootContainer = ResourcesPlugin.getWorkspace().getRoot();
+ IResource[] members;
+ try {
+ members = rootContainer.members();
+ for (int i = 0; i < members.length; i++) {
+ if (members[i] instanceof IProject) {
+ project = (IProject) members[i];
+ try {
+ if (project
+ .isNatureEnabled(PHPeclipsePlugin.PHP_NATURE_ID)) {
+ search(project, result);
+ }
+ } catch (CoreException e) {
+ String msg = "Project: "
+ + project.getLocation().toOSString()
+ + " CoreException " + e.getMessage();
+ result.addError(msg);
+ } catch (Exception e) {
+ String msg = "Project: "
+ + project.getLocation().toOSString()
+ + " Exception " + e.getMessage();
+ result.addError(msg);
+ }
+ }
+ }
+ } catch (CoreException e) {
+ String msg = "Workspace: "
+ + rootContainer.getLocation().toOSString()
+ + " CoreException " + e.getMessage();
+ result.addError(msg);
+ }
+ } else {
+ project = info.getSourceFile().getProject();
+ try {
+ if (project.isNatureEnabled(PHPeclipsePlugin.PHP_NATURE_ID)) {
+ search(project, result);
+ }
+ } catch (CoreException e) {
+ String msg = "Project: " + project.getLocation().toOSString()
+ + " CoreException " + e.getMessage();
+ result.addError(msg);
+ } catch (Exception e) {
+ String msg = "Project: " + project.getLocation().toOSString()
+ + " Exception " + e.getMessage();
+ result.addError(msg);
+ }
+ }
+
+ pm.worked(50);
+
+ if (ctxt != null) {
+ IFile[] files = new IFile[phpFiles.size()];
+ phpFiles.keySet().toArray(files);
+ IConditionChecker checker = ctxt
+ .getChecker(ValidateEditChecker.class);
+ ValidateEditChecker editChecker = (ValidateEditChecker) checker;
+ editChecker.addFiles(files);
+ }
+ pm.done();
+ return result;
+ }
+
+ protected void createChange(final IProgressMonitor pm,
+ final CompositeChange rootChange) {
+ try {
+ pm.beginTask(CoreTexts.renamePropertyDelegate_collectingChanges,
+ 100);
+ // all files in the same bundle
+ if (info.isUpdateProject()) {
+ rootChange.addAll(createChangesForContainer(pm));
+ }
+ } finally {
+ pm.done();
+ }
+ }
+
+ // helping methods
+ // ////////////////
+
+ // private Change createRenameChange() {
+ // // create a change object for the file that contains the property the
+ // // user has selected to rename
+ // IFile file = info.getSourceFile();
+ // TextFileChange result = new TextFileChange(file.getName(), file);
+ // // a file change contains a tree of edits, first add the root of them
+ // MultiTextEdit fileChangeRootEdit = new MultiTextEdit();
+ // result.setEdit(fileChangeRootEdit);
+ //
+ // // edit object for the text replacement in the file, this is the only
+ // child
+ // ReplaceEdit edit = new ReplaceEdit(info.getOffset(),
+ // info.getOldName().length(), info.getNewName());
+ // fileChangeRootEdit.addChild(edit);
+ // return result;
+ // }
+
+ protected Change[] createChangesForContainer(final IProgressMonitor pm) {
+ List result = new ArrayList();
+ Iterator it = phpFiles.keySet().iterator();
+ int numberOfFiles = phpFiles.size();
+ double percent = 100 / numberOfFiles;
+ int work = 0;
+ int indx = 0;
+ while (it.hasNext()) {
+ IFile file = (IFile) it.next();
+ List list = getKeyOffsets(file);
+ if (list != null && list.size() > 0) {
+ TextFileChange tfc = new TextFileChange(file.getName(), file);
+ MultiTextEdit fileChangeRootEdit = new MultiTextEdit();
+ tfc.setEdit(fileChangeRootEdit);
+
+ // edit object for the text replacement in the file, there could
+ // be
+ // multiple childs
+ ReplaceEdit edit;
+ for (int i = 0; i < list.size(); i++) {
+ edit = new ReplaceEdit(((Integer) list.get(i)).intValue(),
+ info.getOldName().length(), info.getNewName());
+ fileChangeRootEdit.addChild(edit);
+ }
+ result.add(tfc);
+ }
+ work = new Double((++indx) * percent).intValue();
+ pm.worked(work);
+ }
+ return (Change[]) result.toArray(new Change[result.size()]);
+ }
+
+ protected boolean isEmpty(final String candidate) {
+ return candidate == null || candidate.trim().length() == 0;
+ }
+
+ // private boolean isPropertyKey( final IFile file, final String candidate )
+ // {
+ // boolean result = false;
+ // try {
+ // Properties props = new Properties();
+ // props.load( file.getContents() );
+ // result = props.containsKey( candidate );
+ // } catch( Exception ex ) {
+ // // ignore this, we just assume this is not a favourable situation
+ // ex.printStackTrace();
+ // }
+ // return result;
+ // }
+
+ // // whether the file is a PHP file with the same base name as the
+ // // one we refactor and contains the key that interests us
+ // private boolean isToRefactor(final IFile file) {
+ // return PHPFileUtil.isPHPFile(file);
+ // // && !file.equals( info.getSourceFile() )
+ // // && isPropertyKey( file, info.getOldName() );
+ // }
+
+ // private String getBundleBaseName() {
+ // String result = info.getSourceFile().getName();
+ // int underscoreIndex = result.indexOf( '_' );
+ // if( underscoreIndex != -1 ) {
+ // result = result.substring( 0, underscoreIndex );
+ // } else {
+ // int index = result.indexOf( EXT_PROPERTIES ) - 1;
+ // result = result.substring( 0, index );
+ // }
+ // return result;
+ // }
+
+ private void search(final IContainer rootContainer,
+ final RefactoringStatus status) {
+ try {
+ IResource[] members = rootContainer.members();
+ for (int i = 0; i < members.length; i++) {
+ if (members[i] instanceof IContainer) {
+ search((IContainer) members[i], status);
+ } else {
+ IFile file = (IFile) members[i];
+ handleFile(file, status);
+ }
+ }
+ } catch (final CoreException cex) {
+ status.addFatalError(cex.getMessage());
+ }
+ }
+
+ private void handleFile(final IFile file, final RefactoringStatus status) {
+ if (PHPFileUtil.isPHPFile(file)) {
+ determineKeyOffsets(file, status);
+ // if (keyOffsets.size() > 0) {
+ // Integer offset = new Integer(keyOffsets);
+ // phpFiles.put(file, offset);
+ // }
+ }
+ }
+
+ protected List getKeyOffsets(final IFile file) {
+ return (List) phpFiles.get(file);
+ }
+
+ // finds the offsets of the identifier to rename
+ // usually, this would be the job of a proper parser;
+ // using a primitive brute-force approach here
+ private void determineKeyOffsets(final IFile file,
+ final RefactoringStatus status) {
+ ArrayList matches = new ArrayList();
+ try {
+ String content = readFileContent(file, status);
+ Scanner scanner = new Scanner(true, false);
+ scanner.setSource(content.toCharArray());
+ scanner.setPHPMode(false);
+ char[] word = info.getOldName().toCharArray();
+
+ int fToken = ITerminalSymbols.TokenNameEOF;
+ try {
+ fToken = scanner.getNextToken();
+ while (fToken != ITerminalSymbols.TokenNameEOF) {
+ if (fToken == ITerminalSymbols.TokenNameVariable
+ || fToken == ITerminalSymbols.TokenNameIdentifier) {
+ if (scanner.equalsCurrentTokenSource(word)) {
+ matches.add(new Integer(scanner
+ .getCurrentTokenStartPosition()));
+ }
+ }
+ fToken = scanner.getNextToken();
+ }
+
+ } catch (InvalidInputException e) {
+ String msg = "File: " + file.getLocation().toOSString()
+ + " InvalidInputException " + e.getMessage();
+ status.addError(msg);
+ } catch (SyntaxError e) {
+ String msg = "File: " + file.getLocation().toOSString()
+ + " SyntaxError " + e.getMessage();
+ status.addError(msg);
+ }
+
+ } catch (Exception e) {
+ String msg = "File: " + file.getLocation().toOSString()
+ + " Exception " + e.getMessage();
+ status.addError(msg);
+ }
+ if (matches.size() > 0) {
+ phpFiles.put(file, matches);
+ }
+
+ // int result = -1;
+ // int candidateIndex = content.indexOf(info.getOldName());
+ // result = candidateIndex;
+ // while( result == -1 && candidateIndex != -1 ) {
+ // if( isKeyOccurrence( content, candidateIndex ) ) {
+ // result = candidateIndex;
+ // }
+ // }
+ // if( result == -1 ) {
+ // // still nothing found, we add a warning to the status
+ // // (we have checked the file contains the property, so that we can't
+ // // determine it's offset is probably because of the rough way
+ // employed
+ // // here to find it)
+ // String msg = CoreTexts.renamePropertyDelegate_propNotFound
+ // + file.getLocation().toOSString();
+ // status.addWarning( msg );
+ // }
+ // return result;
+ }
+
+ private String readFileContent(final IFile file,
+ final RefactoringStatus refStatus) {
+ String result = null;
+ try {
+ InputStream is = file.getContents();
+ byte[] buf = new byte[1024];
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ int len = is.read(buf);
+ while (len > 0) {
+ bos.write(buf, 0, len);
+ len = is.read(buf);
+ }
+ is.close();
+ result = new String(bos.toByteArray());
+ } catch (Exception ex) {
+ String msg = ex.toString();
+ refStatus.addFatalError(msg);
+ String pluginId = PHPeclipsePlugin.getPluginId();
+ IStatus status = new Status(IStatus.ERROR, pluginId, 0, msg, ex);
+ PHPeclipsePlugin.getDefault().getLog().log(status);
+ }
+ return result;
+ }
+
+ // we check only that there is a separator before the next line break (this
+ // is not sufficient, the whole thing may be in a comment etc. ...)
+ // private boolean isKeyOccurrence( final String content,
+ // final int candidateIndex ) {
+ // int index = candidateIndex + info.getOldName().length();
+ // // skip whitespace
+ // while( content.charAt( index ) == ' ' || content.charAt( index ) == '\t'
+ // )
+ // {
+ // index++;
+ // }
+ // return content.charAt( index ) == '=' || content.charAt( index ) == ':';
+ // }
+}
--- /dev/null
+// Copyright (c) 2005 by Leif Frenzel. All rights reserved.
+// See http://leiffrenzel.de
+// modified for phpeclipse.de project by axelcl
+package net.sourceforge.phpdt.ltk.core;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+
+import net.sourceforge.phpdt.core.ISourceRange;
+import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
+import net.sourceforge.phpdt.core.compiler.InvalidInputException;
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+import net.sourceforge.phpdt.internal.compiler.parser.SyntaxError;
+import net.sourceforge.phpdt.internal.core.SourceMethod;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.ltk.core.refactoring.CompositeChange;
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
+import org.eclipse.ltk.core.refactoring.participants.IConditionChecker;
+import org.eclipse.ltk.core.refactoring.participants.ValidateEditChecker;
+
+/**
+ * <p>
+ * delegate object that contains the logic used by the processor.
+ * </p>
+ *
+ */
+public class RenameLocalVariableDelegate extends RenameIdentifierDelegate {
+
+ public RenameLocalVariableDelegate(final RenameIdentifierInfo info) {
+ super(info);
+ }
+
+ RefactoringStatus checkInitialConditions() {
+ RefactoringStatus result = new RefactoringStatus();
+ IFile sourceFile = info.getSourceFile();
+ if (sourceFile == null || !sourceFile.exists()) {
+ result.addFatalError(CoreTexts.renamePropertyDelegate_noSourceFile);
+ } else if (info.getSourceFile().isReadOnly()) {
+ result.addFatalError(CoreTexts.renamePropertyDelegate_roFile);
+ } else if (isEmpty(info.getOldName())) {
+ // || !isPropertyKey( info.getSourceFile(), info.getOldName() ) ) {
+ result.addFatalError(CoreTexts.renamePropertyDelegate_noPHPKey);
+ }
+ return result;
+ }
+
+ RefactoringStatus checkFinalConditions(final IProgressMonitor pm,
+ final CheckConditionsContext ctxt) {
+ RefactoringStatus result = new RefactoringStatus();
+ pm.beginTask(CoreTexts.renamePropertyDelegate_checking, 100);
+ // do something long-running here: traverse the entire project (or even
+ // workspace) to look for all *.p files with the same bundle
+ // base name
+ IFile file = info.getSourceFile();
+ IProject project = file.getProject();
+ try {
+ SourceMethod method = info.getMethod();
+ ISourceRange range = method.getSourceRange();
+ if (project.isNatureEnabled(PHPeclipsePlugin.PHP_NATURE_ID)) {
+ determineMethodOffsets(file, range.getOffset(), range
+ .getLength(), result);
+ }
+ } catch (CoreException e) {
+ String msg = "Project: " + project.getLocation().toOSString()
+ + " CoreException " + e.getMessage();
+ result.addError(msg);
+ } catch (Exception e) {
+ String msg = "Project: " + project.getLocation().toOSString()
+ + " Exception " + e.getMessage();
+ result.addError(msg);
+ }
+
+ pm.worked(50);
+
+ if (ctxt != null) {
+ IFile[] files = new IFile[phpFiles.size()];
+ phpFiles.keySet().toArray(files);
+ IConditionChecker checker = ctxt
+ .getChecker(ValidateEditChecker.class);
+ ValidateEditChecker editChecker = (ValidateEditChecker) checker;
+ editChecker.addFiles(files);
+ }
+ pm.done();
+ return result;
+ }
+
+ protected void createChange(final IProgressMonitor pm,
+ final CompositeChange rootChange) {
+ try {
+ pm.beginTask(CoreTexts.renamePropertyDelegate_collectingChanges,
+ 100);
+ // all files in the same bundle
+ rootChange.addAll(createChangesForContainer(pm));
+ } finally {
+ pm.done();
+ }
+ }
+
+ private void determineMethodOffsets(final IFile file, int offset,
+ int length, final RefactoringStatus status) {
+ ArrayList matches = new ArrayList();
+ try {
+ String content = readFileContent(file, status);
+
+ //
+ // Find a PHPdoc directly before the method
+ //
+ Scanner firstScanner = new Scanner(true, false);
+ firstScanner.setSource(content.toCharArray());
+ int fToken = ITerminalSymbols.TokenNameEOF;
+ int start = 0;
+ int phpdocStart = -1;
+ try {
+ fToken = firstScanner.getNextToken();
+ while (fToken != ITerminalSymbols.TokenNameEOF
+ && start < offset) {
+ if (fToken == ITerminalSymbols.TokenNameCOMMENT_PHPDOC) {
+ phpdocStart = firstScanner
+ .getCurrentTokenStartPosition();
+ } else {
+ phpdocStart = -1;
+ }
+ fToken = firstScanner.getNextToken();
+ start = firstScanner.getCurrentTokenStartPosition();
+ }
+
+ } catch (InvalidInputException e) {
+ String msg = "File: " + file.getLocation().toOSString()
+ + " InvalidInputException " + e.getMessage();
+ status.addError(msg);
+ } catch (SyntaxError e) {
+ String msg = "File: " + file.getLocation().toOSString()
+ + " SyntaxError " + e.getMessage();
+ status.addError(msg);
+ }
+
+ //
+ // Find matches for the word in the PHPdoc+method declaration
+ //
+ if (phpdocStart >= 0 && phpdocStart < offset) {
+ length += offset - phpdocStart;
+ offset = phpdocStart;
+ }
+ String methodString = content.substring(offset, offset + length);
+ Scanner secondScanner = new Scanner(true, false);
+ secondScanner.setSource(methodString.toCharArray());
+ secondScanner.setPHPMode(true);
+ String wordStr = info.getOldName();
+ boolean renameDQString = info.isRenameDQString();
+ boolean renamePHPdoc = info.isRenamePHPdoc();
+ boolean renameOtherComments = info.isRenameOtherComments();
+ char[] word = wordStr.toCharArray();
+
+ fToken = ITerminalSymbols.TokenNameEOF;
+ // double quoted string
+ String tokenString;
+ // double quoted string offset
+ int tokenOffset;
+ int index;
+ try {
+ fToken = secondScanner.getNextToken();
+ while (fToken != ITerminalSymbols.TokenNameEOF) {
+ if (fToken == ITerminalSymbols.TokenNameVariable) {
+ if (secondScanner.equalsCurrentTokenSource(word)) {
+ // the current variable token is equal to the given
+ // word
+ matches.add(new Integer(secondScanner
+ .getCurrentTokenStartPosition()
+ + offset));
+ }
+ } else if (fToken == ITerminalSymbols.TokenNameStringDoubleQuote
+ && renameDQString) {
+ // determine the word in double quoted strings:
+ tokenString = new String(secondScanner
+ .getCurrentTokenSource());
+ tokenOffset = secondScanner
+ .getCurrentTokenStartPosition();
+ index = -1;
+ while ((index = tokenString.indexOf(wordStr, index + 1)) >= 0) {
+ matches.add(new Integer(offset + tokenOffset
+ + index));
+ }
+ } else if (fToken == ITerminalSymbols.TokenNameCOMMENT_PHPDOC
+ && renamePHPdoc) {
+ tokenString = new String(secondScanner
+ .getCurrentTokenSource());
+ tokenOffset = secondScanner
+ .getCurrentTokenStartPosition();
+ index = -1;
+ while ((index = tokenString.indexOf(wordStr, index + 1)) >= 0) {
+ matches.add(new Integer(offset + tokenOffset
+ + index));
+ }
+ } else if ((fToken == ITerminalSymbols.TokenNameCOMMENT_BLOCK || fToken == ITerminalSymbols.TokenNameCOMMENT_LINE)
+ && renameOtherComments) {
+ tokenString = new String(secondScanner
+ .getCurrentTokenSource());
+ tokenOffset = secondScanner
+ .getCurrentTokenStartPosition();
+ index = -1;
+ while ((index = tokenString.indexOf(wordStr, index + 1)) >= 0) {
+ matches.add(new Integer(offset + tokenOffset
+ + index));
+ }
+ }
+ fToken = secondScanner.getNextToken();
+ }
+
+ } catch (InvalidInputException e) {
+ String msg = "File: " + file.getLocation().toOSString()
+ + " InvalidInputException " + e.getMessage();
+ status.addError(msg);
+ } catch (SyntaxError e) {
+ String msg = "File: " + file.getLocation().toOSString()
+ + " SyntaxError " + e.getMessage();
+ status.addError(msg);
+ }
+
+ } catch (Exception e) {
+ String msg = "File: " + file.getLocation().toOSString()
+ + " Exception " + e.getMessage();
+ status.addError(msg);
+ }
+ if (matches.size() > 0) {
+ phpFiles.put(file, matches);
+ }
+ }
+
+ private String readFileContent(final IFile file,
+ final RefactoringStatus refStatus) {
+ String result = null;
+ try {
+ InputStream is = file.getContents();
+ byte[] buf = new byte[1024];
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ int len = is.read(buf);
+ while (len > 0) {
+ bos.write(buf, 0, len);
+ len = is.read(buf);
+ }
+ is.close();
+ result = new String(bos.toByteArray());
+ } catch (Exception ex) {
+ String msg = ex.toString();
+ refStatus.addFatalError(msg);
+ String pluginId = PHPeclipsePlugin.getPluginId();
+ IStatus status = new Status(IStatus.ERROR, pluginId, 0, msg, ex);
+ PHPeclipsePlugin.getDefault().getLog().log(status);
+ }
+ return result;
+ }
+
+}
--- /dev/null
+package net.sourceforge.phpeclipse.actions;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
+import net.sourceforge.phpdt.core.compiler.InvalidInputException;
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+import net.sourceforge.phpdt.internal.compiler.parser.SyntaxError;
+import net.sourceforge.phpdt.internal.compiler.util.Util;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.ui.IFileEditorInput;
+
+public class IncludesScanner implements ITerminalSymbols {
+ // private final PHPOpenAllIncludesEditorAction fOpenAllIncludesAction;
+ private IProject fProject;
+
+ private IFileEditorInput fEditorInput;
+
+ private HashSet fSet;
+
+ public IncludesScanner(IProject project, IFileEditorInput editorInput) {
+ fProject = project;
+ // fOpenAllIncludesAction = action;
+ fEditorInput = editorInput;
+ fSet = new HashSet();
+ }
+
+ /**
+ * Add the information for a given IFile resource
+ *
+ */
+ public void addFile(IFile fileToParse) {
+
+ try {
+ if (fileToParse.exists()) {
+ addInputStream(new BufferedInputStream(fileToParse
+ .getContents()), fileToParse.getProjectRelativePath()
+ .toString());
+ }
+ } catch (CoreException e1) {
+ e1.printStackTrace();
+ }
+ }
+
+ private void addInputStream(InputStream stream, String filePath)
+ throws CoreException {
+ try {
+ if (fSet.add(filePath)) { // new entry in set
+ parseIdentifiers(Util.getInputStreamAsCharArray(stream, -1,
+ null));
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ if (stream != null) {
+ stream.close();
+ }
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ /**
+ * Get the next token from input
+ */
+ private int getNextToken(Scanner scanner) {
+ int token;
+ try {
+ token = scanner.getNextToken();
+ if (Scanner.DEBUG) {
+ int currentEndPosition = scanner.getCurrentTokenEndPosition();
+ int currentStartPosition = scanner
+ .getCurrentTokenStartPosition();
+ System.out.print(currentStartPosition + ","
+ + currentEndPosition + ": ");
+ System.out.println(scanner.toStringAction(token));
+ }
+ return token;
+ } catch (InvalidInputException e) {
+ }
+ return TokenNameERROR;
+ }
+
+ private void parseIdentifiers(char[] charArray) {
+ char[] ident;
+ IFile file;
+ String identifier;
+ int counter = 0;
+
+ Scanner scanner = new Scanner(false, false, false, false, true, null,
+ null, true /* taskCaseSensitive */);
+ scanner.setSource(charArray);
+ scanner.setPHPMode(false);
+ int token = getNextToken(scanner);
+ try {
+ while (token != TokenNameEOF) { // && fToken != TokenNameERROR) {
+ if (token == TokenNameinclude || token == TokenNameinclude_once
+ || token == TokenNamerequire
+ || token == TokenNamerequire_once) {
+ while (token != TokenNameEOF && token != TokenNameERROR
+ && token != TokenNameSEMICOLON
+ && token != TokenNameRPAREN
+ && token != TokenNameLBRACE
+ && token != TokenNameRBRACE) {
+ token = getNextToken(scanner);
+ if (token == TokenNameStringDoubleQuote
+ || token == TokenNameStringSingleQuote) {
+ char[] includeName = scanner
+ .getCurrentStringLiteralSource();
+ try {
+ file = getIncludeFile(new String(includeName));
+ addFile(file);
+ } catch (Exception e) {
+ // ignore
+ }
+ break;
+ }
+ }
+ }
+ token = getNextToken(scanner);
+ }
+ } catch (SyntaxError e) {
+ // e.printStackTrace();
+ }
+ }
+
+ private IContainer getWorkingLocation(IFileEditorInput editorInput) {
+ if (editorInput == null || editorInput.getFile() == null) {
+ return null;
+ }
+ return editorInput.getFile().getParent();
+ }
+
+ public IFile getIncludeFile(String relativeFilename) {
+ IContainer container = getWorkingLocation(fEditorInput);
+ String fullPath = fProject.getLocation().toString();
+ IFile file = null;
+ if (relativeFilename.startsWith("../")) {
+ Path path = new Path(relativeFilename);
+ file = container.getFile(path);
+ return file;
+ }
+ int index = relativeFilename.lastIndexOf('/');
+
+ if (index >= 0) {
+ Path path = new Path(relativeFilename);
+ file = fProject.getFile(path);
+ if (file.exists()) {
+ return file;
+ }
+ }
+ Path path = new Path(relativeFilename);
+ file = container.getFile(path);
+
+ return file;
+ }
+
+ /**
+ * Returns a list of includes
+ *
+ * @return the determined list of includes
+ */
+ public List getList() {
+ ArrayList list = new ArrayList();
+ list.addAll(fSet);
+ return list;
+ }
+
+ /**
+ * @return Returns the set.
+ */
+ public Set getSet() {
+ return fSet;
+ }
+}
\ No newline at end of file
--- /dev/null
+/***********************************************************************************************************************************
+ * Copyright (c) 2000, 2002 IBM Corp. 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: www.phpeclipse.de
+ **********************************************************************************************************************************/
+package net.sourceforge.phpeclipse.actions;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil;
+import net.sourceforge.phpdt.internal.ui.viewsupport.ListContentProvider;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.builder.IdentifierIndexManager;
+import net.sourceforge.phpeclipse.builder.PHPIdentifierLocation;
+import net.sourceforge.phpeclipse.phpeditor.PHPEditor;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPWordExtractor;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.dialogs.ListSelectionDialog;
+
+public class OpenDeclarationEditorAction {
+
+ private PHPEditor fEditor;
+
+ private IProject fProject;
+
+ private boolean isIncludeString;
+
+ public OpenDeclarationEditorAction(PHPEditor editor) {
+ fEditor = editor;
+ fProject = null;
+ isIncludeString = false;
+ }
+
+ /**
+ * @param selection
+ */
+ protected void openSelectedElement(ITextSelection selection) {
+ IDocument doc = fEditor.getDocumentProvider().getDocument(
+ fEditor.getEditorInput());
+ int pos = selection.getOffset();
+ openSelectedPosition(doc, pos);
+ }
+
+ protected void openSelectedPosition(IDocument doc, int position) {
+ IFile f = ((IFileEditorInput) fEditor.getEditorInput()).getFile();
+ fProject = f.getProject();
+ // System.out.println(selection.getText());
+ String identifierOrInclude = getIdentifierOrInclude(doc, position);
+ // System.out.println(word);
+ if (identifierOrInclude != null && !identifierOrInclude.equals("")) {
+ if (isIncludeString) {
+ openIncludeFile(identifierOrInclude);
+ } else {
+ openIdentifierDeclaration(f, identifierOrInclude);
+ }
+ }
+ }
+
+ /**
+ * @param filename
+ */
+ private void openIncludeFile(String filename) {
+ if (filename != null && !filename.equals("")) {
+ try {
+ IFile currentFile = ((IFileEditorInput) fEditor
+ .getEditorInput()).getFile();
+ IPath path = PHPFileUtil.determineFilePath(filename,
+ currentFile, fProject);
+ if (path != null) {
+ IFile file = PHPFileUtil.createFile(path, fProject);
+ if (file != null && file.exists()) {
+ PHPeclipsePlugin.getDefault().openFileInTextEditor(
+ file.getLocation().toString());
+ return;
+ }
+ }
+ } catch (Exception e) {
+ // ignore
+ }
+
+ try {
+
+ IdentifierIndexManager indexManager = PHPeclipsePlugin
+ .getDefault().getIndexManager(fProject);
+ // filename = StringUtil.replaceRegExChars(filename);
+ List list = indexManager.getFileList(filename);
+ if (list != null && list.size() > 0) {
+ // String workspaceLocation =
+ // PHPeclipsePlugin.getWorkspace().getRoot().getLocation().toString();
+ String workspaceLocation = fProject.getLocation()
+ .toString()
+ + java.io.File.separatorChar;
+
+ ListSelectionDialog listSelectionDialog = new ListSelectionDialog(
+ PHPeclipsePlugin.getDefault().getWorkbench()
+ .getActiveWorkbenchWindow().getShell(),
+ list, new ListContentProvider(),
+ new LabelProvider(), "Select the includes to open.");
+ listSelectionDialog.setTitle("Multiple includes found");
+ if (listSelectionDialog.open() == Window.OK) {
+ Object[] locations = listSelectionDialog.getResult();
+ if (locations != null) {
+ try {
+ for (int i = 0; i < locations.length; i++) {
+ // PHPIdentifierLocation location =
+ // (PHPIdentifierLocation)
+ // locations[i];
+ String openFilename = workspaceLocation
+ + ((String) locations[i]);
+ PHPeclipsePlugin.getDefault()
+ .openFileInTextEditor(openFilename);
+ }
+ } catch (CoreException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+
+ }
+ } catch (Exception e) {
+ }
+
+ }
+ return;
+ }
+
+ /**
+ * @param f
+ * @param identiifer
+ */
+ private void openIdentifierDeclaration(IFile f, String identiifer) {
+ if (identiifer != null && !identiifer.equals("")) {
+ IdentifierIndexManager indexManager = PHPeclipsePlugin.getDefault()
+ .getIndexManager(fProject);
+ List locationsList = indexManager.getLocations(identiifer);
+ if (locationsList != null && locationsList.size() > 0) {
+
+ // String workspaceLocation =
+ // PHPeclipsePlugin.getWorkspace().getRoot()
+ // .getLocation().toString();
+
+ String workspaceLocation = fProject.getLocation().toString()
+ + java.io.File.separatorChar;
+ // TODO show all entries of the list in a dialog box
+ // at the moment always the first entry will be opened
+ if (locationsList.size() > 1) {
+ // determine all includes:
+ IncludesScanner includesScanner = new IncludesScanner(
+ fProject, (IFileEditorInput) fEditor
+ .getEditorInput());
+ includesScanner.addFile(f);
+ Set exactIncludeSet = includesScanner.getSet();
+
+ PHPIdentifierLocation includeName;
+ for (int i = 0; i < locationsList.size(); i++) {
+ includeName = (PHPIdentifierLocation) locationsList
+ .get(i);
+ if (exactIncludeSet.contains(includeName.getFilename())) {
+ includeName
+ .setMatch(PHPIdentifierLocation.EXACT_MATCH);
+ } else {
+ includeName
+ .setMatch(PHPIdentifierLocation.UNDEFINED_MATCH);
+ }
+ }
+ Collections.sort(locationsList);
+
+ ListSelectionDialog listSelectionDialog = new ListSelectionDialog(
+ PHPeclipsePlugin.getDefault().getWorkbench()
+ .getActiveWorkbenchWindow().getShell(),
+ locationsList, new ListContentProvider(),
+ new LabelProvider(),
+ "Select the resources to open.");
+ listSelectionDialog.setTitle("Multiple declarations found");
+ if (listSelectionDialog.open() == Window.OK) {
+ Object[] locations = listSelectionDialog.getResult();
+ if (locations != null) {
+ try {
+ for (int i = 0; i < locations.length; i++) {
+ PHPIdentifierLocation location = (PHPIdentifierLocation) locations[i];
+ String filename = workspaceLocation
+ + location.getFilename();
+ // System.out.println(filename);
+ if (location.getOffset() >= 0) {
+ PHPeclipsePlugin.getDefault()
+ .openFileAndGotoOffset(
+ filename,
+ location.getOffset(),
+ identiifer.length());
+ } else {
+ PHPeclipsePlugin.getDefault()
+ .openFileAndFindString(
+ filename, identiifer);
+ }
+ }
+ } catch (CoreException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+ } else {
+ try {
+ PHPIdentifierLocation location = (PHPIdentifierLocation) locationsList
+ .get(0);
+ String filename = workspaceLocation
+ + location.getFilename();
+ // System.out.println(filename);
+ if (location.getOffset() >= 0) {
+ PHPeclipsePlugin.getDefault()
+ .openFileAndGotoOffset(filename,
+ location.getOffset(),
+ identiifer.length());
+ } else {
+ PHPeclipsePlugin
+ .getDefault()
+ .openFileAndFindString(filename, identiifer);
+ }
+ } catch (CoreException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+
+ private String getIdentifierOrInclude(IDocument doc, int pos) {
+ // private String getPHPIncludeText(IDocument doc, int pos) {
+ Point word = null;
+ int start = -1;
+ int end = -1;
+ isIncludeString = false;
+ try {
+ // try to find an include string
+ int position = pos;
+ char character = ' ';
+
+ while (position >= 0) {
+ character = doc.getChar(position);
+ if ((character == '\"') || (character == '\'')
+ || (character == '\r') || (character == '\n'))
+ break;
+ --position;
+ }
+ if ((character == '\"') || (character == '\'')) {
+ start = position;
+
+ position = pos;
+ int length = doc.getLength();
+ character = ' ';
+ while (position < length) {
+ character = doc.getChar(position);
+ if ((character == '\"') || (character == '\'')
+ || (character == '\r') || (character == '\n'))
+ break;
+ ++position;
+ }
+ if ((character == '\"') || (character == '\'')) {
+ start++;
+ end = position;
+
+ if (end > start) {
+ word = new Point(start, end - start); // include name
+ // found
+ isIncludeString = true;
+ }
+ }
+ }
+
+ // try to find an identifier
+ if (word == null) {
+ word = PHPWordExtractor.findWord(doc, pos); // identifier found
+ isIncludeString = false;
+ }
+ } catch (BadLocationException x) {
+ }
+
+ if (word != null) {
+ try {
+ return doc.get(word.x, word.y);
+ } catch (BadLocationException e) {
+ }
+ }
+ return "";
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2000, 2002 IBM Corp. 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: www.phpeclipse.de
+ ******************************************************************************/
+package net.sourceforge.phpeclipse.actions;
+
+import java.io.File;
+import java.util.List;
+
+import net.sourceforge.phpdt.internal.ui.viewsupport.ListContentProvider;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.PHPEditor;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.TextSelection;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.ui.IEditorActionDelegate;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.actions.ActionDelegate;
+import org.eclipse.ui.dialogs.ListSelectionDialog;
+
+public class PHPOpenAllIncludesEditorAction extends ActionDelegate implements
+ IEditorActionDelegate {
+
+ private IWorkbenchWindow fWindow;
+
+ private PHPEditor fEditor;
+
+ private IProject fProject;
+
+ private IncludesScanner fIncludesScanner;
+
+ public void dispose() {
+ }
+
+ public void init(IWorkbenchWindow window) {
+ this.fWindow = window;
+ }
+
+ public void selectionChanged(IAction action, ISelection selection) {
+ if (!selection.isEmpty()) {
+ if (selection instanceof TextSelection) {
+ action.setEnabled(true);
+ } else if (fWindow.getActivePage() != null
+ && fWindow.getActivePage().getActivePart() != null) {
+ //
+ }
+ }
+ }
+
+ private IWorkbenchPage getActivePage() {
+ IWorkbenchWindow workbenchWindow = fEditor.getEditorSite()
+ .getWorkbenchWindow();
+ IWorkbenchPage page = workbenchWindow.getActivePage();
+ return page;
+ }
+
+ public IContainer getWorkingLocation(IFileEditorInput editorInput) {
+ if (editorInput == null || editorInput.getFile() == null) {
+ return null;
+ }
+ return editorInput.getFile().getParent();
+ }
+
+ private IFile getIncludeFile(IProject project,
+ IFileEditorInput editorInput, String relativeFilename) {
+ IContainer container = getWorkingLocation(editorInput);
+ String fullPath = project.getLocation().toString();
+ IFile file = null;
+ if (relativeFilename.startsWith("../")) {
+ Path path = new Path(relativeFilename);
+ file = container.getFile(path);
+ return file;
+ }
+ int index = relativeFilename.lastIndexOf('/');
+
+ if (index >= 0) {
+ Path path = new Path(relativeFilename);
+ file = project.getFile(path);
+ if (file.exists()) {
+ return file;
+ }
+ }
+
+ Path path = new Path(relativeFilename);
+ file = container.getFile(path);
+
+ return file;
+ }
+
+ public void run(IAction action) {
+ if (fEditor == null) {
+ IEditorPart targetEditor = fWindow.getActivePage()
+ .getActiveEditor();
+ if (targetEditor != null && (targetEditor instanceof PHPEditor)) {
+ fEditor = (PHPEditor) targetEditor;
+ }
+ }
+ if (fEditor != null) {
+ // determine the current Project from a (file-based) Editor
+ IFile f = ((IFileEditorInput) fEditor.getEditorInput()).getFile();
+ fProject = f.getProject();
+ // System.out.println(fProject.toString());
+
+ ITextSelection selection = (ITextSelection) fEditor
+ .getSelectionProvider().getSelection();
+ IDocument doc = fEditor.getDocumentProvider().getDocument(
+ fEditor.getEditorInput());
+ fIncludesScanner = new IncludesScanner(fProject,
+ (IFileEditorInput) fEditor.getEditorInput());
+ int pos = selection.getOffset();
+ // System.out.println(selection.getText());
+ String filename = getPHPIncludeText(doc, pos);
+
+ if (filename != null && !filename.equals("")) {
+ try {
+ IFile file = fIncludesScanner.getIncludeFile(filename);
+ fIncludesScanner.addFile(file);
+ } catch (Exception e) {
+ // ignore
+ }
+
+ try {
+
+ List list = fIncludesScanner.getList();
+ if (list != null && list.size() > 0) {
+ // String workspaceLocation =
+ // PHPeclipsePlugin.getWorkspace().getRoot().getLocation().toString();
+ String workspaceLocation = fProject.getLocation()
+ .toString()
+ + File.separatorChar;
+
+ ListSelectionDialog listSelectionDialog = new ListSelectionDialog(
+ PHPeclipsePlugin.getDefault().getWorkbench()
+ .getActiveWorkbenchWindow().getShell(),
+ list, new ListContentProvider(),
+ new LabelProvider(),
+ "Select the includes to open.");
+ listSelectionDialog.setTitle("Multiple includes found");
+ if (listSelectionDialog.open() == Window.OK) {
+ Object[] locations = listSelectionDialog
+ .getResult();
+ if (locations != null) {
+ try {
+ for (int i = 0; i < locations.length; i++) {
+ // PHPIdentifierLocation location =
+ // (PHPIdentifierLocation)
+ // locations[i];
+ String openFilename = workspaceLocation
+ + ((String) locations[i]);
+ PHPeclipsePlugin.getDefault()
+ .openFileInTextEditor(
+ openFilename);
+ }
+ } catch (CoreException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+
+ }
+ } catch (Exception e) {
+ }
+
+ }
+ }
+ }
+
+ public void setActiveEditor(IAction action, IEditorPart targetEditor) {
+ if (targetEditor != null && (targetEditor instanceof PHPEditor)) {
+ fEditor = (PHPEditor) targetEditor;
+ }
+ }
+
+ private String getPHPIncludeText(IDocument doc, int pos) {
+ Point word = null;
+ int start = -1;
+ int end = -1;
+
+ try {
+
+ int position = pos;
+ char character;
+
+ while (position >= 0) {
+ character = doc.getChar(position);
+ if ((character == '\"') || (character == '\'')
+ || (character == '\r') || (character == '\n'))
+ break;
+ --position;
+ }
+
+ start = position;
+
+ position = pos;
+ int length = doc.getLength();
+
+ while (position < length) {
+ character = doc.getChar(position);
+ if ((character == '\"') || (character == '\'')
+ || (character == '\r') || (character == '\n'))
+ break;
+ ++position;
+ }
+
+ start++;
+ end = position;
+
+ if (end > start)
+ word = new Point(start, end - start);
+
+ } catch (BadLocationException x) {
+ }
+
+ if (word != null) {
+ try {
+ return doc.get(word.x, word.y);
+ } catch (BadLocationException e) {
+ }
+ }
+ return "";
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpeclipse.obfuscator;
+
+import java.io.File;
+import java.io.InputStream;
+
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.dialogs.ErrorDialog;
+
+/**
+ * <code>ObfuscatorIgnores</code> gives access to the available templates.
+ */
+public class ObfuscatorIgnores extends ObfuscatorIgnoreSet {
+
+ private static final String DEFAULT_FILE = "default-obfuscator.xml"; //$NON-NLS-1$
+
+ private static final String TEMPLATE_FILE = "obfuscator.xml"; //$NON-NLS-1$
+
+ /** Singleton. */
+ private static ObfuscatorIgnores fgIgnores;
+
+ private IProject fProject;
+
+ public ObfuscatorIgnores(IProject project) {
+ fProject = project;
+ try {
+ File templateFile = getTemplateFile();
+ if (templateFile.exists()) {
+ addFromFile(templateFile);
+ } else {
+ addFromStream(getDefaultsAsStream());
+ saveToFile(templateFile);
+ }
+
+ } catch (CoreException e) {
+ PHPeclipsePlugin.log(e);
+ ErrorDialog.openError(null, ObfuscatorMessages
+ .getString("Obfuscator.error.title"), //$NON-NLS-1$
+ e.getMessage(), e.getStatus());
+
+ clear();
+ }
+ }
+
+ /**
+ * Returns an instance of templates.
+ */
+ // public static ObfuscatorIgnores getInstance() {
+ // if (fgIgnores == null)
+ // fgIgnores = create();
+ //
+ // return fgIgnores;
+ // }
+ //
+ // private static ObfuscatorIgnores create() {
+ // ObfuscatorIgnores templates = new ObfuscatorIgnores();
+ //
+ // try {
+ // File templateFile = getTemplateFile();
+ // if (templateFile.exists()) {
+ // templates.addFromFile(templateFile);
+ // } else {
+ // templates.addFromStream(getDefaultsAsStream());
+ // templates.saveToFile(templateFile);
+ // }
+ //
+ // } catch (CoreException e) {
+ // PHPeclipsePlugin.log(e);
+ // ErrorDialog.openError(null,
+ // ObfuscatorMessages.getString("Templates.error.title"), //$NON-NLS-1$
+ // e.getMessage(), e.getStatus());
+ //
+ // templates.clear();
+ // }
+ //
+ // return templates;
+ // }
+ /**
+ * Resets the template set.
+ */
+ public void reset() throws CoreException {
+ clear();
+ addFromFile(getTemplateFile());
+ }
+
+ /**
+ * Resets the template set with the default templates.
+ */
+ public void restoreDefaults() throws CoreException {
+ clear();
+ addFromStream(getDefaultsAsStream());
+ }
+
+ /**
+ * Saves the template set.
+ */
+ public void save() throws CoreException {
+ saveToFile(getTemplateFile());
+ }
+
+ private InputStream getDefaultsAsStream() {
+ return ObfuscatorIgnores.class.getResourceAsStream(DEFAULT_FILE);
+ }
+
+ private File getTemplateFile() {
+ IPath path = fProject.getLocation();
+ // PHPeclipsePlugin.getDefault().getStateLocation();
+ path = path.append(TEMPLATE_FILE);
+
+ return path.toFile();
+ }
+}
--- /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.phpeclipse.obfuscator.export;
+
+import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.DirectoryDialog;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.ui.dialogs.WizardExportResourcesPage;
+
+/**
+ * Page 1 of the base resource export-to-file-system Wizard
+ */
+/* package */
+class WizardObfuscatorResourceExportPage1 extends WizardExportResourcesPage
+ implements Listener {
+
+ // widgets
+ private Combo destinationNameField;
+
+ private Button destinationBrowseButton;
+
+ protected Button overwriteExistingFilesCheckbox;
+
+ // protected Button createDirectoryStructureButton;
+ // protected Button createSelectionOnlyButton;
+
+ // constants
+ private static final int SIZING_TEXT_FIELD_WIDTH = 250;
+
+ // dialog store id constants
+ private static final String STORE_DESTINATION_NAMES_ID = "WizardObfuscatorResourceExportPage1.STORE_DESTINATION_NAMES_ID"; //$NON-NLS-1$
+
+ private static final String STORE_OVERWRITE_EXISTING_FILES_ID = "WizardObfuscatorResourceExportPage1.STORE_OVERWRITE_EXISTING_FILES_ID"; //$NON-NLS-1$
+ // private static final String STORE_CREATE_STRUCTURE_ID =
+ // "WizardObfuscatorResourceExportPage1.STORE_CREATE_STRUCTURE_ID";
+ // //$NON-NLS-1$
+
+ // messages
+ private static final String SELECT_DESTINATION_MESSAGE = ObfuscatorExportMessages
+ .getString("FileExport.selectDestinationMessage"); //$NON-NLS-1$
+
+ private static final String SELECT_DESTINATION_TITLE = ObfuscatorExportMessages
+ .getString("FileExport.selectDestinationTitle"); //$NON-NLS-1$
+
+ /**
+ * Create an instance of this class
+ */
+ protected WizardObfuscatorResourceExportPage1(String name,
+ IStructuredSelection selection) {
+ super(name, selection);
+ }
+
+ /**
+ * Create an instance of this class
+ */
+ public WizardObfuscatorResourceExportPage1(IStructuredSelection selection) {
+ this("fileSystemExportPage1", selection); //$NON-NLS-1$
+ setTitle(ObfuscatorExportMessages
+ .getString("ObfuscatorTransfer.fileSystemTitle")); //$NON-NLS-1$
+ setDescription(ObfuscatorExportMessages
+ .getString("FileExport.exportLocalFileSystem")); //$NON-NLS-1$
+ }
+
+ /**
+ * Add the passed value to self's destination widget's history
+ *
+ * @param value
+ * java.lang.String
+ */
+ protected void addDestinationItem(String value) {
+ destinationNameField.add(value);
+ }
+
+ /**
+ * (non-Javadoc) Method declared on IDialogPage.
+ */
+ public void createControl(Composite parent) {
+ super.createControl(parent);
+ giveFocusToDestination();
+ // WorkbenchHelp.setHelp(
+ // getControl(),
+ // IDataTransferHelpContextIds.FILE_SYSTEM_EXPORT_WIZARD_PAGE);
+ }
+
+ /**
+ * Create the export destination specification widgets
+ *
+ * @param parent
+ * org.eclipse.swt.widgets.Composite
+ */
+ protected void createDestinationGroup(Composite parent) {
+
+ Font font = parent.getFont();
+ // destination specification group
+ Composite destinationSelectionGroup = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 3;
+ destinationSelectionGroup.setLayout(layout);
+ destinationSelectionGroup.setLayoutData(new GridData(
+ GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL));
+ destinationSelectionGroup.setFont(font);
+
+ Label destinationLabel = new Label(destinationSelectionGroup, SWT.NONE);
+ destinationLabel.setText(getDestinationLabel());
+ destinationLabel.setFont(font);
+
+ // destination name entry field
+ destinationNameField = new Combo(destinationSelectionGroup, SWT.SINGLE
+ | SWT.BORDER);
+ destinationNameField.addListener(SWT.Modify, this);
+ destinationNameField.addListener(SWT.Selection, this);
+ GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL
+ | GridData.GRAB_HORIZONTAL);
+ data.widthHint = SIZING_TEXT_FIELD_WIDTH;
+ destinationNameField.setLayoutData(data);
+ destinationNameField.setFont(font);
+
+ // destination browse button
+ destinationBrowseButton = new Button(destinationSelectionGroup,
+ SWT.PUSH);
+ destinationBrowseButton.setText(ObfuscatorExportMessages
+ .getString("ObfuscatorTransfer.browse")); //$NON-NLS-1$
+ destinationBrowseButton.addListener(SWT.Selection, this);
+ destinationBrowseButton.setFont(font);
+ setButtonLayoutData(destinationBrowseButton);
+
+ new Label(parent, SWT.NONE); // vertical spacer
+ }
+
+ /**
+ * Create the buttons in the options group.
+ */
+
+ protected void createOptionsGroupButtons(Group optionsGroup) {
+
+ Font font = optionsGroup.getFont();
+ createOverwriteExisting(optionsGroup, font);
+
+ // createDirectoryStructureOptions(optionsGroup, font);
+ }
+
+ /**
+ * Create the buttons for the group that determine if the entire or selected
+ * directory structure should be created.
+ *
+ * @param optionsGroup
+ * @param font
+ */
+ // protected void createDirectoryStructureOptions(
+ // Group optionsGroup,
+ // Font font) {
+ // // create directory structure radios
+ // createDirectoryStructureButton =
+ // new Button(optionsGroup, SWT.RADIO | SWT.LEFT);
+ // createDirectoryStructureButton.setText(ObfuscatorExportMessages.getString("FileExport.createDirectoryStructure"));
+ // //$NON-NLS-1$
+ // createDirectoryStructureButton.setSelection(false);
+ // createDirectoryStructureButton.setFont(font);
+ //
+ // // create directory structure radios
+ // createSelectionOnlyButton =
+ // new Button(optionsGroup, SWT.RADIO | SWT.LEFT);
+ // createSelectionOnlyButton.setText(
+ // ObfuscatorExportMessages.getString(
+ // "FileExport.createSelectedDirectories"));//$NON-NLS-1$
+ // createSelectionOnlyButton.setSelection(true);
+ // createSelectionOnlyButton.setFont(font);
+ // }
+ /**
+ * Create the button for checking if we should ask if we are going to
+ * overwrite existing files.
+ *
+ * @param optionsGroup
+ * @param font
+ */
+ protected void createOverwriteExisting(Group optionsGroup, Font font) {
+ // overwrite... checkbox
+ overwriteExistingFilesCheckbox = new Button(optionsGroup, SWT.CHECK
+ | SWT.LEFT);
+ overwriteExistingFilesCheckbox.setText(ObfuscatorExportMessages
+ .getString("ExportFile.overwriteExisting")); //$NON-NLS-1$
+ overwriteExistingFilesCheckbox.setFont(font);
+ }
+
+ /**
+ * Attempts to ensure that the specified directory exists on the local file
+ * system. Answers a boolean indicating success.
+ *
+ * @return boolean
+ * @param directory
+ * java.io.File
+ */
+ protected boolean ensureDirectoryExists(File directory) {
+ if (!directory.exists()) {
+ if (!queryYesNoQuestion(ObfuscatorExportMessages
+ .getString("ObfuscatorTransfer.createTargetDirectory"))) //$NON-NLS-1$
+ return false;
+
+ if (!directory.mkdirs()) {
+ displayErrorDialog(ObfuscatorExportMessages
+ .getString("ObfuscatorTransfer.directoryCreationError")); //$NON-NLS-1$
+ giveFocusToDestination();
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * If the target for export does not exist then attempt to create it. Answer
+ * a boolean indicating whether the target exists (ie.- if it either
+ * pre-existed or this method was able to create it)
+ *
+ * @return boolean
+ */
+ protected boolean ensureTargetIsValid(File targetDirectory) {
+ if (targetDirectory.exists() && !targetDirectory.isDirectory()) {
+ displayErrorDialog(ObfuscatorExportMessages
+ .getString("FileExport.directoryExists")); //$NON-NLS-1$
+ giveFocusToDestination();
+ return false;
+ }
+
+ return ensureDirectoryExists(targetDirectory);
+ }
+
+ /**
+ * Set up and execute the passed Operation. Answer a boolean indicating
+ * success.
+ *
+ * @return boolean
+ */
+ protected boolean executeExportOperation(ObfuscatorExportOperation op) {
+ // op.setCreateLeadupStructure(
+ // createDirectoryStructureButton.getSelection());
+ op.setOverwriteFiles(overwriteExistingFilesCheckbox.getSelection());
+
+ try {
+ getContainer().run(true, true, op);
+ } catch (InterruptedException e) {
+ return false;
+ } catch (InvocationTargetException e) {
+ displayErrorDialog(e.getTargetException());
+ return false;
+ }
+
+ IStatus status = op.getStatus();
+ if (!status.isOK()) {
+ ErrorDialog.openError(getContainer().getShell(),
+ ObfuscatorExportMessages
+ .getString("ObfuscatorTransfer.exportProblems"), //$NON-NLS-1$
+ null, // no special message
+ status);
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * The Finish button was pressed. Try to do the required work now and answer
+ * a boolean indicating success. If false is returned then the wizard will
+ * not close.
+ *
+ * @return boolean
+ */
+ public boolean finish() {
+ if (!ensureTargetIsValid(new File(getDestinationValue())))
+ return false;
+
+ List resourcesToExport = getWhiteCheckedResources();
+
+ // Save dirty editors if possible but do not stop if not all are saved
+ saveDirtyEditors();
+ // about to invoke the operation so save our state
+ saveWidgetValues();
+
+ if (resourcesToExport.size() > 0)
+ return executeExportOperation(new ObfuscatorExportOperation(null,
+ resourcesToExport, getDestinationValue(), this));
+
+ MessageDialog.openInformation(getContainer().getShell(),
+ ObfuscatorExportMessages
+ .getString("ObfuscatorTransfer.information"), //$NON-NLS-1$
+ ObfuscatorExportMessages.getString("FileExport.noneSelected")); //$NON-NLS-1$
+
+ return false;
+ }
+
+ /**
+ * Answer the string to display in self as the destination type
+ *
+ * @return java.lang.String
+ */
+ protected String getDestinationLabel() {
+ return ObfuscatorExportMessages.getString("FileExport.toDirectory"); //$NON-NLS-1$
+ }
+
+ /**
+ * Answer the contents of self's destination specification widget
+ *
+ * @return java.lang.String
+ */
+ protected String getDestinationValue() {
+ return destinationNameField.getText().trim();
+ }
+
+ /**
+ * Set the current input focus to self's destination entry field
+ */
+ protected void giveFocusToDestination() {
+ destinationNameField.setFocus();
+ }
+
+ /**
+ * Open an appropriate destination browser so that the user can specify a
+ * source to import from
+ */
+ protected void handleDestinationBrowseButtonPressed() {
+ DirectoryDialog dialog = new DirectoryDialog(getContainer().getShell(),
+ SWT.SAVE);
+ dialog.setMessage(SELECT_DESTINATION_MESSAGE);
+ dialog.setText(SELECT_DESTINATION_TITLE);
+ dialog.setFilterPath(getDestinationValue());
+ String selectedDirectoryName = dialog.open();
+
+ if (selectedDirectoryName != null) {
+ setErrorMessage(null);
+ setDestinationValue(selectedDirectoryName);
+ }
+ }
+
+ /**
+ * Handle all events and enablements for widgets in this page
+ *
+ * @param e
+ * Event
+ */
+ public void handleEvent(Event e) {
+ Widget source = e.widget;
+
+ if (source == destinationBrowseButton)
+ handleDestinationBrowseButtonPressed();
+
+ updatePageCompletion();
+ }
+
+ /**
+ * Hook method for saving widget values for restoration by the next instance
+ * of this class.
+ */
+ protected void internalSaveWidgetValues() {
+ // update directory names history
+ IDialogSettings settings = getDialogSettings();
+ if (settings != null) {
+ String[] directoryNames = settings
+ .getArray(STORE_DESTINATION_NAMES_ID);
+ if (directoryNames == null)
+ directoryNames = new String[0];
+
+ directoryNames = addToHistory(directoryNames, getDestinationValue());
+ settings.put(STORE_DESTINATION_NAMES_ID, directoryNames);
+
+ // options
+ settings.put(STORE_OVERWRITE_EXISTING_FILES_ID,
+ overwriteExistingFilesCheckbox.getSelection());
+
+ // settings.put(
+ // STORE_CREATE_STRUCTURE_ID,
+ // createDirectoryStructureButton.getSelection());
+
+ }
+ }
+
+ /**
+ * Hook method for restoring widget values to the values that they held last
+ * time this wizard was used to completion.
+ */
+ protected void restoreWidgetValues() {
+ IDialogSettings settings = getDialogSettings();
+ if (settings != null) {
+ String[] directoryNames = settings
+ .getArray(STORE_DESTINATION_NAMES_ID);
+ if (directoryNames == null)
+ return; // ie.- no settings stored
+
+ // destination
+ setDestinationValue(directoryNames[0]);
+ for (int i = 0; i < directoryNames.length; i++)
+ addDestinationItem(directoryNames[i]);
+
+ // options
+ overwriteExistingFilesCheckbox.setSelection(settings
+ .getBoolean(STORE_OVERWRITE_EXISTING_FILES_ID));
+
+ // boolean createDirectories =
+ // settings.getBoolean(STORE_CREATE_STRUCTURE_ID);
+ // createDirectoryStructureButton.setSelection(createDirectories);
+ // createSelectionOnlyButton.setSelection(!createDirectories);
+ }
+ }
+
+ /**
+ * Set the contents of the receivers destination specification widget to the
+ * passed value
+ *
+ */
+ protected void setDestinationValue(String value) {
+ destinationNameField.setText(value);
+ }
+
+ /**
+ * Answer a boolean indicating whether the receivers destination
+ * specification widgets currently all contain valid values.
+ */
+ protected boolean validateDestinationGroup() {
+ String destinationValue = getDestinationValue();
+ if (destinationValue.length() == 0) {
+ setMessage(destinationEmptyMessage());
+ return false;
+ }
+
+ String conflictingContainer = getConflictingContainerNameFor(destinationValue);
+ if (conflictingContainer == null)
+ setErrorMessage(""); //$NON-NLS-1$
+ else {
+ setErrorMessage(ObfuscatorExportMessages.format(
+ "FileExport.conflictingContainer", //$NON-NLS-1$
+ new Object[] { conflictingContainer }));
+ giveFocusToDestination();
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Get the message used to denote an empty destination.
+ */
+ protected String destinationEmptyMessage() {
+ return ObfuscatorExportMessages
+ .getString("FileExport.destinationEmpty"); //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the name of a container with a location that encompasses
+ * targetDirectory. Returns null if there is no conflict.
+ *
+ * @param targetDirectory
+ * the path of the directory to check.
+ * @return the conflicting container name or <code>null</code>
+ */
+ protected String getConflictingContainerNameFor(String targetDirectory) {
+
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ IPath testPath = new Path(targetDirectory);
+
+ if (root.getLocation().isPrefixOf(testPath))
+ return ObfuscatorExportMessages.getString("FileExport.rootName"); //$NON-NLS-1$
+
+ IProject[] projects = root.getProjects();
+
+ for (int i = 0; i < projects.length; i++) {
+ if (projects[i].getLocation().isPrefixOf(testPath))
+ return projects[i].getName();
+ }
+
+ return null;
+
+ }
+
+}
--- /dev/null
+package net.sourceforge.phpeclipse.phpeditor;
+
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. 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 implementation
+ www.phpeclipse.de
+ **********************************************************************/
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.text.BreakIterator;
+import java.text.CharacterIterator;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.ResourceBundle;
+import java.util.StringTokenizer;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IImportContainer;
+import net.sourceforge.phpdt.core.IImportDeclaration;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.core.IMember;
+import net.sourceforge.phpdt.core.ISourceRange;
+import net.sourceforge.phpdt.core.ISourceReference;
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
+import net.sourceforge.phpdt.core.compiler.InvalidInputException;
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+import net.sourceforge.phpdt.internal.compiler.parser.SyntaxError;
+import net.sourceforge.phpdt.internal.ui.actions.CompositeActionGroup;
+import net.sourceforge.phpdt.internal.ui.actions.FoldingActionGroup;
+import net.sourceforge.phpdt.internal.ui.actions.SelectionConverter;
+import net.sourceforge.phpdt.internal.ui.text.CustomSourceInformationControl;
+import net.sourceforge.phpdt.internal.ui.text.DocumentCharacterIterator;
+import net.sourceforge.phpdt.internal.ui.text.HTMLTextPresenter;
+import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
+import net.sourceforge.phpdt.internal.ui.text.JavaWordFinder;
+import net.sourceforge.phpdt.internal.ui.text.JavaWordIterator;
+import net.sourceforge.phpdt.internal.ui.text.PHPPairMatcher;
+import net.sourceforge.phpdt.internal.ui.text.PreferencesAdapter;
+import net.sourceforge.phpdt.internal.ui.text.java.hover.JavaExpandHover;
+import net.sourceforge.phpdt.internal.ui.viewsupport.ISelectionListenerWithAST;
+import net.sourceforge.phpdt.internal.ui.viewsupport.IViewPartInputProvider;
+import net.sourceforge.phpdt.internal.ui.viewsupport.SelectionListenerWithASTManager;
+import net.sourceforge.phpdt.ui.IContextMenuConstants;
+import net.sourceforge.phpdt.ui.JavaUI;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpdt.ui.actions.GotoMatchingBracketAction;
+import net.sourceforge.phpdt.ui.actions.OpenEditorActionGroup;
+import net.sourceforge.phpdt.ui.text.JavaTextTools;
+import net.sourceforge.phpdt.ui.text.PHPSourceViewerConfiguration;
+import net.sourceforge.phpdt.ui.text.folding.IJavaFoldingStructureProvider;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.editor.BrowserUtil;
+import net.sourceforge.phpeclipse.webbrowser.views.BrowserView;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.GroupMarker;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DefaultInformationControl;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentExtension4;
+import org.eclipse.jface.text.IDocumentListener;
+import org.eclipse.jface.text.IInformationControl;
+import org.eclipse.jface.text.IInformationControlCreator;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ISelectionValidator;
+import org.eclipse.jface.text.ISynchronizable;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.ITextInputListener;
+import org.eclipse.jface.text.ITextPresentationListener;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.ITextViewerExtension2;
+import org.eclipse.jface.text.ITextViewerExtension4;
+import org.eclipse.jface.text.ITextViewerExtension5;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.jface.text.TextSelection;
+import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.jface.text.information.IInformationProvider;
+import org.eclipse.jface.text.information.InformationPresenter;
+import org.eclipse.jface.text.link.LinkedModeModel;
+import org.eclipse.jface.text.reconciler.IReconciler;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.AnnotationRulerColumn;
+import org.eclipse.jface.text.source.CompositeRuler;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.IAnnotationModelExtension;
+import org.eclipse.jface.text.source.IOverviewRuler;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.ISourceViewerExtension2;
+import org.eclipse.jface.text.source.IVerticalRuler;
+import org.eclipse.jface.text.source.IVerticalRulerColumn;
+import org.eclipse.jface.text.source.OverviewRuler;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+import org.eclipse.jface.text.source.projection.ProjectionSupport;
+import org.eclipse.jface.text.source.projection.ProjectionViewer;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.ListenerList;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.IPostSelectionProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.BidiSegmentEvent;
+import org.eclipse.swt.custom.BidiSegmentListener;
+import org.eclipse.swt.custom.ST;
+import org.eclipse.swt.custom.StyleRange;
+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.swt.events.MouseMoveListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IPartService;
+import org.eclipse.ui.ISelectionListener;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWindowListener;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.ActionContext;
+import org.eclipse.ui.actions.ActionGroup;
+import org.eclipse.ui.editors.text.DefaultEncodingSupport;
+import org.eclipse.ui.editors.text.EditorsUI;
+import org.eclipse.ui.editors.text.IEncodingSupport;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.ui.part.IShowInSource;
+import org.eclipse.ui.part.IShowInTargetList;
+import org.eclipse.ui.part.ShowInContext;
+import org.eclipse.ui.texteditor.AbstractDecoratedTextEditor;
+import org.eclipse.ui.texteditor.AnnotationPreference;
+import org.eclipse.ui.texteditor.ChainedPreferenceStore;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.IEditorStatusLine;
+import org.eclipse.ui.texteditor.ITextEditorActionConstants;
+import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
+import org.eclipse.ui.texteditor.IUpdate;
+import org.eclipse.ui.texteditor.MarkerAnnotation;
+import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
+import org.eclipse.ui.texteditor.TextEditorAction;
+import org.eclipse.ui.texteditor.TextNavigationAction;
+import org.eclipse.ui.texteditor.TextOperationAction;
+import org.eclipse.ui.views.contentoutline.ContentOutline;
+import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
+import org.eclipse.ui.views.tasklist.TaskList;
+
+/**
+ * PHP specific text editor.
+ */
+public abstract class PHPEditor extends AbstractDecoratedTextEditor implements
+ IViewPartInputProvider, IShowInTargetList, IShowInSource {
+ // extends StatusTextEditor implements IViewPartInputProvider { // extends
+ // TextEditor {
+
+ /**
+ * Internal implementation class for a change listener.
+ *
+ * @since 3.0
+ */
+ protected abstract class AbstractSelectionChangedListener implements
+ ISelectionChangedListener {
+
+ /**
+ * Installs this selection changed listener with the given selection
+ * provider. If the selection provider is a post selection provider,
+ * post selection changed events are the preferred choice, otherwise
+ * normal selection changed events are requested.
+ *
+ * @param selectionProvider
+ */
+ public void install(ISelectionProvider selectionProvider) {
+ if (selectionProvider == null)
+ return;
+
+ if (selectionProvider instanceof IPostSelectionProvider) {
+ IPostSelectionProvider provider = (IPostSelectionProvider) selectionProvider;
+ provider.addPostSelectionChangedListener(this);
+ } else {
+ selectionProvider.addSelectionChangedListener(this);
+ }
+ }
+
+ /**
+ * Removes this selection changed listener from the given selection
+ * provider.
+ *
+ * @param selectionProvider
+ * the selection provider
+ */
+ public void uninstall(ISelectionProvider selectionProvider) {
+ if (selectionProvider == null)
+ return;
+
+ if (selectionProvider instanceof IPostSelectionProvider) {
+ IPostSelectionProvider provider = (IPostSelectionProvider) selectionProvider;
+ provider.removePostSelectionChangedListener(this);
+ } else {
+ selectionProvider.removeSelectionChangedListener(this);
+ }
+ }
+ }
+
+ /**
+ * Updates the Java outline page selection and this editor's range
+ * indicator.
+ *
+ * @since 3.0
+ */
+ private class EditorSelectionChangedListener extends
+ AbstractSelectionChangedListener {
+
+ /*
+ * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
+ */
+ public void selectionChanged(SelectionChangedEvent event) {
+ // XXX: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=56161
+ PHPEditor.this.selectionChanged();
+ }
+ }
+
+ /**
+ * "Smart" runnable for updating the outline page's selection.
+ */
+ // class OutlinePageSelectionUpdater implements Runnable {
+ //
+ // /** Has the runnable already been posted? */
+ // private boolean fPosted = false;
+ //
+ // public OutlinePageSelectionUpdater() {
+ // }
+ //
+ // /*
+ // * @see Runnable#run()
+ // */
+ // public void run() {
+ // synchronizeOutlinePageSelection();
+ // fPosted = false;
+ // }
+ //
+ // /**
+ // * Posts this runnable into the event queue.
+ // */
+ // public void post() {
+ // if (fPosted)
+ // return;
+ //
+ // Shell shell = getSite().getShell();
+ // if (shell != null & !shell.isDisposed()) {
+ // fPosted = true;
+ // shell.getDisplay().asyncExec(this);
+ // }
+ // }
+ // };
+ class SelectionChangedListener implements ISelectionChangedListener {
+ public void selectionChanged(SelectionChangedEvent event) {
+ doSelectionChanged(event);
+ }
+ };
+
+ /**
+ * Adapts an options {@link java.util.Map}to
+ * {@link org.eclipse.jface.preference.IPreferenceStore}.
+ * <p>
+ * This preference store is read-only i.e. write access throws an
+ * {@link java.lang.UnsupportedOperationException}.
+ * </p>
+ *
+ * @since 3.0
+ */
+ private static class OptionsAdapter implements IPreferenceStore {
+
+ /**
+ * A property change event filter.
+ */
+ public interface IPropertyChangeEventFilter {
+
+ /**
+ * Should the given event be filtered?
+ *
+ * @param event
+ * The property change event.
+ * @return <code>true</code> iff the given event should be
+ * filtered.
+ */
+ public boolean isFiltered(PropertyChangeEvent event);
+
+ }
+
+ /**
+ * Property change listener. Listens for events in the options Map and
+ * fires a {@link org.eclipse.jface.util.PropertyChangeEvent}on this
+ * adapter with arguments from the received event.
+ */
+ private class PropertyChangeListener implements IPropertyChangeListener {
+
+ /**
+ * {@inheritDoc}
+ */
+ public void propertyChange(PropertyChangeEvent event) {
+ if (getFilter().isFiltered(event))
+ return;
+
+ if (event.getNewValue() == null)
+ fOptions.remove(event.getProperty());
+ else
+ fOptions.put(event.getProperty(), event.getNewValue());
+
+ firePropertyChangeEvent(event.getProperty(), event
+ .getOldValue(), event.getNewValue());
+ }
+ }
+
+ /** Listeners on this adapter */
+ private ListenerList fListeners = new ListenerList();
+
+ /** Listener on the adapted options Map */
+ private IPropertyChangeListener fListener = new PropertyChangeListener();
+
+ /** Adapted options Map */
+ private Map fOptions;
+
+ /** Preference store through which events are received. */
+ private IPreferenceStore fMockupPreferenceStore;
+
+ /** Property event filter. */
+ private IPropertyChangeEventFilter fFilter;
+
+ /**
+ * Initialize with the given options.
+ *
+ * @param options
+ * The options to wrap
+ * @param mockupPreferenceStore
+ * the mock-up preference store
+ * @param filter
+ * the property change filter
+ */
+ public OptionsAdapter(Map options,
+ IPreferenceStore mockupPreferenceStore,
+ IPropertyChangeEventFilter filter) {
+ fMockupPreferenceStore = mockupPreferenceStore;
+ fOptions = options;
+ setFilter(filter);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addPropertyChangeListener(IPropertyChangeListener listener) {
+ if (fListeners.size() == 0)
+ fMockupPreferenceStore.addPropertyChangeListener(fListener);
+ fListeners.add(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void removePropertyChangeListener(
+ IPropertyChangeListener listener) {
+ fListeners.remove(listener);
+ if (fListeners.size() == 0)
+ fMockupPreferenceStore.removePropertyChangeListener(fListener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean contains(String name) {
+ return fOptions.containsKey(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void firePropertyChangeEvent(String name, Object oldValue,
+ Object newValue) {
+ 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) {
+ boolean value = BOOLEAN_DEFAULT_DEFAULT;
+ String s = (String) fOptions.get(name);
+ if (s != null)
+ value = s.equals(TRUE);
+ return value;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean getDefaultBoolean(String name) {
+ return BOOLEAN_DEFAULT_DEFAULT;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public double getDefaultDouble(String name) {
+ return DOUBLE_DEFAULT_DEFAULT;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public float getDefaultFloat(String name) {
+ return FLOAT_DEFAULT_DEFAULT;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getDefaultInt(String name) {
+ return INT_DEFAULT_DEFAULT;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public long getDefaultLong(String name) {
+ return LONG_DEFAULT_DEFAULT;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getDefaultString(String name) {
+ return STRING_DEFAULT_DEFAULT;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public double getDouble(String name) {
+ double value = DOUBLE_DEFAULT_DEFAULT;
+ String s = (String) fOptions.get(name);
+ if (s != null) {
+ try {
+ value = new Double(s).doubleValue();
+ } catch (NumberFormatException e) {
+ }
+ }
+ return value;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public float getFloat(String name) {
+ float value = FLOAT_DEFAULT_DEFAULT;
+ String s = (String) fOptions.get(name);
+ if (s != null) {
+ try {
+ value = new Float(s).floatValue();
+ } catch (NumberFormatException e) {
+ }
+ }
+ return value;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getInt(String name) {
+ int value = INT_DEFAULT_DEFAULT;
+ String s = (String) fOptions.get(name);
+ if (s != null) {
+ try {
+ value = new Integer(s).intValue();
+ } catch (NumberFormatException e) {
+ }
+ }
+ return value;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public long getLong(String name) {
+ long value = LONG_DEFAULT_DEFAULT;
+ String s = (String) fOptions.get(name);
+ if (s != null) {
+ try {
+ value = new Long(s).longValue();
+ } catch (NumberFormatException e) {
+ }
+ }
+ return value;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getString(String name) {
+ String value = (String) fOptions.get(name);
+ if (value == null)
+ value = STRING_DEFAULT_DEFAULT;
+ return value;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isDefault(String name) {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean needsSaving() {
+ return !fOptions.isEmpty();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void putValue(String name, String value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setDefault(String name, double value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setDefault(String name, float value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setDefault(String name, int value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setDefault(String name, long value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setDefault(String name, String defaultObject) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setDefault(String name, boolean value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setToDefault(String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setValue(String name, double value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setValue(String name, float value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setValue(String name, int value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setValue(String name, long value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setValue(String name, String value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setValue(String name, boolean value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns the adapted options Map.
+ *
+ * @return Returns the adapted options Map.
+ */
+ public Map getOptions() {
+ return fOptions;
+ }
+
+ /**
+ * Returns the mock-up preference store, events are received through
+ * this preference store.
+ *
+ * @return Returns the mock-up preference store.
+ */
+ public IPreferenceStore getMockupPreferenceStore() {
+ return fMockupPreferenceStore;
+ }
+
+ /**
+ * Set the event filter to the given filter.
+ *
+ * @param filter
+ * The new filter.
+ */
+ public void setFilter(IPropertyChangeEventFilter filter) {
+ fFilter = filter;
+ }
+
+ /**
+ * Returns the event filter.
+ *
+ * @return The event filter.
+ */
+ public IPropertyChangeEventFilter getFilter() {
+ return fFilter;
+ }
+ }
+
+ /*
+ * Link mode.
+ */
+ // class MouseClickListener implements KeyListener, MouseListener,
+ // MouseMoveListener, FocusListener, PaintListener,
+ // IPropertyChangeListener, IDocumentListener, ITextInputListener {
+ //
+ // /** The session is active. */
+ // private boolean fActive;
+ //
+ // /** The currently active style range. */
+ // private IRegion fActiveRegion;
+ //
+ // /** The currently active style range as position. */
+ // private Position fRememberedPosition;
+ //
+ // /** The hand cursor. */
+ // private Cursor fCursor;
+ //
+ // /** The link color. */
+ // private Color fColor;
+ //
+ // /** The key modifier mask. */
+ // private int fKeyModifierMask;
+ //
+ // public void deactivate() {
+ // deactivate(false);
+ // }
+ //
+ // public void deactivate(boolean redrawAll) {
+ // if (!fActive)
+ // return;
+ //
+ // repairRepresentation(redrawAll);
+ // fActive = false;
+ // }
+ //
+ // public void install() {
+ //
+ // ISourceViewer sourceViewer = getSourceViewer();
+ // if (sourceViewer == null)
+ // return;
+ //
+ // StyledText text = sourceViewer.getTextWidget();
+ // if (text == null || text.isDisposed())
+ // return;
+ //
+ // updateColor(sourceViewer);
+ //
+ // sourceViewer.addTextInputListener(this);
+ //
+ // IDocument document = sourceViewer.getDocument();
+ // if (document != null)
+ // document.addDocumentListener(this);
+ //
+ // text.addKeyListener(this);
+ // text.addMouseListener(this);
+ // text.addMouseMoveListener(this);
+ // text.addFocusListener(this);
+ // text.addPaintListener(this);
+ //
+ // updateKeyModifierMask();
+ //
+ // IPreferenceStore preferenceStore = getPreferenceStore();
+ // preferenceStore.addPropertyChangeListener(this);
+ // }
+ //
+ // private void updateKeyModifierMask() {
+ // String modifiers =
+ // getPreferenceStore().getString(BROWSER_LIKE_LINKS_KEY_MODIFIER);
+ // fKeyModifierMask = computeStateMask(modifiers);
+ // if (fKeyModifierMask == -1) {
+ // // Fallback to stored state mask
+ // fKeyModifierMask =
+ // getPreferenceStore().getInt(BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK);
+ // }
+ // ;
+ // }
+ //
+ // private int computeStateMask(String modifiers) {
+ // if (modifiers == null)
+ // return -1;
+ //
+ // if (modifiers.length() == 0)
+ // return SWT.NONE;
+ //
+ // int stateMask = 0;
+ // StringTokenizer modifierTokenizer = new StringTokenizer(modifiers,
+ // ",;.:+-*
+ // "); //$NON-NLS-1$
+ // while (modifierTokenizer.hasMoreTokens()) {
+ // int modifier =
+ // EditorUtility.findLocalizedModifier(modifierTokenizer.nextToken());
+ // if (modifier == 0 || (stateMask & modifier) == modifier)
+ // return -1;
+ // stateMask = stateMask | modifier;
+ // }
+ // return stateMask;
+ // }
+ //
+ // public void uninstall() {
+ //
+ // if (fColor != null) {
+ // fColor.dispose();
+ // fColor = null;
+ // }
+ //
+ // if (fCursor != null) {
+ // fCursor.dispose();
+ // fCursor = null;
+ // }
+ //
+ // ISourceViewer sourceViewer = getSourceViewer();
+ // if (sourceViewer == null)
+ // return;
+ //
+ // sourceViewer.removeTextInputListener(this);
+ //
+ // IDocument document = sourceViewer.getDocument();
+ // if (document != null)
+ // document.removeDocumentListener(this);
+ //
+ // IPreferenceStore preferenceStore = getPreferenceStore();
+ // if (preferenceStore != null)
+ // preferenceStore.removePropertyChangeListener(this);
+ //
+ // StyledText text = sourceViewer.getTextWidget();
+ // if (text == null || text.isDisposed())
+ // return;
+ //
+ // text.removeKeyListener(this);
+ // text.removeMouseListener(this);
+ // text.removeMouseMoveListener(this);
+ // text.removeFocusListener(this);
+ // text.removePaintListener(this);
+ // }
+ //
+ // /*
+ // * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
+ // */
+ // public void propertyChange(PropertyChangeEvent event) {
+ // if (event.getProperty().equals(PHPEditor.LINK_COLOR)) {
+ // ISourceViewer viewer = getSourceViewer();
+ // if (viewer != null)
+ // updateColor(viewer);
+ // } else if (event.getProperty().equals(BROWSER_LIKE_LINKS_KEY_MODIFIER)) {
+ // updateKeyModifierMask();
+ // }
+ // }
+ //
+ // private void updateColor(ISourceViewer viewer) {
+ // if (fColor != null)
+ // fColor.dispose();
+ //
+ // StyledText text = viewer.getTextWidget();
+ // if (text == null || text.isDisposed())
+ // return;
+ //
+ // Display display = text.getDisplay();
+ // fColor = createColor(getPreferenceStore(), PHPEditor.LINK_COLOR,
+ // display);
+ // }
+ //
+ // /**
+ // * Creates a color from the information stored in the given preference
+ // store. Returns <code>null</code> if there is no such
+ // * information available.
+ // */
+ // private Color createColor(IPreferenceStore store, String key, Display
+ // display) {
+ //
+ // RGB rgb = null;
+ //
+ // if (store.contains(key)) {
+ //
+ // if (store.isDefault(key))
+ // rgb = PreferenceConverter.getDefaultColor(store, key);
+ // else
+ // rgb = PreferenceConverter.getColor(store, key);
+ //
+ // if (rgb != null)
+ // return new Color(display, rgb);
+ // }
+ //
+ // return null;
+ // }
+ //
+ // private void repairRepresentation() {
+ // repairRepresentation(false);
+ // }
+ //
+ // private void repairRepresentation(boolean redrawAll) {
+ //
+ // if (fActiveRegion == null)
+ // return;
+ //
+ // ISourceViewer viewer = getSourceViewer();
+ // if (viewer != null) {
+ // resetCursor(viewer);
+ //
+ // int offset = fActiveRegion.getOffset();
+ // int length = fActiveRegion.getLength();
+ //
+ // // remove style
+ // if (!redrawAll && viewer instanceof ITextViewerExtension2)
+ // ((ITextViewerExtension2) viewer).invalidateTextPresentation(offset,
+ // length);
+ // else
+ // viewer.invalidateTextPresentation();
+ //
+ // // remove underline
+ // if (viewer instanceof ITextViewerExtension3) {
+ // ITextViewerExtension3 extension = (ITextViewerExtension3) viewer;
+ // offset = extension.modelOffset2WidgetOffset(offset);
+ // } else {
+ // offset -= viewer.getVisibleRegion().getOffset();
+ // }
+ //
+ // StyledText text = viewer.getTextWidget();
+ // try {
+ // text.redrawRange(offset, length, true);
+ // } catch (IllegalArgumentException x) {
+ // PHPeclipsePlugin.log(x);
+ // }
+ // }
+ //
+ // fActiveRegion = null;
+ // }
+ //
+ // // will eventually be replaced by a method provided by jdt.core
+ // private IRegion selectWord(IDocument document, int anchor) {
+ //
+ // try {
+ // int offset = anchor;
+ // char c;
+ //
+ // while (offset >= 0) {
+ // c = document.getChar(offset);
+ // if (!Scanner.isPHPIdentifierPart(c))
+ // break;
+ // --offset;
+ // }
+ //
+ // int start = offset;
+ //
+ // offset = anchor;
+ // int length = document.getLength();
+ //
+ // while (offset < length) {
+ // c = document.getChar(offset);
+ // if (!Scanner.isPHPIdentifierPart(c))
+ // break;
+ // ++offset;
+ // }
+ //
+ // int end = offset;
+ //
+ // if (start == end)
+ // return new Region(start, 0);
+ // else
+ // return new Region(start + 1, end - start - 1);
+ //
+ // } catch (BadLocationException x) {
+ // return null;
+ // }
+ // }
+ //
+ // IRegion getCurrentTextRegion(ISourceViewer viewer) {
+ //
+ // int offset = getCurrentTextOffset(viewer);
+ // if (offset == -1)
+ // return null;
+ //
+ // return null;
+ // // IJavaElement input= SelectionConverter.getInput(PHPEditor.this);
+ // // if (input == null)
+ // // return null;
+ // //
+ // // try {
+ // //
+ // // IJavaElement[] elements= null;
+ // // synchronized (input) {
+ // // elements= ((ICodeAssist) input).codeSelect(offset, 0);
+ // // }
+ // //
+ // // if (elements == null || elements.length == 0)
+ // // return null;
+ // //
+ // // return selectWord(viewer.getDocument(), offset);
+ // //
+ // // } catch (JavaModelException e) {
+ // // return null;
+ // // }
+ // }
+ //
+ // private int getCurrentTextOffset(ISourceViewer viewer) {
+ //
+ // try {
+ // StyledText text = viewer.getTextWidget();
+ // if (text == null || text.isDisposed())
+ // return -1;
+ //
+ // Display display = text.getDisplay();
+ // Point absolutePosition = display.getCursorLocation();
+ // Point relativePosition = text.toControl(absolutePosition);
+ //
+ // int widgetOffset = text.getOffsetAtLocation(relativePosition);
+ // if (viewer instanceof ITextViewerExtension3) {
+ // ITextViewerExtension3 extension = (ITextViewerExtension3) viewer;
+ // return extension.widgetOffset2ModelOffset(widgetOffset);
+ // } else {
+ // return widgetOffset + viewer.getVisibleRegion().getOffset();
+ // }
+ //
+ // } catch (IllegalArgumentException e) {
+ // return -1;
+ // }
+ // }
+ //
+ // private void highlightRegion(ISourceViewer viewer, IRegion region) {
+ //
+ // if (region.equals(fActiveRegion))
+ // return;
+ //
+ // repairRepresentation();
+ //
+ // StyledText text = viewer.getTextWidget();
+ // if (text == null || text.isDisposed())
+ // return;
+ //
+ // // highlight region
+ // int offset = 0;
+ // int length = 0;
+ //
+ // if (viewer instanceof ITextViewerExtension3) {
+ // ITextViewerExtension3 extension = (ITextViewerExtension3) viewer;
+ // IRegion widgetRange = extension.modelRange2WidgetRange(region);
+ // if (widgetRange == null)
+ // return;
+ //
+ // offset = widgetRange.getOffset();
+ // length = widgetRange.getLength();
+ //
+ // } else {
+ // offset = region.getOffset() - viewer.getVisibleRegion().getOffset();
+ // length = region.getLength();
+ // }
+ //
+ // StyleRange oldStyleRange = text.getStyleRangeAtOffset(offset);
+ // Color foregroundColor = fColor;
+ // Color backgroundColor = oldStyleRange == null ? text.getBackground() :
+ // oldStyleRange.background;
+ // StyleRange styleRange = new StyleRange(offset, length, foregroundColor,
+ // backgroundColor);
+ // text.setStyleRange(styleRange);
+ //
+ // // underline
+ // text.redrawRange(offset, length, true);
+ //
+ // fActiveRegion = region;
+ // }
+ //
+ // private void activateCursor(ISourceViewer viewer) {
+ // StyledText text = viewer.getTextWidget();
+ // if (text == null || text.isDisposed())
+ // return;
+ // Display display = text.getDisplay();
+ // if (fCursor == null)
+ // fCursor = new Cursor(display, SWT.CURSOR_HAND);
+ // text.setCursor(fCursor);
+ // }
+ //
+ // private void resetCursor(ISourceViewer viewer) {
+ // StyledText text = viewer.getTextWidget();
+ // if (text != null && !text.isDisposed())
+ // text.setCursor(null);
+ //
+ // if (fCursor != null) {
+ // fCursor.dispose();
+ // fCursor = null;
+ // }
+ // }
+ //
+ // /*
+ // * @see
+ // org.eclipse.swt.events.KeyListener#keyPressed(org.eclipse.swt.events.KeyEvent)
+ // */
+ // public void keyPressed(KeyEvent event) {
+ //
+ // if (fActive) {
+ // deactivate();
+ // return;
+ // }
+ //
+ // if (event.keyCode != fKeyModifierMask) {
+ // deactivate();
+ // return;
+ // }
+ //
+ // fActive = true;
+ //
+ // // removed for #25871
+ // //
+ // // ISourceViewer viewer= getSourceViewer();
+ // // if (viewer == null)
+ // // return;
+ // //
+ // // IRegion region= getCurrentTextRegion(viewer);
+ // // if (region == null)
+ // // return;
+ // //
+ // // highlightRegion(viewer, region);
+ // // activateCursor(viewer);
+ // }
+ //
+ // /*
+ // * @see
+ // org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent)
+ // */
+ // public void keyReleased(KeyEvent event) {
+ //
+ // if (!fActive)
+ // return;
+ //
+ // deactivate();
+ // }
+ //
+ // /*
+ // * @see
+ // org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
+ // */
+ // public void mouseDoubleClick(MouseEvent e) {
+ // }
+ //
+ // /*
+ // * @see
+ // org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent)
+ // */
+ // public void mouseDown(MouseEvent event) {
+ //
+ // if (!fActive)
+ // return;
+ //
+ // if (event.stateMask != fKeyModifierMask) {
+ // deactivate();
+ // return;
+ // }
+ //
+ // if (event.button != 1) {
+ // deactivate();
+ // return;
+ // }
+ // }
+ //
+ // /*
+ // * @see
+ // org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent)
+ // */
+ // public void mouseUp(MouseEvent e) {
+ //
+ // if (!fActive)
+ // return;
+ //
+ // if (e.button != 1) {
+ // deactivate();
+ // return;
+ // }
+ //
+ // boolean wasActive = fCursor != null;
+ //
+ // deactivate();
+ //
+ // if (wasActive) {
+ // IAction action = getAction("OpenEditor"); //$NON-NLS-1$
+ // if (action != null)
+ // action.run();
+ // }
+ // }
+ //
+ // /*
+ // * @see
+ // org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent)
+ // */
+ // public void mouseMove(MouseEvent event) {
+ //
+ // if (event.widget instanceof Control && !((Control)
+ // event.widget).isFocusControl()) {
+ // deactivate();
+ // return;
+ // }
+ //
+ // if (!fActive) {
+ // if (event.stateMask != fKeyModifierMask)
+ // return;
+ // // modifier was already pressed
+ // fActive = true;
+ // }
+ //
+ // ISourceViewer viewer = getSourceViewer();
+ // if (viewer == null) {
+ // deactivate();
+ // return;
+ // }
+ //
+ // StyledText text = viewer.getTextWidget();
+ // if (text == null || text.isDisposed()) {
+ // deactivate();
+ // return;
+ // }
+ //
+ // if ((event.stateMask & SWT.BUTTON1) != 0 && text.getSelectionCount() !=
+ // 0)
+ // {
+ // deactivate();
+ // return;
+ // }
+ //
+ // IRegion region = getCurrentTextRegion(viewer);
+ // if (region == null || region.getLength() == 0) {
+ // repairRepresentation();
+ // return;
+ // }
+ //
+ // highlightRegion(viewer, region);
+ // activateCursor(viewer);
+ // }
+ //
+ // /*
+ // * @see
+ // org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.swt.events.FocusEvent)
+ // */
+ // public void focusGained(FocusEvent e) {
+ // }
+ //
+ // /*
+ // * @see
+ // org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt.events.FocusEvent)
+ // */
+ // public void focusLost(FocusEvent event) {
+ // deactivate();
+ // }
+ //
+ // /*
+ // * @see
+ // org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
+ // */
+ // public void documentAboutToBeChanged(DocumentEvent event) {
+ // if (fActive && fActiveRegion != null) {
+ // fRememberedPosition = new Position(fActiveRegion.getOffset(),
+ // fActiveRegion.getLength());
+ // try {
+ // event.getDocument().addPosition(fRememberedPosition);
+ // } catch (BadLocationException x) {
+ // fRememberedPosition = null;
+ // }
+ // }
+ // }
+ //
+ // /*
+ // * @see
+ // org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent)
+ // */
+ // public void documentChanged(DocumentEvent event) {
+ // if (fRememberedPosition != null && !fRememberedPosition.isDeleted()) {
+ // event.getDocument().removePosition(fRememberedPosition);
+ // fActiveRegion = new Region(fRememberedPosition.getOffset(),
+ // fRememberedPosition.getLength());
+ // }
+ // fRememberedPosition = null;
+ //
+ // ISourceViewer viewer = getSourceViewer();
+ // if (viewer != null) {
+ // StyledText widget = viewer.getTextWidget();
+ // if (widget != null && !widget.isDisposed()) {
+ // widget.getDisplay().asyncExec(new Runnable() {
+ // public void run() {
+ // deactivate();
+ // }
+ // });
+ // }
+ // }
+ // }
+ //
+ // /*
+ // * @see
+ // org.eclipse.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(org.eclipse.jface.text.IDocument,
+ // * org.eclipse.jface.text.IDocument)
+ // */
+ // public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument
+ // newInput) {
+ // if (oldInput == null)
+ // return;
+ // deactivate();
+ // oldInput.removeDocumentListener(this);
+ // }
+ //
+ // /*
+ // * @see
+ // org.eclipse.jface.text.ITextInputListener#inputDocumentChanged(org.eclipse.jface.text.IDocument,
+ // * org.eclipse.jface.text.IDocument)
+ // */
+ // public void inputDocumentChanged(IDocument oldInput, IDocument newInput)
+ // {
+ // if (newInput == null)
+ // return;
+ // newInput.addDocumentListener(this);
+ // }
+ //
+ // /*
+ // * @see PaintListener#paintControl(PaintEvent)
+ // */
+ // public void paintControl(PaintEvent event) {
+ // if (fActiveRegion == null)
+ // return;
+ //
+ // ISourceViewer viewer = getSourceViewer();
+ // if (viewer == null)
+ // return;
+ //
+ // StyledText text = viewer.getTextWidget();
+ // if (text == null || text.isDisposed())
+ // return;
+ //
+ // int offset = 0;
+ // int length = 0;
+ //
+ // if (viewer instanceof ITextViewerExtension3) {
+ //
+ // ITextViewerExtension3 extension = (ITextViewerExtension3) viewer;
+ // IRegion widgetRange = extension.modelRange2WidgetRange(new Region(offset,
+ // length));
+ // if (widgetRange == null)
+ // return;
+ //
+ // offset = widgetRange.getOffset();
+ // length = widgetRange.getLength();
+ //
+ // } else {
+ //
+ // IRegion region = viewer.getVisibleRegion();
+ // if (!includes(region, fActiveRegion))
+ // return;
+ //
+ // offset = fActiveRegion.getOffset() - region.getOffset();
+ // length = fActiveRegion.getLength();
+ // }
+ //
+ // // support for bidi
+ // Point minLocation = getMinimumLocation(text, offset, length);
+ // Point maxLocation = getMaximumLocation(text, offset, length);
+ //
+ // int x1 = minLocation.x;
+ // int x2 = minLocation.x + maxLocation.x - minLocation.x - 1;
+ // int y = minLocation.y + text.getLineHeight() - 1;
+ //
+ // GC gc = event.gc;
+ // if (fColor != null && !fColor.isDisposed())
+ // gc.setForeground(fColor);
+ // gc.drawLine(x1, y, x2, y);
+ // }
+ //
+ // private boolean includes(IRegion region, IRegion position) {
+ // return position.getOffset() >= region.getOffset()
+ // && position.getOffset() + position.getLength() <= region.getOffset() +
+ // region.getLength();
+ // }
+ //
+ // private Point getMinimumLocation(StyledText text, int offset, int length)
+ // {
+ // Point minLocation = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE);
+ //
+ // for (int i = 0; i <= length; i++) {
+ // Point location = text.getLocationAtOffset(offset + i);
+ //
+ // if (location.x < minLocation.x)
+ // minLocation.x = location.x;
+ // if (location.y < minLocation.y)
+ // minLocation.y = location.y;
+ // }
+ //
+ // return minLocation;
+ // }
+ //
+ // private Point getMaximumLocation(StyledText text, int offset, int length)
+ // {
+ // Point maxLocation = new Point(Integer.MIN_VALUE, Integer.MIN_VALUE);
+ //
+ // for (int i = 0; i <= length; i++) {
+ // Point location = text.getLocationAtOffset(offset + i);
+ //
+ // if (location.x > maxLocation.x)
+ // maxLocation.x = location.x;
+ // if (location.y > maxLocation.y)
+ // maxLocation.y = location.y;
+ // }
+ //
+ // return maxLocation;
+ // }
+ // };
+ /*
+ * Link mode.
+ */
+ class MouseClickListener implements KeyListener, MouseListener,
+ MouseMoveListener, FocusListener, PaintListener,
+ IPropertyChangeListener, IDocumentListener, ITextInputListener,
+ ITextPresentationListener {
+
+ /** The session is active. */
+ private boolean fActive;
+
+ /** The currently active style range. */
+ private IRegion fActiveRegion;
+
+ /** The currently active style range as position. */
+ private Position fRememberedPosition;
+
+ /** The hand cursor. */
+ private Cursor fCursor;
+
+ /** The link color. */
+ private Color fColor;
+
+ /** The key modifier mask. */
+ private int fKeyModifierMask;
+
+ public void deactivate() {
+ deactivate(false);
+ }
+
+ public void deactivate(boolean redrawAll) {
+ if (!fActive)
+ return;
+
+ repairRepresentation(redrawAll);
+ fActive = false;
+ }
+
+ public void install() {
+ ISourceViewer sourceViewer = getSourceViewer();
+ if (sourceViewer == null)
+ return;
+
+ StyledText text = sourceViewer.getTextWidget();
+ if (text == null || text.isDisposed())
+ return;
+
+ updateColor(sourceViewer);
+
+ sourceViewer.addTextInputListener(this);
+
+ IDocument document = sourceViewer.getDocument();
+ if (document != null)
+ document.addDocumentListener(this);
+
+ text.addKeyListener(this);
+ text.addMouseListener(this);
+ text.addMouseMoveListener(this);
+ text.addFocusListener(this);
+ text.addPaintListener(this);
+
+ ((ITextViewerExtension4) sourceViewer)
+ .addTextPresentationListener(this);
+
+ updateKeyModifierMask();
+
+ IPreferenceStore preferenceStore = getPreferenceStore();
+ preferenceStore.addPropertyChangeListener(this);
+ }
+
+ private void updateKeyModifierMask() {
+ String modifiers = getPreferenceStore().getString(
+ BROWSER_LIKE_LINKS_KEY_MODIFIER);
+ fKeyModifierMask = computeStateMask(modifiers);
+ if (fKeyModifierMask == -1) {
+ // Fall back to stored state mask
+ fKeyModifierMask = getPreferenceStore().getInt(
+ BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK);
+ }
+ }
+
+ private int computeStateMask(String modifiers) {
+ if (modifiers == null)
+ return -1;
+
+ if (modifiers.length() == 0)
+ return SWT.NONE;
+
+ int stateMask = 0;
+ StringTokenizer modifierTokenizer = new StringTokenizer(modifiers,
+ ",;.:+-* "); //$NON-NLS-1$
+ while (modifierTokenizer.hasMoreTokens()) {
+ int modifier = EditorUtility
+ .findLocalizedModifier(modifierTokenizer.nextToken());
+ if (modifier == 0 || (stateMask & modifier) == modifier)
+ return -1;
+ stateMask = stateMask | modifier;
+ }
+ return stateMask;
+ }
+
+ public void uninstall() {
+
+ if (fColor != null) {
+ fColor.dispose();
+ fColor = null;
+ }
+
+ if (fCursor != null) {
+ fCursor.dispose();
+ fCursor = null;
+ }
+
+ ISourceViewer sourceViewer = getSourceViewer();
+ if (sourceViewer != null)
+ sourceViewer.removeTextInputListener(this);
+
+ IDocumentProvider documentProvider = getDocumentProvider();
+ if (documentProvider != null) {
+ IDocument document = documentProvider
+ .getDocument(getEditorInput());
+ if (document != null)
+ document.removeDocumentListener(this);
+ }
+
+ IPreferenceStore preferenceStore = getPreferenceStore();
+ if (preferenceStore != null)
+ preferenceStore.removePropertyChangeListener(this);
+
+ if (sourceViewer == null)
+ return;
+
+ StyledText text = sourceViewer.getTextWidget();
+ if (text == null || text.isDisposed())
+ return;
+
+ text.removeKeyListener(this);
+ text.removeMouseListener(this);
+ text.removeMouseMoveListener(this);
+ text.removeFocusListener(this);
+ text.removePaintListener(this);
+
+ ((ITextViewerExtension4) sourceViewer)
+ .removeTextPresentationListener(this);
+ }
+
+ /*
+ * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
+ */
+ public void propertyChange(PropertyChangeEvent event) {
+ if (event.getProperty().equals(PHPEditor.LINK_COLOR)) {
+ ISourceViewer viewer = getSourceViewer();
+ if (viewer != null)
+ updateColor(viewer);
+ } else if (event.getProperty().equals(
+ BROWSER_LIKE_LINKS_KEY_MODIFIER)) {
+ updateKeyModifierMask();
+ }
+ }
+
+ private void updateColor(ISourceViewer viewer) {
+ if (fColor != null)
+ fColor.dispose();
+
+ StyledText text = viewer.getTextWidget();
+ if (text == null || text.isDisposed())
+ return;
+
+ Display display = text.getDisplay();
+ fColor = createColor(getPreferenceStore(), PHPEditor.LINK_COLOR,
+ display);
+ }
+
+ /**
+ * Creates a color from the information stored in the given preference
+ * store.
+ *
+ * @param store
+ * the preference store
+ * @param key
+ * the key
+ * @param display
+ * the display
+ * @return the color or <code>null</code> if there is no such
+ * information available
+ */
+ private Color createColor(IPreferenceStore store, String key,
+ Display display) {
+
+ RGB rgb = null;
+
+ if (store.contains(key)) {
+
+ if (store.isDefault(key))
+ rgb = PreferenceConverter.getDefaultColor(store, key);
+ else
+ rgb = PreferenceConverter.getColor(store, key);
+
+ if (rgb != null)
+ return new Color(display, rgb);
+ }
+
+ return null;
+ }
+
+ private void repairRepresentation() {
+ repairRepresentation(false);
+ }
+
+ private void repairRepresentation(boolean redrawAll) {
+
+ if (fActiveRegion == null)
+ return;
+
+ int offset = fActiveRegion.getOffset();
+ int length = fActiveRegion.getLength();
+ fActiveRegion = null;
+
+ ISourceViewer viewer = getSourceViewer();
+ if (viewer != null) {
+
+ resetCursor(viewer);
+
+ // Invalidate ==> remove applied text presentation
+ if (!redrawAll && viewer instanceof ITextViewerExtension2)
+ ((ITextViewerExtension2) viewer)
+ .invalidateTextPresentation(offset, length);
+ else
+ viewer.invalidateTextPresentation();
+
+ // Remove underline
+ if (viewer instanceof ITextViewerExtension5) {
+ ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
+ offset = extension.modelOffset2WidgetOffset(offset);
+ } else {
+ offset -= viewer.getVisibleRegion().getOffset();
+ }
+ try {
+ StyledText text = viewer.getTextWidget();
+
+ text.redrawRange(offset, length, false);
+ } catch (IllegalArgumentException x) {
+ // JavaPlugin.log(x);
+ }
+ }
+ }
+
+ // will eventually be replaced by a method provided by jdt.core
+ private IRegion selectWord(IDocument document, int anchor) {
+
+ try {
+ int offset = anchor;
+ char c;
+
+ while (offset >= 0) {
+ c = document.getChar(offset);
+ if (!Scanner.isPHPIdentifierPart(c) && c != '$')
+ break;
+ --offset;
+ }
+
+ int start = offset;
+
+ offset = anchor;
+ int length = document.getLength();
+
+ while (offset < length) {
+ c = document.getChar(offset);
+ if (!Scanner.isPHPIdentifierPart(c) && c != '$')
+ break;
+ ++offset;
+ }
+
+ int end = offset;
+
+ if (start == end)
+ return new Region(start, 0);
+ else
+ return new Region(start + 1, end - start - 1);
+
+ } catch (BadLocationException x) {
+ return null;
+ }
+ }
+
+ IRegion getCurrentTextRegion(ISourceViewer viewer) {
+
+ int offset = getCurrentTextOffset(viewer);
+ if (offset == -1)
+ return null;
+
+ IJavaElement input = SelectionConverter.getInput(PHPEditor.this);
+ if (input == null)
+ return null;
+
+ // try {
+
+ // IJavaElement[] elements= null;
+ // synchronized (input) {
+ // elements= ((ICodeAssist) input).codeSelect(offset, 0);
+ // }
+ //
+ // if (elements == null || elements.length == 0)
+ // return null;
+
+ return selectWord(viewer.getDocument(), offset);
+
+ // } catch (JavaModelException e) {
+ // return null;
+ // }
+ }
+
+ private int getCurrentTextOffset(ISourceViewer viewer) {
+
+ try {
+ StyledText text = viewer.getTextWidget();
+ if (text == null || text.isDisposed())
+ return -1;
+
+ Display display = text.getDisplay();
+ Point absolutePosition = display.getCursorLocation();
+ Point relativePosition = text.toControl(absolutePosition);
+
+ int widgetOffset = text.getOffsetAtLocation(relativePosition);
+ if (viewer instanceof ITextViewerExtension5) {
+ ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
+ return extension.widgetOffset2ModelOffset(widgetOffset);
+ } else {
+ return widgetOffset + viewer.getVisibleRegion().getOffset();
+ }
+
+ } catch (IllegalArgumentException e) {
+ return -1;
+ }
+ }
+
+ public void applyTextPresentation(TextPresentation textPresentation) {
+ if (fActiveRegion == null)
+ return;
+ IRegion region = textPresentation.getExtent();
+ if (fActiveRegion.getOffset() + fActiveRegion.getLength() >= region
+ .getOffset()
+ && region.getOffset() + region.getLength() > fActiveRegion
+ .getOffset())
+ textPresentation.mergeStyleRange(new StyleRange(fActiveRegion
+ .getOffset(), fActiveRegion.getLength(), fColor, null));
+ }
+
+ private void highlightRegion(ISourceViewer viewer, IRegion region) {
+
+ if (region.equals(fActiveRegion))
+ return;
+
+ repairRepresentation();
+
+ StyledText text = viewer.getTextWidget();
+ if (text == null || text.isDisposed())
+ return;
+
+ // Underline
+ int offset = 0;
+ int length = 0;
+ if (viewer instanceof ITextViewerExtension5) {
+ ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
+ IRegion widgetRange = extension.modelRange2WidgetRange(region);
+ if (widgetRange == null)
+ return;
+
+ offset = widgetRange.getOffset();
+ length = widgetRange.getLength();
+
+ } else {
+ offset = region.getOffset()
+ - viewer.getVisibleRegion().getOffset();
+ length = region.getLength();
+ }
+ text.redrawRange(offset, length, false);
+
+ // Invalidate region ==> apply text presentation
+ fActiveRegion = region;
+ if (viewer instanceof ITextViewerExtension2)
+ ((ITextViewerExtension2) viewer).invalidateTextPresentation(
+ region.getOffset(), region.getLength());
+ else
+ viewer.invalidateTextPresentation();
+ }
+
+ private void activateCursor(ISourceViewer viewer) {
+ StyledText text = viewer.getTextWidget();
+ if (text == null || text.isDisposed())
+ return;
+ Display display = text.getDisplay();
+ if (fCursor == null)
+ fCursor = new Cursor(display, SWT.CURSOR_HAND);
+ text.setCursor(fCursor);
+ }
+
+ private void resetCursor(ISourceViewer viewer) {
+ StyledText text = viewer.getTextWidget();
+ if (text != null && !text.isDisposed())
+ text.setCursor(null);
+
+ if (fCursor != null) {
+ fCursor.dispose();
+ fCursor = null;
+ }
+ }
+
+ /*
+ * @see org.eclipse.swt.events.KeyListener#keyPressed(org.eclipse.swt.events.KeyEvent)
+ */
+ public void keyPressed(KeyEvent event) {
+
+ if (fActive) {
+ deactivate();
+ return;
+ }
+
+ if (event.keyCode != fKeyModifierMask) {
+ deactivate();
+ return;
+ }
+
+ fActive = true;
+
+ // removed for #25871
+ //
+ // ISourceViewer viewer= getSourceViewer();
+ // if (viewer == null)
+ // return;
+ //
+ // IRegion region= getCurrentTextRegion(viewer);
+ // if (region == null)
+ // return;
+ //
+ // highlightRegion(viewer, region);
+ // activateCursor(viewer);
+ }
+
+ /*
+ * @see org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent)
+ */
+ public void keyReleased(KeyEvent event) {
+
+ if (!fActive)
+ return;
+
+ deactivate();
+ }
+
+ /*
+ * @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
+ */
+ public void mouseDoubleClick(MouseEvent e) {
+ }
+
+ /*
+ * @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent)
+ */
+ public void mouseDown(MouseEvent event) {
+
+ if (!fActive)
+ return;
+
+ if (event.stateMask != fKeyModifierMask) {
+ deactivate();
+ return;
+ }
+
+ if (event.button != 1) {
+ deactivate();
+ return;
+ }
+ }
+
+ /*
+ * @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent)
+ */
+ public void mouseUp(MouseEvent e) {
+
+ if (!fActive)
+ return;
+
+ if (e.button != 1) {
+ deactivate();
+ return;
+ }
+
+ boolean wasActive = fCursor != null;
+
+ deactivate();
+
+ if (wasActive) {
+ IAction action = getAction("OpenEditor"); //$NON-NLS-1$
+ if (action != null)
+ action.run();
+ }
+ }
+
+ /*
+ * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent)
+ */
+ public void mouseMove(MouseEvent event) {
+
+ if (event.widget instanceof Control
+ && !((Control) event.widget).isFocusControl()) {
+ deactivate();
+ return;
+ }
+
+ if (!fActive) {
+ if (event.stateMask != fKeyModifierMask)
+ return;
+ // modifier was already pressed
+ fActive = true;
+ }
+
+ ISourceViewer viewer = getSourceViewer();
+ if (viewer == null) {
+ deactivate();
+ return;
+ }
+
+ StyledText text = viewer.getTextWidget();
+ if (text == null || text.isDisposed()) {
+ deactivate();
+ return;
+ }
+
+ if ((event.stateMask & SWT.BUTTON1) != 0
+ && text.getSelectionCount() != 0) {
+ deactivate();
+ return;
+ }
+
+ IRegion region = getCurrentTextRegion(viewer);
+ if (region == null || region.getLength() == 0) {
+ repairRepresentation();
+ return;
+ }
+
+ highlightRegion(viewer, region);
+ activateCursor(viewer);
+ }
+
+ /*
+ * @see org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.swt.events.FocusEvent)
+ */
+ public void focusGained(FocusEvent e) {
+ }
+
+ /*
+ * @see org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt.events.FocusEvent)
+ */
+ public void focusLost(FocusEvent event) {
+ deactivate();
+ }
+
+ /*
+ * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
+ */
+ public void documentAboutToBeChanged(DocumentEvent event) {
+ if (fActive && fActiveRegion != null) {
+ fRememberedPosition = new Position(fActiveRegion.getOffset(),
+ fActiveRegion.getLength());
+ try {
+ event.getDocument().addPosition(fRememberedPosition);
+ } catch (BadLocationException x) {
+ fRememberedPosition = null;
+ }
+ }
+ }
+
+ /*
+ * @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent)
+ */
+ public void documentChanged(DocumentEvent event) {
+ if (fRememberedPosition != null) {
+ if (!fRememberedPosition.isDeleted()) {
+
+ event.getDocument().removePosition(fRememberedPosition);
+ fActiveRegion = new Region(fRememberedPosition.getOffset(),
+ fRememberedPosition.getLength());
+ fRememberedPosition = null;
+
+ ISourceViewer viewer = getSourceViewer();
+ if (viewer != null) {
+ StyledText widget = viewer.getTextWidget();
+ if (widget != null && !widget.isDisposed()) {
+ widget.getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ deactivate();
+ }
+ });
+ }
+ }
+
+ } else {
+ fActiveRegion = null;
+ fRememberedPosition = null;
+ deactivate();
+ }
+ }
+ }
+
+ /*
+ * @see org.eclipse.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(org.eclipse.jface.text.IDocument,
+ * org.eclipse.jface.text.IDocument)
+ */
+ public void inputDocumentAboutToBeChanged(IDocument oldInput,
+ IDocument newInput) {
+ if (oldInput == null)
+ return;
+ deactivate();
+ oldInput.removeDocumentListener(this);
+ }
+
+ /*
+ * @see org.eclipse.jface.text.ITextInputListener#inputDocumentChanged(org.eclipse.jface.text.IDocument,
+ * org.eclipse.jface.text.IDocument)
+ */
+ public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
+ if (newInput == null)
+ return;
+ newInput.addDocumentListener(this);
+ }
+
+ /*
+ * @see PaintListener#paintControl(PaintEvent)
+ */
+ public void paintControl(PaintEvent event) {
+ if (fActiveRegion == null)
+ return;
+
+ ISourceViewer viewer = getSourceViewer();
+ if (viewer == null)
+ return;
+
+ StyledText text = viewer.getTextWidget();
+ if (text == null || text.isDisposed())
+ return;
+
+ int offset = 0;
+ int length = 0;
+
+ if (viewer instanceof ITextViewerExtension5) {
+
+ ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
+ IRegion widgetRange = extension
+ .modelRange2WidgetRange(fActiveRegion);
+ if (widgetRange == null)
+ return;
+
+ offset = widgetRange.getOffset();
+ length = widgetRange.getLength();
+
+ } else {
+
+ IRegion region = viewer.getVisibleRegion();
+ if (!includes(region, fActiveRegion))
+ return;
+
+ offset = fActiveRegion.getOffset() - region.getOffset();
+ length = fActiveRegion.getLength();
+ }
+
+ // support for bidi
+ Point minLocation = getMinimumLocation(text, offset, length);
+ Point maxLocation = getMaximumLocation(text, offset, length);
+
+ int x1 = minLocation.x;
+ int x2 = minLocation.x + maxLocation.x - minLocation.x - 1;
+ int y = minLocation.y + text.getLineHeight() - 1;
+
+ GC gc = event.gc;
+ if (fColor != null && !fColor.isDisposed())
+ gc.setForeground(fColor);
+ gc.drawLine(x1, y, x2, y);
+ }
+
+ private boolean includes(IRegion region, IRegion position) {
+ return position.getOffset() >= region.getOffset()
+ && position.getOffset() + position.getLength() <= region
+ .getOffset()
+ + region.getLength();
+ }
+
+ private Point getMinimumLocation(StyledText text, int offset, int length) {
+ Point minLocation = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE);
+
+ for (int i = 0; i <= length; i++) {
+ Point location = text.getLocationAtOffset(offset + i);
+
+ if (location.x < minLocation.x)
+ minLocation.x = location.x;
+ if (location.y < minLocation.y)
+ minLocation.y = location.y;
+ }
+
+ return minLocation;
+ }
+
+ private Point getMaximumLocation(StyledText text, int offset, int length) {
+ Point maxLocation = new Point(Integer.MIN_VALUE, Integer.MIN_VALUE);
+
+ for (int i = 0; i <= length; i++) {
+ Point location = text.getLocationAtOffset(offset + i);
+
+ if (location.x > maxLocation.x)
+ maxLocation.x = location.x;
+ if (location.y > maxLocation.y)
+ maxLocation.y = location.y;
+ }
+
+ return maxLocation;
+ }
+ }
+
+ /**
+ * This action dispatches into two behaviours: If there is no current text
+ * hover, the javadoc is displayed using information presenter. If there is
+ * a current text hover, it is converted into a information presenter in
+ * order to make it sticky.
+ */
+ class InformationDispatchAction extends TextEditorAction {
+
+ /** The wrapped text operation action. */
+ private final TextOperationAction fTextOperationAction;
+
+ /**
+ * Creates a dispatch action.
+ */
+ public InformationDispatchAction(ResourceBundle resourceBundle,
+ String prefix, final TextOperationAction textOperationAction) {
+ super(resourceBundle, prefix, PHPEditor.this);
+ if (textOperationAction == null)
+ throw new IllegalArgumentException();
+ fTextOperationAction = textOperationAction;
+ }
+
+ /*
+ * @see org.eclipse.jface.action.IAction#run()
+ */
+ public void run() {
+
+ ISourceViewer sourceViewer = getSourceViewer();
+ if (sourceViewer == null) {
+ fTextOperationAction.run();
+ return;
+ }
+
+ if (!(sourceViewer instanceof ITextViewerExtension2)) {
+ fTextOperationAction.run();
+ return;
+ }
+
+ ITextViewerExtension2 textViewerExtension2 = (ITextViewerExtension2) sourceViewer;
+
+ // does a text hover exist?
+ ITextHover textHover = textViewerExtension2.getCurrentTextHover();
+ if (textHover == null) {
+ fTextOperationAction.run();
+ return;
+ }
+
+ Point hoverEventLocation = textViewerExtension2
+ .getHoverEventLocation();
+ int offset = computeOffsetAtLocation(sourceViewer,
+ hoverEventLocation.x, hoverEventLocation.y);
+ if (offset == -1) {
+ fTextOperationAction.run();
+ return;
+ }
+
+ try {
+ // get the text hover content
+ IDocument document = sourceViewer.getDocument();
+ String contentType = document.getContentType(offset);
+
+ final IRegion hoverRegion = textHover.getHoverRegion(
+ sourceViewer, offset);
+ if (hoverRegion == null)
+ return;
+
+ final String hoverInfo = textHover.getHoverInfo(sourceViewer,
+ hoverRegion);
+
+ // with information provider
+ IInformationProvider informationProvider = new IInformationProvider() {
+ /*
+ * @see org.eclipse.jface.text.information.IInformationProvider#getSubject(org.eclipse.jface.text.ITextViewer,
+ * int)
+ */
+ public IRegion getSubject(ITextViewer textViewer, int offset) {
+ return hoverRegion;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.information.IInformationProvider#getInformation(org.eclipse.jface.text.ITextViewer,
+ * org.eclipse.jface.text.IRegion)
+ */
+ public String getInformation(ITextViewer textViewer,
+ IRegion subject) {
+ return hoverInfo;
+ }
+ };
+
+ fInformationPresenter.setOffset(offset);
+ fInformationPresenter.setInformationProvider(
+ informationProvider, contentType);
+ fInformationPresenter.showInformation();
+
+ } catch (BadLocationException e) {
+ }
+ }
+
+ // modified version from TextViewer
+ private int computeOffsetAtLocation(ITextViewer textViewer, int x, int y) {
+
+ StyledText styledText = textViewer.getTextWidget();
+ IDocument document = textViewer.getDocument();
+
+ if (document == null)
+ return -1;
+
+ try {
+ int widgetLocation = styledText.getOffsetAtLocation(new Point(
+ x, y));
+ if (textViewer instanceof ITextViewerExtension5) {
+ ITextViewerExtension5 extension = (ITextViewerExtension5) textViewer;
+ return extension.widgetOffset2ModelOffset(widgetLocation);
+ } else {
+ IRegion visibleRegion = textViewer.getVisibleRegion();
+ return widgetLocation + visibleRegion.getOffset();
+ }
+ } catch (IllegalArgumentException e) {
+ return -1;
+ }
+
+ }
+ };
+
+ /**
+ * This action implements smart home.
+ *
+ * Instead of going to the start of a line it does the following: - if smart
+ * home/end is enabled and the caret is after the line's first
+ * non-whitespace then the caret is moved directly before it, taking JavaDoc
+ * and multi-line comments into account. - if the caret is before the line's
+ * first non-whitespace the caret is moved to the beginning of the line - if
+ * the caret is at the beginning of the line see first case.
+ *
+ * @since 3.0
+ */
+ protected class SmartLineStartAction extends LineStartAction {
+
+ /**
+ * Creates a new smart line start action
+ *
+ * @param textWidget
+ * the styled text widget
+ * @param doSelect
+ * a boolean flag which tells if the text up to the beginning
+ * of the line should be selected
+ */
+ public SmartLineStartAction(final StyledText textWidget,
+ final boolean doSelect) {
+ super(textWidget, doSelect);
+ }
+
+ /*
+ * @see org.eclipse.ui.texteditor.AbstractTextEditor.LineStartAction#getLineStartPosition(java.lang.String,
+ * int, java.lang.String)
+ */
+ protected int getLineStartPosition(final IDocument document,
+ final String line, final int length, final int offset) {
+
+ String type = IDocument.DEFAULT_CONTENT_TYPE;
+ try {
+ type = TextUtilities.getContentType(document,
+ IPHPPartitions.PHP_PARTITIONING, offset, true);
+ } catch (BadLocationException exception) {
+ // Should not happen
+ }
+
+ int index = super.getLineStartPosition(document, line, length,
+ offset);
+ if (type.equals(IPHPPartitions.PHP_PHPDOC_COMMENT)
+ || type.equals(IPHPPartitions.PHP_MULTILINE_COMMENT)) {
+ if (index < length - 1 && line.charAt(index) == '*'
+ && line.charAt(index + 1) != '/') {
+ do {
+ ++index;
+ } while (index < length
+ && Character.isWhitespace(line.charAt(index)));
+ }
+ } else {
+ if (index < length - 1 && line.charAt(index) == '/'
+ && line.charAt(index + 1) == '/') {
+ index++;
+ do {
+ ++index;
+ } while (index < length
+ && Character.isWhitespace(line.charAt(index)));
+ }
+ }
+ return index;
+ }
+ }
+
+ /**
+ * Text navigation action to navigate to the next sub-word.
+ *
+ * @since 3.0
+ */
+ protected abstract class NextSubWordAction extends TextNavigationAction {
+
+ protected JavaWordIterator fIterator = new JavaWordIterator();
+
+ /**
+ * Creates a new next sub-word action.
+ *
+ * @param code
+ * Action code for the default operation. Must be an action
+ * code from
+ * @see org.eclipse.swt.custom.ST.
+ */
+ protected NextSubWordAction(int code) {
+ super(getSourceViewer().getTextWidget(), code);
+ }
+
+ /*
+ * @see org.eclipse.jface.action.IAction#run()
+ */
+ public void run() {
+ // Check whether we are in a java code partition and the preference
+ // is
+ // enabled
+ final IPreferenceStore store = getPreferenceStore();
+ if (!store
+ .getBoolean(PreferenceConstants.EDITOR_SUB_WORD_NAVIGATION)) {
+ super.run();
+ return;
+ }
+
+ final ISourceViewer viewer = getSourceViewer();
+ final IDocument document = viewer.getDocument();
+ fIterator
+ .setText((CharacterIterator) new DocumentCharacterIterator(
+ document));
+ int position = widgetOffset2ModelOffset(viewer, viewer
+ .getTextWidget().getCaretOffset());
+ if (position == -1)
+ return;
+
+ int next = findNextPosition(position);
+ if (next != BreakIterator.DONE) {
+ setCaretPosition(next);
+ getTextWidget().showSelection();
+ fireSelectionChanged();
+ }
+
+ }
+
+ /**
+ * Finds the next position after the given position.
+ *
+ * @param position
+ * the current position
+ * @return the next position
+ */
+ protected int findNextPosition(int position) {
+ ISourceViewer viewer = getSourceViewer();
+ int widget = -1;
+ while (position != BreakIterator.DONE && widget == -1) { // TODO:
+ // optimize
+ position = fIterator.following(position);
+ if (position != BreakIterator.DONE)
+ widget = modelOffset2WidgetOffset(viewer, position);
+ }
+ return position;
+ }
+
+ /**
+ * Sets the caret position to the sub-word boundary given with
+ * <code>position</code>.
+ *
+ * @param position
+ * Position where the action should move the caret
+ */
+ protected abstract void setCaretPosition(int position);
+ }
+
+ /**
+ * Text navigation action to navigate to the next sub-word.
+ *
+ * @since 3.0
+ */
+ protected class NavigateNextSubWordAction extends NextSubWordAction {
+
+ /**
+ * Creates a new navigate next sub-word action.
+ */
+ public NavigateNextSubWordAction() {
+ super(ST.WORD_NEXT);
+ }
+
+ /*
+ * @see net.sourceforge.phpdt.internal.ui.javaeditor.JavaEditor.NextSubWordAction#setCaretPosition(int)
+ */
+ protected void setCaretPosition(final int position) {
+ getTextWidget().setCaretOffset(
+ modelOffset2WidgetOffset(getSourceViewer(), position));
+ }
+ }
+
+ /**
+ * Text operation action to delete the next sub-word.
+ *
+ * @since 3.0
+ */
+ protected class DeleteNextSubWordAction extends NextSubWordAction implements
+ IUpdate {
+
+ /**
+ * Creates a new delete next sub-word action.
+ */
+ public DeleteNextSubWordAction() {
+ super(ST.DELETE_WORD_NEXT);
+ }
+
+ /*
+ * @see net.sourceforge.phpdt.internal.ui.javaeditor.JavaEditor.NextSubWordAction#setCaretPosition(int)
+ */
+ protected void setCaretPosition(final int position) {
+ if (!validateEditorInputState())
+ return;
+
+ final ISourceViewer viewer = getSourceViewer();
+ final int caret = widgetOffset2ModelOffset(viewer, viewer
+ .getTextWidget().getCaretOffset());
+
+ try {
+ viewer.getDocument().replace(caret, position - caret, ""); //$NON-NLS-1$
+ } catch (BadLocationException exception) {
+ // Should not happen
+ }
+ }
+
+ /*
+ * @see net.sourceforge.phpdt.internal.ui.javaeditor.JavaEditor.NextSubWordAction#findNextPosition(int)
+ */
+ protected int findNextPosition(int position) {
+ return fIterator.following(position);
+ }
+
+ /*
+ * @see org.eclipse.ui.texteditor.IUpdate#update()
+ */
+ public void update() {
+ setEnabled(isEditorInputModifiable());
+ }
+ }
+
+ /**
+ * Text operation action to select the next sub-word.
+ *
+ * @since 3.0
+ */
+ protected class SelectNextSubWordAction extends NextSubWordAction {
+
+ /**
+ * Creates a new select next sub-word action.
+ */
+ public SelectNextSubWordAction() {
+ super(ST.SELECT_WORD_NEXT);
+ }
+
+ /*
+ * @see net.sourceforge.phpdt.internal.ui.javaeditor.JavaEditor.NextSubWordAction#setCaretPosition(int)
+ */
+ protected void setCaretPosition(final int position) {
+ final ISourceViewer viewer = getSourceViewer();
+
+ final StyledText text = viewer.getTextWidget();
+ if (text != null && !text.isDisposed()) {
+
+ final Point selection = text.getSelection();
+ final int caret = text.getCaretOffset();
+ final int offset = modelOffset2WidgetOffset(viewer, position);
+
+ if (caret == selection.x)
+ text.setSelectionRange(selection.y, offset - selection.y);
+ else
+ text.setSelectionRange(selection.x, offset - selection.x);
+ }
+ }
+ }
+
+ /**
+ * Text navigation action to navigate to the previous sub-word.
+ *
+ * @since 3.0
+ */
+ protected abstract class PreviousSubWordAction extends TextNavigationAction {
+
+ protected JavaWordIterator fIterator = new JavaWordIterator();
+
+ /**
+ * Creates a new previous sub-word action.
+ *
+ * @param code
+ * Action code for the default operation. Must be an action
+ * code from
+ * @see org.eclipse.swt.custom.ST.
+ */
+ protected PreviousSubWordAction(final int code) {
+ super(getSourceViewer().getTextWidget(), code);
+ }
+
+ /*
+ * @see org.eclipse.jface.action.IAction#run()
+ */
+ public void run() {
+ // Check whether we are in a java code partition and the preference
+ // is
+ // enabled
+ final IPreferenceStore store = getPreferenceStore();
+ if (!store
+ .getBoolean(PreferenceConstants.EDITOR_SUB_WORD_NAVIGATION)) {
+ super.run();
+ return;
+ }
+
+ final ISourceViewer viewer = getSourceViewer();
+ final IDocument document = viewer.getDocument();
+ fIterator
+ .setText((CharacterIterator) new DocumentCharacterIterator(
+ document));
+ int position = widgetOffset2ModelOffset(viewer, viewer
+ .getTextWidget().getCaretOffset());
+ if (position == -1)
+ return;
+
+ int previous = findPreviousPosition(position);
+ if (previous != BreakIterator.DONE) {
+ setCaretPosition(previous);
+ getTextWidget().showSelection();
+ fireSelectionChanged();
+ }
+
+ }
+
+ /**
+ * Finds the previous position before the given position.
+ *
+ * @param position
+ * the current position
+ * @return the previous position
+ */
+ protected int findPreviousPosition(int position) {
+ ISourceViewer viewer = getSourceViewer();
+ int widget = -1;
+ while (position != BreakIterator.DONE && widget == -1) { // TODO:
+ // optimize
+ position = fIterator.preceding(position);
+ if (position != BreakIterator.DONE)
+ widget = modelOffset2WidgetOffset(viewer, position);
+ }
+ return position;
+ }
+
+ /**
+ * Sets the caret position to the sub-word boundary given with
+ * <code>position</code>.
+ *
+ * @param position
+ * Position where the action should move the caret
+ */
+ protected abstract void setCaretPosition(int position);
+ }
+
+ /**
+ * Text navigation action to navigate to the previous sub-word.
+ *
+ * @since 3.0
+ */
+ protected class NavigatePreviousSubWordAction extends PreviousSubWordAction {
+
+ /**
+ * Creates a new navigate previous sub-word action.
+ */
+ public NavigatePreviousSubWordAction() {
+ super(ST.WORD_PREVIOUS);
+ }
+
+ /*
+ * @see net.sourceforge.phpdt.internal.ui.javaeditor.JavaEditor.PreviousSubWordAction#setCaretPosition(int)
+ */
+ protected void setCaretPosition(final int position) {
+ getTextWidget().setCaretOffset(
+ modelOffset2WidgetOffset(getSourceViewer(), position));
+ }
+ }
+
+ /**
+ * Text operation action to delete the previous sub-word.
+ *
+ * @since 3.0
+ */
+ protected class DeletePreviousSubWordAction extends PreviousSubWordAction
+ implements IUpdate {
+
+ /**
+ * Creates a new delete previous sub-word action.
+ */
+ public DeletePreviousSubWordAction() {
+ super(ST.DELETE_WORD_PREVIOUS);
+ }
+
+ /*
+ * @see net.sourceforge.phpdt.internal.ui.javaeditor.JavaEditor.PreviousSubWordAction#setCaretPosition(int)
+ */
+ protected void setCaretPosition(final int position) {
+ if (!validateEditorInputState())
+ return;
+
+ final ISourceViewer viewer = getSourceViewer();
+ final int caret = widgetOffset2ModelOffset(viewer, viewer
+ .getTextWidget().getCaretOffset());
+
+ try {
+ viewer.getDocument().replace(position, caret - position, ""); //$NON-NLS-1$
+ } catch (BadLocationException exception) {
+ // Should not happen
+ }
+ }
+
+ /*
+ * @see net.sourceforge.phpdt.internal.ui.javaeditor.JavaEditor.PreviousSubWordAction#findPreviousPosition(int)
+ */
+ protected int findPreviousPosition(int position) {
+ return fIterator.preceding(position);
+ }
+
+ /*
+ * @see org.eclipse.ui.texteditor.IUpdate#update()
+ */
+ public void update() {
+ setEnabled(isEditorInputModifiable());
+ }
+ }
+
+ /**
+ * Text operation action to select the previous sub-word.
+ *
+ * @since 3.0
+ */
+ protected class SelectPreviousSubWordAction extends PreviousSubWordAction {
+
+ /**
+ * Creates a new select previous sub-word action.
+ */
+ public SelectPreviousSubWordAction() {
+ super(ST.SELECT_WORD_PREVIOUS);
+ }
+
+ /*
+ * @see net.sourceforge.phpdt.internal.ui.javaeditor.JavaEditor.PreviousSubWordAction#setCaretPosition(int)
+ */
+ protected void setCaretPosition(final int position) {
+ final ISourceViewer viewer = getSourceViewer();
+
+ final StyledText text = viewer.getTextWidget();
+ if (text != null && !text.isDisposed()) {
+
+ final Point selection = text.getSelection();
+ final int caret = text.getCaretOffset();
+ final int offset = modelOffset2WidgetOffset(viewer, position);
+
+ if (caret == selection.x)
+ text.setSelectionRange(selection.y, offset - selection.y);
+ else
+ text.setSelectionRange(selection.x, offset - selection.x);
+ }
+ }
+ }
+
+ // static protected class AnnotationAccess implements IAnnotationAccess {
+ // /*
+ // * @see
+ // org.eclipse.jface.text.source.IAnnotationAccess#getType(org.eclipse.jface.text.source.Annotation)
+ // */
+ // public Object getType(Annotation annotation) {
+ // if (annotation instanceof IJavaAnnotation) {
+ // IJavaAnnotation javaAnnotation = (IJavaAnnotation) annotation;
+ // // if (javaAnnotation.isRelevant())
+ // // return javaAnnotation.getAnnotationType();
+ // }
+ // return null;
+ // }
+ //
+ // /*
+ // * @see
+ // org.eclipse.jface.text.source.IAnnotationAccess#isMultiLine(org.eclipse.jface.text.source.Annotation)
+ // */
+ // public boolean isMultiLine(Annotation annotation) {
+ // return true;
+ // }
+ //
+ // /*
+ // * @see
+ // org.eclipse.jface.text.source.IAnnotationAccess#isTemporary(org.eclipse.jface.text.source.Annotation)
+ // */
+ // public boolean isTemporary(Annotation annotation) {
+ // if (annotation instanceof IJavaAnnotation) {
+ // IJavaAnnotation javaAnnotation = (IJavaAnnotation) annotation;
+ // if (javaAnnotation.isRelevant())
+ // return javaAnnotation.isTemporary();
+ // }
+ // return false;
+ // }
+ // };
+
+ private class PropertyChangeListener implements
+ org.eclipse.core.runtime.Preferences.IPropertyChangeListener {
+ /*
+ * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
+ */
+ public void propertyChange(
+ org.eclipse.core.runtime.Preferences.PropertyChangeEvent event) {
+ handlePreferencePropertyChanged(event);
+ }
+ };
+
+ /**
+ * Finds and marks occurrence annotations.
+ *
+ * @since 3.0
+ */
+ class OccurrencesFinderJob extends Job {
+
+ private IDocument fDocument;
+
+ private ISelection fSelection;
+
+ private ISelectionValidator fPostSelectionValidator;
+
+ private boolean fCanceled = false;
+
+ private IProgressMonitor fProgressMonitor;
+
+ private Position[] fPositions;
+
+ public OccurrencesFinderJob(IDocument document, Position[] positions,
+ ISelection selection) {
+ super(PHPEditorMessages.JavaEditor_markOccurrences_job_name);
+ fDocument = document;
+ fSelection = selection;
+ fPositions = positions;
+
+ if (getSelectionProvider() instanceof ISelectionValidator)
+ fPostSelectionValidator = (ISelectionValidator) getSelectionProvider();
+ }
+
+ // cannot use cancel() because it is declared final
+ void doCancel() {
+ fCanceled = true;
+ cancel();
+ }
+
+ private boolean isCanceled() {
+ return fCanceled
+ || fProgressMonitor.isCanceled()
+ || fPostSelectionValidator != null
+ && !(fPostSelectionValidator.isValid(fSelection) || fForcedMarkOccurrencesSelection == fSelection)
+ || LinkedModeModel.hasInstalledModel(fDocument);
+ }
+
+ /*
+ * @see Job#run(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ public IStatus run(IProgressMonitor progressMonitor) {
+
+ fProgressMonitor = progressMonitor;
+
+ if (isCanceled())
+ return Status.CANCEL_STATUS;
+
+ ITextViewer textViewer = getViewer();
+ if (textViewer == null)
+ return Status.CANCEL_STATUS;
+
+ IDocument document = textViewer.getDocument();
+ if (document == null)
+ return Status.CANCEL_STATUS;
+
+ IDocumentProvider documentProvider = getDocumentProvider();
+ if (documentProvider == null)
+ return Status.CANCEL_STATUS;
+
+ IAnnotationModel annotationModel = documentProvider
+ .getAnnotationModel(getEditorInput());
+ if (annotationModel == null)
+ return Status.CANCEL_STATUS;
+
+ // Add occurrence annotations
+ int length = fPositions.length;
+ Map annotationMap = new HashMap(length);
+ for (int i = 0; i < length; i++) {
+
+ if (isCanceled())
+ return Status.CANCEL_STATUS;
+
+ String message;
+ Position position = fPositions[i];
+
+ // Create & add annotation
+ try {
+ message = document.get(position.offset, position.length);
+ } catch (BadLocationException ex) {
+ // Skip this match
+ continue;
+ }
+ annotationMap
+ .put(
+ new Annotation(
+ "net.sourceforge.phpdt.ui.occurrences", false, message), //$NON-NLS-1$
+ position);
+ }
+
+ if (isCanceled())
+ return Status.CANCEL_STATUS;
+
+ synchronized (getLockObject(annotationModel)) {
+ if (annotationModel instanceof IAnnotationModelExtension) {
+ ((IAnnotationModelExtension) annotationModel)
+ .replaceAnnotations(fOccurrenceAnnotations,
+ annotationMap);
+ } else {
+ removeOccurrenceAnnotations();
+ Iterator iter = annotationMap.entrySet().iterator();
+ while (iter.hasNext()) {
+ Map.Entry mapEntry = (Map.Entry) iter.next();
+ annotationModel.addAnnotation((Annotation) mapEntry
+ .getKey(), (Position) mapEntry.getValue());
+ }
+ }
+ fOccurrenceAnnotations = (Annotation[]) annotationMap.keySet()
+ .toArray(new Annotation[annotationMap.keySet().size()]);
+ }
+
+ return Status.OK_STATUS;
+ }
+ }
+
+ /**
+ * Cancels the occurrences finder job upon document changes.
+ *
+ * @since 3.0
+ */
+ class OccurrencesFinderJobCanceler implements IDocumentListener,
+ ITextInputListener {
+
+ public void install() {
+ ISourceViewer sourceViewer = getSourceViewer();
+ if (sourceViewer == null)
+ return;
+
+ StyledText text = sourceViewer.getTextWidget();
+ if (text == null || text.isDisposed())
+ return;
+
+ sourceViewer.addTextInputListener(this);
+
+ IDocument document = sourceViewer.getDocument();
+ if (document != null)
+ document.addDocumentListener(this);
+ }
+
+ public void uninstall() {
+ ISourceViewer sourceViewer = getSourceViewer();
+ if (sourceViewer != null)
+ sourceViewer.removeTextInputListener(this);
+
+ IDocumentProvider documentProvider = getDocumentProvider();
+ if (documentProvider != null) {
+ IDocument document = documentProvider
+ .getDocument(getEditorInput());
+ if (document != null)
+ document.removeDocumentListener(this);
+ }
+ }
+
+ /*
+ * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
+ */
+ public void documentAboutToBeChanged(DocumentEvent event) {
+ if (fOccurrencesFinderJob != null)
+ fOccurrencesFinderJob.doCancel();
+ }
+
+ /*
+ * @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent)
+ */
+ public void documentChanged(DocumentEvent event) {
+ }
+
+ /*
+ * @see org.eclipse.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(org.eclipse.jface.text.IDocument,
+ * org.eclipse.jface.text.IDocument)
+ */
+ public void inputDocumentAboutToBeChanged(IDocument oldInput,
+ IDocument newInput) {
+ if (oldInput == null)
+ return;
+
+ oldInput.removeDocumentListener(this);
+ }
+
+ /*
+ * @see org.eclipse.jface.text.ITextInputListener#inputDocumentChanged(org.eclipse.jface.text.IDocument,
+ * org.eclipse.jface.text.IDocument)
+ */
+ public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
+ if (newInput == null)
+ return;
+ newInput.addDocumentListener(this);
+ }
+ }
+
+ /**
+ * Internal activation listener.
+ *
+ * @since 3.0
+ */
+ private class ActivationListener implements IWindowListener {
+
+ /*
+ * @see org.eclipse.ui.IWindowListener#windowActivated(org.eclipse.ui.IWorkbenchWindow)
+ * @since 3.1
+ */
+ public void windowActivated(IWorkbenchWindow window) {
+ if (window == getEditorSite().getWorkbenchWindow()
+ && fMarkOccurrenceAnnotations && isActivePart()) {
+ fForcedMarkOccurrencesSelection = getSelectionProvider()
+ .getSelection();
+ SelectionListenerWithASTManager
+ .getDefault()
+ .forceSelectionChange(
+ PHPEditor.this,
+ (ITextSelection) fForcedMarkOccurrencesSelection);
+ }
+ }
+
+ /*
+ * @see org.eclipse.ui.IWindowListener#windowDeactivated(org.eclipse.ui.IWorkbenchWindow)
+ * @since 3.1
+ */
+ public void windowDeactivated(IWorkbenchWindow window) {
+ if (window == getEditorSite().getWorkbenchWindow()
+ && fMarkOccurrenceAnnotations && isActivePart())
+ removeOccurrenceAnnotations();
+ }
+
+ /*
+ * @see org.eclipse.ui.IWindowListener#windowClosed(org.eclipse.ui.IWorkbenchWindow)
+ * @since 3.1
+ */
+ public void windowClosed(IWorkbenchWindow window) {
+ }
+
+ /*
+ * @see org.eclipse.ui.IWindowListener#windowOpened(org.eclipse.ui.IWorkbenchWindow)
+ * @since 3.1
+ */
+ public void windowOpened(IWorkbenchWindow window) {
+ }
+ }
+
+ /**
+ * Updates the selection in the editor's widget with the selection of the
+ * outline page.
+ */
+ class OutlineSelectionChangedListener extends
+ AbstractSelectionChangedListener {
+ public void selectionChanged(SelectionChangedEvent event) {
+ doSelectionChanged(event);
+ }
+ }
+
+ /**
+ * The internal shell activation listener for updating occurrences.
+ *
+ * @since 3.0
+ */
+ private ActivationListener fActivationListener = new ActivationListener();
+
+ private ISelectionListenerWithAST fPostSelectionListenerWithAST;
+
+ private OccurrencesFinderJob fOccurrencesFinderJob;
+
+ /** The occurrences finder job canceler */
+ private OccurrencesFinderJobCanceler fOccurrencesFinderJobCanceler;
+
+ /**
+ * Holds the current occurrence annotations.
+ *
+ * @since 3.0
+ */
+ private Annotation[] fOccurrenceAnnotations = null;
+
+ /**
+ * Tells whether all occurrences of the element at the current caret
+ * location are automatically marked in this editor.
+ *
+ * @since 3.0
+ */
+ private boolean fMarkOccurrenceAnnotations;
+
+ /**
+ * The selection used when forcing occurrence marking through code.
+ *
+ * @since 3.0
+ */
+ private ISelection fForcedMarkOccurrencesSelection;
+
+ /**
+ * The document modification stamp at the time when the last occurrence
+ * marking took place.
+ *
+ * @since 3.1
+ */
+ private long fMarkOccurrenceModificationStamp = IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP;
+
+ /**
+ * The region of the word under the caret used to when computing the current
+ * occurrence markings.
+ *
+ * @since 3.1
+ */
+ private IRegion fMarkOccurrenceTargetRegion;
+
+ /**
+ * Tells whether the occurrence annotations are sticky i.e. whether they
+ * stay even if there's no valid Java element at the current caret position.
+ * Only valid if {@link #fMarkOccurrenceAnnotations} is <code>true</code>.
+ *
+ * @since 3.0
+ */
+ private boolean fStickyOccurrenceAnnotations;
+
+ /** Preference key for showing the line number ruler */
+ // private final static String LINE_NUMBER_RULER =
+ // PreferenceConstants.EDITOR_LINE_NUMBER_RULER;
+ /** Preference key for the foreground color of the line numbers */
+ // private final static String LINE_NUMBER_COLOR =
+ // PreferenceConstants.EDITOR_LINE_NUMBER_RULER_COLOR;
+ /** Preference key for the link color */
+ private final static String LINK_COLOR = PreferenceConstants.EDITOR_LINK_COLOR;
+
+ /** Preference key for compiler task tags */
+ private final static String COMPILER_TASK_TAGS = JavaCore.COMPILER_TASK_TAGS;
+
+ // protected PHPActionGroup fActionGroups;
+ // /** The outline page */
+ // private AbstractContentOutlinePage fOutlinePage;
+ /** The outline page */
+ protected JavaOutlinePage fOutlinePage;
+
+ /** Outliner context menu Id */
+ protected String fOutlinerContextMenuId;
+
+ /**
+ * Indicates whether this editor should react on outline page selection
+ * changes
+ */
+ private int fIgnoreOutlinePageSelection;
+
+ /** The outline page selection updater */
+ // private OutlinePageSelectionUpdater fUpdater;
+ // protected PHPSyntaxParserThread fValidationThread = null;
+ // private IPreferenceStore fPHPPrefStore;
+ /** The selection changed listener */
+ // protected ISelectionChangedListener fSelectionChangedListener = new
+ // SelectionChangedListener();
+ /**
+ * The editor selection changed listener.
+ *
+ * @since 3.0
+ */
+ private EditorSelectionChangedListener fEditorSelectionChangedListener;
+
+ /** The selection changed listener */
+ protected AbstractSelectionChangedListener fOutlineSelectionChangedListener = new OutlineSelectionChangedListener();
+
+ /** The editor's bracket matcher */
+ private PHPPairMatcher fBracketMatcher = new PHPPairMatcher(BRACKETS);
+
+ /** The line number ruler column */
+ // private LineNumberRulerColumn fLineNumberRulerColumn;
+ /** This editor's encoding support */
+ private DefaultEncodingSupport fEncodingSupport;
+
+ /** The mouse listener */
+ private MouseClickListener fMouseListener;
+
+ /**
+ * Indicates whether this editor is about to update any annotation views.
+ *
+ * @since 3.0
+ */
+ private boolean fIsUpdatingAnnotationViews = false;
+
+ /**
+ * The marker that served as last target for a goto marker request.
+ *
+ * @since 3.0
+ */
+ private IMarker fLastMarkerTarget = null;
+
+ protected CompositeActionGroup fActionGroups;
+
+ protected CompositeActionGroup fContextMenuGroup;
+
+ /**
+ * This editor's projection support
+ *
+ * @since 3.0
+ */
+ private ProjectionSupport fProjectionSupport;
+
+ /**
+ * This editor's projection model updater
+ *
+ * @since 3.0
+ */
+ private IJavaFoldingStructureProvider fProjectionModelUpdater;
+
+ /**
+ * The override and implements indicator manager for this editor.
+ *
+ * @since 3.0
+ */
+ // protected OverrideIndicatorManager fOverrideIndicatorManager;
+ /**
+ * The action group for folding.
+ *
+ * @since 3.0
+ */
+ private FoldingActionGroup fFoldingGroup;
+
+ /** The information presenter. */
+ private InformationPresenter fInformationPresenter;
+
+ /** The annotation access */
+ // protected IAnnotationAccess fAnnotationAccess = new AnnotationAccess();
+ /** The overview ruler */
+ protected OverviewRuler isOverviewRulerVisible;
+
+ /** The source viewer decoration support */
+ // protected SourceViewerDecorationSupport fSourceViewerDecorationSupport;
+ /** The overview ruler */
+ // protected OverviewRuler fOverviewRuler;
+ /** The preference property change listener for java core. */
+ private org.eclipse.core.runtime.Preferences.IPropertyChangeListener fPropertyChangeListener = new PropertyChangeListener();
+
+ /**
+ * Returns the most narrow java element including the given offset
+ *
+ * @param offset
+ * the offset inside of the requested element
+ */
+ abstract protected IJavaElement getElementAt(int offset);
+
+ /**
+ * Returns the java element of this editor's input corresponding to the
+ * given IJavaElement
+ */
+ abstract protected IJavaElement getCorrespondingElement(IJavaElement element);
+
+ /**
+ * Sets the input of the editor's outline page.
+ */
+ abstract protected void setOutlinePageInput(JavaOutlinePage page,
+ IEditorInput input);
+
+ /**
+ * Default constructor.
+ */
+ public PHPEditor() {
+ super();
+ }
+
+ /*
+ * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#initializeKeyBindingScopes()
+ */
+ protected void initializeKeyBindingScopes() {
+ setKeyBindingScopes(new String[] { "net.sourceforge.phpdt.ui.phpEditorScope" }); //$NON-NLS-1$
+ }
+
+ /*
+ * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#initializeEditor()
+ */
+ protected void initializeEditor() {
+ // jsurfer old code
+ // JavaTextTools textTools =
+ // PHPeclipsePlugin.getDefault().getJavaTextTools();
+ // setSourceViewerConfiguration(new
+ // PHPSourceViewerConfiguration(textTools,
+ // this, IPHPPartitions.PHP_PARTITIONING)); //,
+ // IJavaPartitions.JAVA_PARTITIONING));
+ IPreferenceStore store = createCombinedPreferenceStore(null);
+ setPreferenceStore(store);
+ JavaTextTools textTools = PHPeclipsePlugin.getDefault()
+ .getJavaTextTools();
+ setSourceViewerConfiguration(new PHPSourceViewerConfiguration(textTools
+ .getColorManager(), store, this,
+ IPHPPartitions.PHP_PARTITIONING));
+
+ // TODO changed in 3.x ?
+ // setRangeIndicator(new DefaultRangeIndicator());
+ // if
+ // (PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE))
+ // fUpdater = new OutlinePageSelectionUpdater();
+ // jsurfer end
+
+ // IPreferenceStore store= createCombinedPreferenceStore(null);
+ // setPreferenceStore(store);
+ // JavaTextTools textTools=
+ // PHPeclipsePlugin.getDefault().getJavaTextTools();
+ // setSourceViewerConfiguration(new
+ // JavaSourceViewerConfiguration(textTools.getColorManager(), store,
+ // this, IJavaPartitions.JAVA_PARTITIONING));
+ fMarkOccurrenceAnnotations = store
+ .getBoolean(PreferenceConstants.EDITOR_MARK_OCCURRENCES);
+ fStickyOccurrenceAnnotations = store
+ .getBoolean(PreferenceConstants.EDITOR_STICKY_OCCURRENCES);
+ // fMarkTypeOccurrences=
+ // store.getBoolean(PreferenceConstants.EDITOR_MARK_TYPE_OCCURRENCES);
+ // fMarkMethodOccurrences=
+ // store.getBoolean(PreferenceConstants.EDITOR_MARK_METHOD_OCCURRENCES);
+ // fMarkConstantOccurrences=
+ // store.getBoolean(PreferenceConstants.EDITOR_MARK_CONSTANT_OCCURRENCES);
+ // fMarkFieldOccurrences=
+ // store.getBoolean(PreferenceConstants.EDITOR_MARK_FIELD_OCCURRENCES);
+ // fMarkLocalVariableypeOccurrences=
+ // store.getBoolean(PreferenceConstants.EDITOR_MARK_LOCAL_VARIABLE_OCCURRENCES);
+ // fMarkExceptions=
+ // store.getBoolean(PreferenceConstants.EDITOR_MARK_EXCEPTION_OCCURRENCES);
+ // fMarkImplementors=
+ // store.getBoolean(PreferenceConstants.EDITOR_MARK_IMPLEMENTORS);
+ // fMarkMethodExitPoints=
+ // store.getBoolean(PreferenceConstants.EDITOR_MARK_METHOD_EXIT_POINTS);
+
+ }
+
+ /*
+ * @see org.eclipse.ui.texteditor.AbstractTextEditor#updatePropertyDependentActions()
+ */
+ protected void updatePropertyDependentActions() {
+ super.updatePropertyDependentActions();
+ if (fEncodingSupport != null)
+ fEncodingSupport.reset();
+ }
+
+ /*
+ * Update the hovering behavior depending on the preferences.
+ */
+ private void updateHoverBehavior() {
+ SourceViewerConfiguration configuration = getSourceViewerConfiguration();
+ String[] types = configuration
+ .getConfiguredContentTypes(getSourceViewer());
+
+ for (int i = 0; i < types.length; i++) {
+
+ String t = types[i];
+
+ int[] stateMasks = configuration.getConfiguredTextHoverStateMasks(
+ getSourceViewer(), t);
+
+ ISourceViewer sourceViewer = getSourceViewer();
+ if (sourceViewer instanceof ITextViewerExtension2) {
+ if (stateMasks != null) {
+ for (int j = 0; j < stateMasks.length; j++) {
+ int stateMask = stateMasks[j];
+ ITextHover textHover = configuration.getTextHover(
+ sourceViewer, t, stateMask);
+ ((ITextViewerExtension2) sourceViewer).setTextHover(
+ textHover, t, stateMask);
+ }
+ } else {
+ ITextHover textHover = configuration.getTextHover(
+ sourceViewer, t);
+ ((ITextViewerExtension2) sourceViewer).setTextHover(
+ textHover, t,
+ ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK);
+ }
+ } else
+ sourceViewer.setTextHover(configuration.getTextHover(
+ sourceViewer, t), t);
+ }
+ }
+
+ public void updatedTitleImage(Image image) {
+ setTitleImage(image);
+ }
+
+ /*
+ * @see net.sourceforge.phpdt.internal.ui.viewsupport.IViewPartInputProvider#getViewPartInput()
+ */
+ public Object getViewPartInput() {
+ return getEditorInput().getAdapter(IResource.class);
+ }
+
+ /*
+ * @see org.eclipse.ui.texteditor.AbstractTextEditor#doSetSelection(ISelection)
+ */
+ protected void doSetSelection(ISelection selection) {
+ super.doSetSelection(selection);
+ synchronizeOutlinePageSelection();
+ }
+
+ boolean isFoldingEnabled() {
+ return PHPeclipsePlugin.getDefault().getPreferenceStore().getBoolean(
+ PreferenceConstants.EDITOR_FOLDING_ENABLED);
+ }
+
+ /*
+ * @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.
+ * widgets.Composite)
+ */
+ public void createPartControl(Composite parent) {
+ super.createPartControl(parent);
+
+ // fSourceViewerDecorationSupport.install(getPreferenceStore());
+
+ ProjectionViewer projectionViewer = (ProjectionViewer) getSourceViewer();
+
+ fProjectionSupport = new ProjectionSupport(projectionViewer,
+ getAnnotationAccess(), getSharedColors());
+ fProjectionSupport
+ .addSummarizableAnnotationType("org.eclipse.ui.workbench.texteditor.error"); //$NON-NLS-1$
+ fProjectionSupport
+ .addSummarizableAnnotationType("org.eclipse.ui.workbench.texteditor.warning"); //$NON-NLS-1$
+ fProjectionSupport
+ .setHoverControlCreator(new IInformationControlCreator() {
+ public IInformationControl createInformationControl(
+ Shell shell) {
+ return new CustomSourceInformationControl(shell,
+ IDocument.DEFAULT_CONTENT_TYPE);
+ }
+ });
+ fProjectionSupport.install();
+
+ fProjectionModelUpdater = PHPeclipsePlugin.getDefault()
+ .getFoldingStructureProviderRegistry()
+ .getCurrentFoldingProvider();
+ if (fProjectionModelUpdater != null)
+ fProjectionModelUpdater.install(this, projectionViewer);
+
+ if (isFoldingEnabled())
+ projectionViewer.doOperation(ProjectionViewer.TOGGLE);
+ Preferences preferences = PHPeclipsePlugin.getDefault()
+ .getPluginPreferences();
+ preferences.addPropertyChangeListener(fPropertyChangeListener);
+
+ IInformationControlCreator informationControlCreator = new IInformationControlCreator() {
+ public IInformationControl createInformationControl(Shell parent) {
+ boolean cutDown = false;
+ int style = cutDown ? SWT.NONE : (SWT.V_SCROLL | SWT.H_SCROLL);
+ return new DefaultInformationControl(parent, SWT.RESIZE, style,
+ new HTMLTextPresenter(cutDown));
+ }
+ };
+
+ fInformationPresenter = new InformationPresenter(
+ informationControlCreator);
+ fInformationPresenter.setSizeConstraints(60, 10, true, true);
+ fInformationPresenter.install(getSourceViewer());
+
+ fEditorSelectionChangedListener = new EditorSelectionChangedListener();
+ fEditorSelectionChangedListener.install(getSelectionProvider());
+
+ if (isBrowserLikeLinks())
+ enableBrowserLikeLinks();
+
+ if (PreferenceConstants.getPreferenceStore().getBoolean(
+ PreferenceConstants.EDITOR_DISABLE_OVERWRITE_MODE))
+ enableOverwriteMode(false);
+
+ if (fMarkOccurrenceAnnotations)
+ installOccurrencesFinder();
+
+ PlatformUI.getWorkbench().addWindowListener(fActivationListener);
+
+ setWordWrap();
+ }
+
+ private void setWordWrap() {
+ if (getSourceViewer() != null) {
+ getSourceViewer().getTextWidget().setWordWrap(
+ PHPeclipsePlugin.getDefault().getPreferenceStore()
+ .getBoolean(PreferenceConstants.EDITOR_WRAP_WORDS));
+ }
+ }
+
+ protected void configureSourceViewerDecorationSupport(
+ SourceViewerDecorationSupport support) {
+
+ support.setCharacterPairMatcher(fBracketMatcher);
+ support.setMatchingCharacterPainterPreferenceKeys(MATCHING_BRACKETS,
+ MATCHING_BRACKETS_COLOR);
+
+ super.configureSourceViewerDecorationSupport(support);
+ }
+
+ /*
+ * @see org.eclipse.ui.texteditor.AbstractTextEditor#gotoMarker(org.eclipse.core.resources.IMarker)
+ */
+ public void gotoMarker(IMarker marker) {
+ fLastMarkerTarget = marker;
+ if (!fIsUpdatingAnnotationViews) {
+ super.gotoMarker(marker);
+ }
+ }
+
+ /**
+ * Jumps to the next enabled annotation according to the given direction. An
+ * annotation type is enabled if it is configured to be in the Next/Previous
+ * tool bar drop down menu and if it is checked.
+ *
+ * @param forward
+ * <code>true</code> if search direction is forward,
+ * <code>false</code> if backward
+ */
+ public Annotation gotoAnnotation(boolean forward) {
+ ITextSelection selection = (ITextSelection) getSelectionProvider()
+ .getSelection();
+ Position position = new Position(0, 0);
+ Annotation annotation = null;
+ if (false /* delayed - see bug 18316 */) {
+ annotation = getNextAnnotation(selection.getOffset(), selection
+ .getLength(), forward, position);
+ selectAndReveal(position.getOffset(), position.getLength());
+ } else /* no delay - see bug 18316 */{
+ annotation = getNextAnnotation(selection.getOffset(), selection
+ .getLength(), forward, position);
+ setStatusLineErrorMessage(null);
+ setStatusLineMessage(null);
+ if (annotation != null) {
+ updateAnnotationViews(annotation);
+ selectAndReveal(position.getOffset(), position.getLength());
+ setStatusLineMessage(annotation.getText());
+ }
+ }
+ return annotation;
+ }
+
+ /**
+ * Returns the lock object for the given annotation model.
+ *
+ * @param annotationModel
+ * the annotation model
+ * @return the annotation model's lock object
+ * @since 3.0
+ */
+ private Object getLockObject(IAnnotationModel annotationModel) {
+ if (annotationModel instanceof ISynchronizable)
+ return ((ISynchronizable) annotationModel).getLockObject();
+ else
+ return annotationModel;
+ }
+
+ /**
+ * Updates the annotation views that show the given annotation.
+ *
+ * @param annotation
+ * the annotation
+ */
+ private void updateAnnotationViews(Annotation annotation) {
+ IMarker marker = null;
+ if (annotation instanceof MarkerAnnotation)
+ marker = ((MarkerAnnotation) annotation).getMarker();
+ else if (annotation instanceof IJavaAnnotation) {
+ Iterator e = ((IJavaAnnotation) annotation).getOverlaidIterator();
+ if (e != null) {
+ while (e.hasNext()) {
+ Object o = e.next();
+ if (o instanceof MarkerAnnotation) {
+ marker = ((MarkerAnnotation) o).getMarker();
+ break;
+ }
+ }
+ }
+ }
+
+ if (marker != null && !marker.equals(fLastMarkerTarget)) {
+ try {
+ boolean isProblem = marker.isSubtypeOf(IMarker.PROBLEM);
+ IWorkbenchPage page = getSite().getPage();
+ IViewPart view = page
+ .findView(isProblem ? IPageLayout.ID_PROBLEM_VIEW
+ : IPageLayout.ID_TASK_LIST); //$NON-NLS-1$ //$NON-NLS-2$
+ if (view != null) {
+ Method method = view
+ .getClass()
+ .getMethod(
+ "setSelection", new Class[] { IStructuredSelection.class, boolean.class }); //$NON-NLS-1$
+ method.invoke(view, new Object[] {
+ new StructuredSelection(marker), Boolean.TRUE });
+ }
+ } catch (CoreException x) {
+ } catch (NoSuchMethodException x) {
+ } catch (IllegalAccessException x) {
+ } catch (InvocationTargetException x) {
+ }
+ // ignore exceptions, don't update any of the lists, just set status
+ // line
+ }
+ }
+
+ /**
+ * Returns this document's complete text.
+ *
+ * @return the document's complete text
+ */
+ public String get() {
+ IDocument doc = this.getDocumentProvider().getDocument(
+ this.getEditorInput());
+ return doc.get();
+ }
+
+ /**
+ * Sets the outliner's context menu ID.
+ */
+ protected void setOutlinerContextMenuId(String menuId) {
+ fOutlinerContextMenuId = menuId;
+ }
+
+ /**
+ * Returns the standard action group of this editor.
+ */
+ protected ActionGroup getActionGroup() {
+ return fActionGroups;
+ }
+
+ // public JavaOutlinePage getfOutlinePage() {
+ // return fOutlinePage;
+ // }
+
+ /**
+ * The <code>PHPEditor</code> implementation of this
+ * <code>AbstractTextEditor</code> method extend the actions to add those
+ * specific to the receiver
+ */
+ protected void createActions() {
+ super.createActions();
+
+ ActionGroup oeg, ovg, jsg, sg;
+ fActionGroups = new CompositeActionGroup(
+ new ActionGroup[] { oeg = new OpenEditorActionGroup(this),
+ // sg= new ShowActionGroup(this),
+ // ovg= new OpenViewActionGroup(this),
+ // jsg= new JavaSearchActionGroup(this)
+ });
+ fContextMenuGroup = new CompositeActionGroup(new ActionGroup[] { oeg });
+ // , ovg, sg, jsg});
+
+ fFoldingGroup = new FoldingActionGroup(this, getViewer());
+
+ // ResourceAction resAction = new
+ // TextOperationAction(PHPEditorMessages.getResourceBundle(),
+ // "ShowJavaDoc.", this, ISourceViewer.INFORMATION, true); //$NON-NLS-1$
+ // resAction = new
+ // InformationDispatchAction(PHPEditorMessages.getResourceBundle(),
+ // "ShowJavaDoc.", (TextOperationAction) resAction); //$NON-NLS-1$
+ // resAction.setActionDefinitionId(net.sourceforge.phpdt.ui.actions.PHPEditorActionDefinitionIds.SHOW_JAVADOC);
+ // setAction("ShowJavaDoc", resAction); //$NON-NLS-1$
+
+ // WorkbenchHelp.setHelp(resAction,
+ // IJavaHelpContextIds.SHOW_JAVADOC_ACTION);
+
+ Action action = new GotoMatchingBracketAction(this);
+ action
+ .setActionDefinitionId(PHPEditorActionDefinitionIds.GOTO_MATCHING_BRACKET);
+ setAction(GotoMatchingBracketAction.GOTO_MATCHING_BRACKET, action);
+
+ // action= new
+ // TextOperationAction(PHPEditorMessages.getResourceBundle(),"ShowOutline.",
+ // this, JavaSourceViewer.SHOW_OUTLINE, true); //$NON-NLS-1$
+ // action.setActionDefinitionId(PHPEditorActionDefinitionIds.SHOW_OUTLINE);
+ // setAction(PHPEditorActionDefinitionIds.SHOW_OUTLINE, action);
+ // // WorkbenchHelp.setHelp(action,
+ // IJavaHelpContextIds.SHOW_OUTLINE_ACTION);
+ //
+ // action= new
+ // TextOperationAction(PHPEditorMessages.getResourceBundle(),"OpenStructure.",
+ // this, JavaSourceViewer.OPEN_STRUCTURE, true); //$NON-NLS-1$
+ // action.setActionDefinitionId(PHPEditorActionDefinitionIds.SHOW_OUTLINE.OPEN_STRUCTURE);
+ // setAction(PHPEditorActionDefinitionIds.SHOW_OUTLINE.OPEN_STRUCTURE,
+ // action);
+ // // WorkbenchHelp.setHelp(action,
+ // IJavaHelpContextIds.OPEN_STRUCTURE_ACTION);
+ //
+ // action= new
+ // TextOperationAction(PHPEditorMessages.getResourceBundle(),"OpenHierarchy.",
+ // this, JavaSourceViewer.SHOW_HIERARCHY, true); //$NON-NLS-1$
+ // action.setActionDefinitionId(PHPEditorActionDefinitionIds.SHOW_OUTLINE.OPEN_HIERARCHY);
+ // setAction(PHPEditorActionDefinitionIds.SHOW_OUTLINE.OPEN_HIERARCHY,
+ // action);
+ // // WorkbenchHelp.setHelp(action,
+ // IJavaHelpContextIds.OPEN_HIERARCHY_ACTION);
+
+ fEncodingSupport = new DefaultEncodingSupport();
+ fEncodingSupport.initialize(this);
+
+ // fSelectionHistory= new SelectionHistory(this);
+ //
+ // action= new StructureSelectEnclosingAction(this, fSelectionHistory);
+ // action.setActionDefinitionId(PHPEditorActionDefinitionIds.SELECT_ENCLOSING);
+ // setAction(StructureSelectionAction.ENCLOSING, action);
+ //
+ // action= new StructureSelectNextAction(this, fSelectionHistory);
+ // action.setActionDefinitionId(PHPEditorActionDefinitionIds.SELECT_NEXT);
+ // setAction(StructureSelectionAction.NEXT, action);
+ //
+ // action= new StructureSelectPreviousAction(this, fSelectionHistory);
+ // action.setActionDefinitionId(PHPEditorActionDefinitionIds.SELECT_PREVIOUS);
+ // setAction(StructureSelectionAction.PREVIOUS, action);
+ //
+ // StructureSelectHistoryAction historyAction= new
+ // StructureSelectHistoryAction(this, fSelectionHistory);
+ // historyAction.setActionDefinitionId(PHPEditorActionDefinitionIds.SELECT_LAST);
+ // setAction(StructureSelectionAction.HISTORY, historyAction);
+ // fSelectionHistory.setHistoryAction(historyAction);
+ //
+ // action= GoToNextPreviousMemberAction.newGoToNextMemberAction(this);
+ // action.setActionDefinitionId(PHPEditorActionDefinitionIds.GOTO_NEXT_MEMBER);
+ // setAction(GoToNextPreviousMemberAction.NEXT_MEMBER, action);
+ //
+ // action=
+ // GoToNextPreviousMemberAction.newGoToPreviousMemberAction(this);
+ // action.setActionDefinitionId(PHPEditorActionDefinitionIds.GOTO_PREVIOUS_MEMBER);
+ // setAction(GoToNextPreviousMemberAction.PREVIOUS_MEMBER, action);
+ //
+ // action= new QuickFormatAction();
+ // action.setActionDefinitionId(PHPEditorActionDefinitionIds.QUICK_FORMAT);
+ // setAction(IJavaEditorActionDefinitionIds.QUICK_FORMAT, action);
+ //
+ // action= new RemoveOccurrenceAnnotations(this);
+ // action.setActionDefinitionId(PHPEditorActionDefinitionIds.REMOVE_OCCURRENCE_ANNOTATIONS);
+ // setAction("RemoveOccurrenceAnnotations", action); //$NON-NLS-1$
+
+ // add annotation actions
+ action = new JavaSelectMarkerRulerAction2(PHPEditorMessages
+ .getResourceBundle(), "Editor.RulerAnnotationSelection.", this); //$NON-NLS-1$
+ setAction("AnnotationAction", action); //$NON-NLS-1$
+ }
+
+ private void internalDoSetInput(IEditorInput input) throws CoreException {
+ super.doSetInput(input);
+
+ if (getSourceViewer() instanceof JavaSourceViewer) {
+ JavaSourceViewer viewer = (JavaSourceViewer) getSourceViewer();
+ if (viewer.getReconciler() == null) {
+ IReconciler reconciler = getSourceViewerConfiguration()
+ .getReconciler(viewer);
+ if (reconciler != null) {
+ reconciler.install(viewer);
+ viewer.setReconciler(reconciler);
+ }
+ }
+ }
+
+ if (fEncodingSupport != null)
+ fEncodingSupport.reset();
+
+ setOutlinePageInput(fOutlinePage, input);
+
+ if (fProjectionModelUpdater != null)
+ fProjectionModelUpdater.initialize();
+
+ // if (isShowingOverrideIndicators())
+ // installOverrideIndicator(false);
+ }
+
+ /*
+ * @see org.eclipse.ui.texteditor.AbstractTextEditor#setPreferenceStore(org.eclipse.jface.preference.IPreferenceStore)
+ * @since 3.0
+ */
+ protected void setPreferenceStore(IPreferenceStore store) {
+ super.setPreferenceStore(store);
+ if (getSourceViewerConfiguration() instanceof PHPSourceViewerConfiguration) {
+ JavaTextTools textTools = PHPeclipsePlugin.getDefault()
+ .getJavaTextTools();
+ setSourceViewerConfiguration(new PHPSourceViewerConfiguration(
+ textTools.getColorManager(), store, this,
+ IPHPPartitions.PHP_PARTITIONING));
+ }
+ if (getSourceViewer() instanceof JavaSourceViewer)
+ ((JavaSourceViewer) getSourceViewer()).setPreferenceStore(store);
+ }
+
+ /**
+ * The <code>PHPEditor</code> implementation of this
+ * <code>AbstractTextEditor</code> method performs any extra disposal
+ * actions required by the php editor.
+ */
+ public void dispose() {
+ if (fProjectionModelUpdater != null) {
+ fProjectionModelUpdater.uninstall();
+ fProjectionModelUpdater = null;
+ }
+
+ if (fProjectionSupport != null) {
+ fProjectionSupport.dispose();
+ fProjectionSupport = null;
+ }
+ // PHPEditorEnvironment.disconnect(this);
+ if (fOutlinePage != null)
+ fOutlinePage.setInput(null);
+
+ if (fActionGroups != null)
+ fActionGroups.dispose();
+
+ if (isBrowserLikeLinks())
+ disableBrowserLikeLinks();
+
+ // cancel possible running computation
+ fMarkOccurrenceAnnotations = false;
+ uninstallOccurrencesFinder();
+
+ uninstallOverrideIndicator();
+
+ if (fActivationListener != null) {
+ PlatformUI.getWorkbench().removeWindowListener(fActivationListener);
+ fActivationListener = null;
+ }
+
+ if (fEncodingSupport != null) {
+ fEncodingSupport.dispose();
+ fEncodingSupport = null;
+ }
+
+ if (fPropertyChangeListener != null) {
+ Preferences preferences = PHPeclipsePlugin.getDefault()
+ .getPluginPreferences();
+ preferences.removePropertyChangeListener(fPropertyChangeListener);
+ fPropertyChangeListener = null;
+ }
+
+ // if (fSourceViewerDecorationSupport != null) {
+ // fSourceViewerDecorationSupport.dispose();
+ // fSourceViewerDecorationSupport = null;
+ // }
+
+ if (fBracketMatcher != null) {
+ fBracketMatcher.dispose();
+ fBracketMatcher = null;
+ }
+
+ if (fEditorSelectionChangedListener != null) {
+ fEditorSelectionChangedListener.uninstall(getSelectionProvider());
+ fEditorSelectionChangedListener = null;
+ }
+
+ super.dispose();
+ }
+
+ /**
+ * The <code>PHPEditor</code> implementation of this
+ * <code>AbstractTextEditor</code> method performs any extra revert
+ * behavior required by the php editor.
+ */
+ // public void doRevertToSaved() {
+ // super.doRevertToSaved();
+ // if (fOutlinePage != null)
+ // fOutlinePage.update();
+ // }
+ /**
+ * The <code>PHPEditor</code> implementation of this
+ * <code>AbstractTextEditor</code> method performs any extra save behavior
+ * required by the php editor.
+ */
+ // public void doSave(IProgressMonitor monitor) {
+ // super.doSave(monitor);
+ // compile or not, according to the user preferences
+ // IPreferenceStore store = getPreferenceStore();
+ // the parse on save was changed to the eclipse "builders" concept
+ // if (store.getBoolean(PHPeclipsePlugin.PHP_PARSE_ON_SAVE)) {
+ // IAction a = PHPParserAction.getInstance();
+ // if (a != null)
+ // a.run();
+ // }
+ // if (SWT.getPlatform().equals("win32")) {
+ // IAction a = ShowExternalPreviewAction.getInstance();
+ // if (a != null)
+ // a.run();
+ // }
+ // if (fOutlinePage != null)
+ // fOutlinePage.update();
+ // }
+ /**
+ * The <code>PHPEditor</code> implementation of this
+ * <code>AbstractTextEditor</code> method performs any extra save as
+ * behavior required by the php editor.
+ */
+ // public void doSaveAs() {
+ // super.doSaveAs();
+ // if (fOutlinePage != null)
+ // fOutlinePage.update();
+ // }
+ /*
+ * @see StatusTextEditor#getStatusHeader(IStatus)
+ */
+ protected String getStatusHeader(IStatus status) {
+ if (fEncodingSupport != null) {
+ String message = fEncodingSupport.getStatusHeader(status);
+ if (message != null)
+ return message;
+ }
+ return super.getStatusHeader(status);
+ }
+
+ /*
+ * @see StatusTextEditor#getStatusBanner(IStatus)
+ */
+ protected String getStatusBanner(IStatus status) {
+ if (fEncodingSupport != null) {
+ String message = fEncodingSupport.getStatusBanner(status);
+ if (message != null)
+ return message;
+ }
+ return super.getStatusBanner(status);
+ }
+
+ /*
+ * @see StatusTextEditor#getStatusMessage(IStatus)
+ */
+ protected String getStatusMessage(IStatus status) {
+ if (fEncodingSupport != null) {
+ String message = fEncodingSupport.getStatusMessage(status);
+ if (message != null)
+ return message;
+ }
+ return super.getStatusMessage(status);
+ }
+
+ /**
+ * The <code>PHPEditor</code> implementation of this
+ * <code>AbstractTextEditor</code> method performs sets the input of the
+ * outline page after AbstractTextEditor has set input.
+ */
+ // protected void doSetInput(IEditorInput input) throws CoreException {
+ // super.doSetInput(input);
+ // if (fEncodingSupport != null)
+ // fEncodingSupport.reset();
+ // setOutlinePageInput(fOutlinePage, input);
+ // }
+ /*
+ * @see AbstractTextEditor#doSetInput
+ */
+ protected void doSetInput(IEditorInput input) throws CoreException {
+ ISourceViewer sourceViewer = getSourceViewer();
+ if (!(sourceViewer instanceof ISourceViewerExtension2)) {
+ setPreferenceStore(createCombinedPreferenceStore(input));
+ internalDoSetInput(input);
+ return;
+ }
+
+ // uninstall & unregister preference store listener
+ if (isBrowserLikeLinks())
+ disableBrowserLikeLinks();
+ getSourceViewerDecorationSupport(sourceViewer).uninstall();
+ ((ISourceViewerExtension2) sourceViewer).unconfigure();
+
+ setPreferenceStore(createCombinedPreferenceStore(input));
+
+ // install & register preference store listener
+ sourceViewer.configure(getSourceViewerConfiguration());
+ getSourceViewerDecorationSupport(sourceViewer).install(
+ getPreferenceStore());
+ if (isBrowserLikeLinks())
+ enableBrowserLikeLinks();
+
+ internalDoSetInput(input);
+ }
+
+ /*
+ * @see org.phpeclipse.phpdt.internal.ui.viewsupport.IViewPartInputProvider#getViewPartInput()
+ */
+ // public Object getViewPartInput() {
+ // return getEditorInput().getAdapter(IFile.class);
+ // }
+ /**
+ * The <code>PHPEditor</code> implementation of this
+ * <code>AbstractTextEditor</code> method adds any PHPEditor specific
+ * entries.
+ */
+ public void editorContextMenuAboutToShow(MenuManager menu) {
+ super.editorContextMenuAboutToShow(menu);
+ menu.appendToGroup(ITextEditorActionConstants.GROUP_UNDO,
+ new Separator(IContextMenuConstants.GROUP_OPEN));
+ menu.insertAfter(IContextMenuConstants.GROUP_OPEN, new GroupMarker(
+ IContextMenuConstants.GROUP_SHOW));
+
+ ActionContext context = new ActionContext(getSelectionProvider()
+ .getSelection());
+ fContextMenuGroup.setContext(context);
+ fContextMenuGroup.fillContextMenu(menu);
+ fContextMenuGroup.setContext(null);
+ // addAction(menu, ITextEditorActionConstants.GROUP_EDIT, "Format");
+ // //$NON-NLS-1$
+ //
+ // ActionContext context =
+ // new ActionContext(getSelectionProvider().getSelection());
+ // fContextMenuGroup.setContext(context);
+ // fContextMenuGroup.fillContextMenu(menu);
+ // fContextMenuGroup.setContext(null);
+ }
+
+ /**
+ * Creates the outline page used with this editor.
+ */
+ protected JavaOutlinePage createOutlinePage() {
+ JavaOutlinePage page = new JavaOutlinePage(fOutlinerContextMenuId, this);
+ fOutlineSelectionChangedListener.install(page);
+ setOutlinePageInput(page, getEditorInput());
+ return page;
+ }
+
+ /**
+ * Informs the editor that its outliner has been closed.
+ */
+ public void outlinePageClosed() {
+ if (fOutlinePage != null) {
+ fOutlineSelectionChangedListener.uninstall(fOutlinePage);
+ fOutlinePage = null;
+ resetHighlightRange();
+ }
+ }
+
+ /**
+ * Synchronizes the outliner selection with the given element position in
+ * the editor.
+ *
+ * @param element
+ * the java element to select
+ */
+ protected void synchronizeOutlinePage(ISourceReference element) {
+ synchronizeOutlinePage(element, true);
+ }
+
+ /**
+ * Synchronizes the outliner selection with the given element position in
+ * the editor.
+ *
+ * @param element
+ * the java element to select
+ * @param checkIfOutlinePageActive
+ * <code>true</code> if check for active outline page needs to
+ * be done
+ */
+ protected void synchronizeOutlinePage(ISourceReference element,
+ boolean checkIfOutlinePageActive) {
+ if (fOutlinePage != null && element != null
+ && !(checkIfOutlinePageActive && isJavaOutlinePageActive())) {
+ fOutlineSelectionChangedListener.uninstall(fOutlinePage);
+ fOutlinePage.select(element);
+ fOutlineSelectionChangedListener.install(fOutlinePage);
+ }
+ }
+
+ /**
+ * Synchronizes the outliner selection with the actual cursor position in
+ * the editor.
+ */
+ public void synchronizeOutlinePageSelection() {
+ synchronizeOutlinePage(computeHighlightRangeSourceReference());
+
+ // ISourceViewer sourceViewer = getSourceViewer();
+ // if (sourceViewer == null || fOutlinePage == null)
+ // return;
+ //
+ // StyledText styledText = sourceViewer.getTextWidget();
+ // if (styledText == null)
+ // return;
+ //
+ // int caret = 0;
+ // if (sourceViewer instanceof ITextViewerExtension3) {
+ // ITextViewerExtension3 extension = (ITextViewerExtension3)
+ // sourceViewer;
+ // caret =
+ // extension.widgetOffset2ModelOffset(styledText.getCaretOffset());
+ // } else {
+ // int offset = sourceViewer.getVisibleRegion().getOffset();
+ // caret = offset + styledText.getCaretOffset();
+ // }
+ //
+ // IJavaElement element = getElementAt(caret);
+ // if (element instanceof ISourceReference) {
+ // fOutlinePage.removeSelectionChangedListener(fSelectionChangedListener);
+ // fOutlinePage.select((ISourceReference) element);
+ // fOutlinePage.addSelectionChangedListener(fSelectionChangedListener);
+ // }
+ }
+
+ protected void setSelection(ISourceReference reference, boolean moveCursor) {
+
+ ISelection selection = getSelectionProvider().getSelection();
+ if (selection instanceof TextSelection) {
+ TextSelection textSelection = (TextSelection) selection;
+ if (textSelection.getOffset() != 0
+ || textSelection.getLength() != 0)
+ markInNavigationHistory();
+ }
+
+ if (reference != null) {
+
+ StyledText textWidget = null;
+
+ ISourceViewer sourceViewer = getSourceViewer();
+ if (sourceViewer != null)
+ textWidget = sourceViewer.getTextWidget();
+
+ if (textWidget == null)
+ return;
+
+ try {
+
+ ISourceRange range = reference.getSourceRange();
+ if (range == null)
+ return;
+
+ int offset = range.getOffset();
+ int length = range.getLength();
+
+ if (offset < 0 || length < 0)
+ return;
+
+ textWidget.setRedraw(false);
+
+ setHighlightRange(offset, length, moveCursor);
+
+ if (!moveCursor)
+ return;
+
+ offset = -1;
+ length = -1;
+
+ if (reference instanceof IMember) {
+ range = ((IMember) reference).getNameRange();
+ if (range != null) {
+ offset = range.getOffset();
+ length = range.getLength();
+ }
+ }
+ // else if (reference instanceof IImportDeclaration) {
+ // String name= ((IImportDeclaration)
+ // reference).getElementName();
+ // if (name != null && name.length() > 0) {
+ // String content= reference.getSource();
+ // if (content != null) {
+ // offset= range.getOffset() + content.indexOf(name);
+ // length= name.length();
+ // }
+ // }
+ // } else if (reference instanceof IPackageDeclaration) {
+ // String name= ((IPackageDeclaration)
+ // reference).getElementName();
+ // if (name != null && name.length() > 0) {
+ // String content= reference.getSource();
+ // if (content != null) {
+ // offset= range.getOffset() + content.indexOf(name);
+ // length= name.length();
+ // }
+ // }
+ // }
+
+ if (offset > -1 && length > 0) {
+ sourceViewer.revealRange(offset, length);
+ sourceViewer.setSelectedRange(offset, length);
+ }
+
+ } catch (JavaModelException x) {
+ } catch (IllegalArgumentException x) {
+ } finally {
+ if (textWidget != null)
+ textWidget.setRedraw(true);
+ }
+
+ } else if (moveCursor) {
+ resetHighlightRange();
+ }
+
+ markInNavigationHistory();
+ }
+
+ public void setSelection(IJavaElement element) {
+ if (element == null || element instanceof ICompilationUnit) { // ||
+ // element
+ // instanceof
+ // IClassFile)
+ // {
+ /*
+ * If the element is an ICompilationUnit this unit is either the
+ * input of this editor or not being displayed. In both cases,
+ * nothing should happened.
+ * (http://dev.eclipse.org/bugs/show_bug.cgi?id=5128)
+ */
+ return;
+ }
+
+ IJavaElement corresponding = getCorrespondingElement(element);
+ if (corresponding instanceof ISourceReference) {
+ ISourceReference reference = (ISourceReference) corresponding;
+ // set highlight range
+ setSelection(reference, true);
+ // set outliner selection
+ if (fOutlinePage != null) {
+ fOutlineSelectionChangedListener.uninstall(fOutlinePage);
+ fOutlinePage.select(reference);
+ fOutlineSelectionChangedListener.install(fOutlinePage);
+ }
+ }
+ }
+
+ public synchronized void editingScriptStarted() {
+ ++fIgnoreOutlinePageSelection;
+ }
+
+ public synchronized void editingScriptEnded() {
+ --fIgnoreOutlinePageSelection;
+ }
+
+ public synchronized boolean isEditingScriptRunning() {
+ return (fIgnoreOutlinePageSelection > 0);
+ }
+
+ /**
+ * The <code>PHPEditor</code> implementation of this
+ * <code>AbstractTextEditor</code> method performs gets the java content
+ * outline page if request is for a an outline page.
+ */
+ public Object getAdapter(Class required) {
+
+ if (IContentOutlinePage.class.equals(required)) {
+ if (fOutlinePage == null)
+ fOutlinePage = createOutlinePage();
+ return fOutlinePage;
+ }
+
+ if (IEncodingSupport.class.equals(required))
+ return fEncodingSupport;
+
+ if (required == IShowInTargetList.class) {
+ return new IShowInTargetList() {
+ public String[] getShowInTargetIds() {
+ return new String[] { JavaUI.ID_PACKAGES,
+ IPageLayout.ID_OUTLINE, IPageLayout.ID_RES_NAV };
+ }
+
+ };
+ }
+ if (fProjectionSupport != null) {
+ Object adapter = fProjectionSupport.getAdapter(getSourceViewer(),
+ required);
+ if (adapter != null)
+ return adapter;
+ }
+
+ return super.getAdapter(required);
+ }
+
+ // public Object getAdapter(Class required) {
+ // if (IContentOutlinePage.class.equals(required)) {
+ // if (fOutlinePage == null) {
+ // fOutlinePage = new PHPContentOutlinePage(getDocumentProvider(), this);
+ // if (getEditorInput() != null)
+ // fOutlinePage.setInput(getEditorInput());
+ // }
+ // return fOutlinePage;
+ // }
+ //
+ // if (IEncodingSupport.class.equals(required))
+ // return fEncodingSupport;
+ //
+ // return super.getAdapter(required);
+ // }
+
+ protected void doSelectionChanged(SelectionChangedEvent event) {
+ ISourceReference reference = null;
+
+ ISelection selection = event.getSelection();
+ Iterator iter = ((IStructuredSelection) selection).iterator();
+ while (iter.hasNext()) {
+ Object o = iter.next();
+ if (o instanceof ISourceReference) {
+ reference = (ISourceReference) o;
+ break;
+ }
+ }
+
+ if (!isActivePart() && PHPeclipsePlugin.getActivePage() != null)
+ PHPeclipsePlugin.getActivePage().bringToTop(this);
+
+ try {
+ editingScriptStarted();
+ setSelection(reference, !isActivePart());
+ } finally {
+ editingScriptEnded();
+ }
+ }
+
+ /*
+ * @see AbstractTextEditor#adjustHighlightRange(int, int)
+ */
+ protected void adjustHighlightRange(int offset, int length) {
+
+ try {
+
+ IJavaElement element = getElementAt(offset);
+ while (element instanceof ISourceReference) {
+ ISourceRange range = ((ISourceReference) element)
+ .getSourceRange();
+ if (offset < range.getOffset() + range.getLength()
+ && range.getOffset() < offset + length) {
+
+ ISourceViewer viewer = getSourceViewer();
+ if (viewer instanceof ITextViewerExtension5) {
+ ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
+ extension.exposeModelRange(new Region(
+ range.getOffset(), range.getLength()));
+ }
+
+ setHighlightRange(range.getOffset(), range.getLength(),
+ true);
+ if (fOutlinePage != null) {
+ fOutlineSelectionChangedListener
+ .uninstall(fOutlinePage);
+ fOutlinePage.select((ISourceReference) element);
+ fOutlineSelectionChangedListener.install(fOutlinePage);
+ }
+
+ return;
+ }
+ element = element.getParent();
+ }
+
+ } catch (JavaModelException x) {
+ PHPeclipsePlugin.log(x.getStatus());
+ }
+
+ ISourceViewer viewer = getSourceViewer();
+ if (viewer instanceof ITextViewerExtension5) {
+ ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
+ extension.exposeModelRange(new Region(offset, length));
+ } else {
+ resetHighlightRange();
+ }
+
+ }
+
+ protected boolean isActivePart() {
+ IWorkbenchWindow window = getSite().getWorkbenchWindow();
+ IPartService service = window.getPartService();
+ IWorkbenchPart part = service.getActivePart();
+ return part != null && part.equals(this);
+ }
+
+ // public void openContextHelp() {
+ // IDocument doc =
+ // this.getDocumentProvider().getDocument(this.getEditorInput());
+ // ITextSelection selection = (ITextSelection)
+ // this.getSelectionProvider().getSelection();
+ // int pos = selection.getOffset();
+ // String word = getFunctionName(doc, pos);
+ // openContextHelp(word);
+ // }
+ //
+ // private void openContextHelp(String word) {
+ // open(word);
+ // }
+ //
+ // public static void open(String word) {
+ // IHelp help = WorkbenchHelp.getHelpSupport();
+ // if (help != null) {
+ // IHelpResource helpResource = new PHPFunctionHelpResource(word);
+ // WorkbenchHelp.getHelpSupport().displayHelpResource(helpResource);
+ // } else {
+ // // showMessage(shell, dialogTitle, ActionMessages.getString("Open help
+ // not available"), false); //$NON-NLS-1$
+ // }
+ // }
+
+ // private String getFunctionName(IDocument doc, int pos) {
+ // Point word = PHPWordExtractor.findWord(doc, pos);
+ // if (word != null) {
+ // try {
+ // return doc.get(word.x, word.y).replace('_', '-');
+ // } catch (BadLocationException e) {
+ // }
+ // }
+ // return "";
+ // }
+
+ /*
+ * @see AbstractTextEditor#handlePreferenceStoreChanged(PropertyChangeEvent)
+ */
+ protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
+
+ try {
+
+ ISourceViewer sourceViewer = getSourceViewer();
+ if (sourceViewer == null)
+ return;
+
+ String property = event.getProperty();
+
+ if (PreferenceConstants.EDITOR_TAB_WIDTH.equals(property)) {
+ Object value = event.getNewValue();
+ if (value instanceof Integer) {
+ sourceViewer.getTextWidget().setTabs(
+ ((Integer) value).intValue());
+ } else if (value instanceof String) {
+ try {
+ sourceViewer.getTextWidget().setTabs(
+ Integer.parseInt((String) value));
+ } catch (NumberFormatException e) {
+ // bug #1038071 - set default tab:
+ sourceViewer.getTextWidget().setTabs(80);
+ }
+ }
+ return;
+ }
+
+ // if (OVERVIEW_RULER.equals(property)) {
+ // if (isOverviewRulerVisible())
+ // showOverviewRuler();
+ // else
+ // hideOverviewRuler();
+ // return;
+ // }
+
+ // if (LINE_NUMBER_RULER.equals(property)) {
+ // if (isLineNumberRulerVisible())
+ // showLineNumberRuler();
+ // else
+ // hideLineNumberRuler();
+ // return;
+ // }
+
+ // if (fLineNumberRulerColumn != null
+ // && (LINE_NUMBER_COLOR.equals(property) ||
+ // PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT.equals(property) ||
+ // PREFERENCE_COLOR_BACKGROUND.equals(property))) {
+ //
+ // initializeLineNumberRulerColumn(fLineNumberRulerColumn);
+ // }
+
+ if (isJavaEditorHoverProperty(property))
+ updateHoverBehavior();
+
+ if (BROWSER_LIKE_LINKS.equals(property)) {
+ if (isBrowserLikeLinks())
+ enableBrowserLikeLinks();
+ else
+ disableBrowserLikeLinks();
+ return;
+ }
+
+ if (PreferenceConstants.EDITOR_DISABLE_OVERWRITE_MODE
+ .equals(property)) {
+ if (event.getNewValue() instanceof Boolean) {
+ Boolean disable = (Boolean) event.getNewValue();
+ enableOverwriteMode(!disable.booleanValue());
+ }
+ return;
+ }
+
+ boolean newBooleanValue = false;
+ Object newValue = event.getNewValue();
+ if (newValue != null)
+ newBooleanValue = Boolean.valueOf(newValue.toString())
+ .booleanValue();
+
+ if (PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE
+ .equals(property)) {
+ if (newBooleanValue)
+ selectionChanged();
+ return;
+ }
+
+ if (PreferenceConstants.EDITOR_MARK_OCCURRENCES.equals(property)) {
+ if (newBooleanValue != fMarkOccurrenceAnnotations) {
+ fMarkOccurrenceAnnotations = newBooleanValue;
+ if (!fMarkOccurrenceAnnotations)
+ uninstallOccurrencesFinder();
+ else
+ installOccurrencesFinder();
+ }
+ return;
+ }
+
+ if (PreferenceConstants.EDITOR_STICKY_OCCURRENCES.equals(property)) {
+ fStickyOccurrenceAnnotations = newBooleanValue;
+ return;
+ }
+ // }
+ // }
+ // if
+ // (PreferenceConstants.EDITOR_STICKY_OCCURRENCES.equals(property))
+ // {
+ // if (event.getNewValue() instanceof Boolean) {
+ // boolean stickyOccurrenceAnnotations=
+ // ((Boolean)event.getNewValue()).booleanValue();
+ // if (stickyOccurrenceAnnotations != fStickyOccurrenceAnnotations)
+ // {
+
+ ((PHPSourceViewerConfiguration) getSourceViewerConfiguration())
+ .handlePropertyChangeEvent(event);
+
+ // if (affectsOverrideIndicatorAnnotations(event)) {
+ // if (isShowingOverrideIndicators()) {
+ // if (fOverrideIndicatorManager == null)
+ // installOverrideIndicator(true);
+ // } else {
+ // if (fOverrideIndicatorManager != null)
+ // uninstallOverrideIndicator();
+ // }
+ // return;
+ // }
+
+ if (PreferenceConstants.EDITOR_FOLDING_PROVIDER.equals(property)) {
+ if (sourceViewer instanceof ProjectionViewer) {
+ ProjectionViewer projectionViewer = (ProjectionViewer) sourceViewer;
+ if (fProjectionModelUpdater != null)
+ fProjectionModelUpdater.uninstall();
+ // either freshly enabled or provider changed
+ fProjectionModelUpdater = PHPeclipsePlugin.getDefault()
+ .getFoldingStructureProviderRegistry()
+ .getCurrentFoldingProvider();
+ if (fProjectionModelUpdater != null) {
+ fProjectionModelUpdater.install(this, projectionViewer);
+ }
+ }
+ return;
+ }
+ } finally {
+ super.handlePreferenceStoreChanged(event);
+ }
+ }
+
+ // /*
+ // * @see
+ // AbstractTextEditor#handlePreferenceStoreChanged(PropertyChangeEvent)
+ // */
+ // protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
+ //
+ // try {
+ //
+ // ISourceViewer sourceViewer = getSourceViewer();
+ // if (sourceViewer == null)
+ // return;
+ //
+ // String property = event.getProperty();
+ //
+ // // if
+ // (JavaSourceViewerConfiguration.PREFERENCE_TAB_WIDTH.equals(property)) {
+ // // Object value= event.getNewValue();
+ // // if (value instanceof Integer) {
+ // // sourceViewer.getTextWidget().setTabs(((Integer) value).intValue());
+ // // } else if (value instanceof String) {
+ // // sourceViewer.getTextWidget().setTabs(Integer.parseInt((String)
+ // value));
+ // // }
+ // // return;
+ // // }
+ //
+ // if (IPreferenceConstants.LINE_NUMBER_RULER.equals(property)) {
+ // if (isLineNumberRulerVisible())
+ // showLineNumberRuler();
+ // else
+ // hideLineNumberRuler();
+ // return;
+ // }
+ //
+ // if (fLineNumberRulerColumn != null
+ // && (IPreferenceConstants.LINE_NUMBER_COLOR.equals(property)
+ // || PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT.equals(property)
+ // || PREFERENCE_COLOR_BACKGROUND.equals(property))) {
+ //
+ // initializeLineNumberRulerColumn(fLineNumberRulerColumn);
+ // }
+ //
+ // } finally {
+ // super.handlePreferenceStoreChanged(event);
+ // }
+ // }
+
+ // private boolean isJavaEditorHoverProperty(String property) {
+ // return PreferenceConstants.EDITOR_DEFAULT_HOVER.equals(property)
+ // || PreferenceConstants.EDITOR_NONE_HOVER.equals(property)
+ // || PreferenceConstants.EDITOR_CTRL_HOVER.equals(property)
+ // || PreferenceConstants.EDITOR_SHIFT_HOVER.equals(property)
+ // || PreferenceConstants.EDITOR_CTRL_ALT_HOVER.equals(property)
+ // || PreferenceConstants.EDITOR_CTRL_SHIFT_HOVER.equals(property)
+ // || PreferenceConstants.EDITOR_CTRL_ALT_SHIFT_HOVER.equals(property)
+ // || PreferenceConstants.EDITOR_ALT_SHIFT_HOVER.equals(property);
+ // }
+
+ /**
+ * Shows the line number ruler column.
+ */
+ // private void showLineNumberRuler() {
+ // IVerticalRuler v = getVerticalRuler();
+ // if (v instanceof CompositeRuler) {
+ // CompositeRuler c = (CompositeRuler) v;
+ // c.addDecorator(1, createLineNumberRulerColumn());
+ // }
+ // }
+ private boolean isJavaEditorHoverProperty(String property) {
+ return PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS.equals(property);
+ }
+
+ /**
+ * Return whether the browser like links should be enabled according to the
+ * preference store settings.
+ *
+ * @return <code>true</code> if the browser like links should be enabled
+ */
+ private boolean isBrowserLikeLinks() {
+ IPreferenceStore store = getPreferenceStore();
+ return store.getBoolean(BROWSER_LIKE_LINKS);
+ }
+
+ /**
+ * Enables browser like links.
+ */
+ private void enableBrowserLikeLinks() {
+ if (fMouseListener == null) {
+ fMouseListener = new MouseClickListener();
+ fMouseListener.install();
+ }
+ }
+
+ /**
+ * Disables browser like links.
+ */
+ private void disableBrowserLikeLinks() {
+ if (fMouseListener != null) {
+ fMouseListener.uninstall();
+ fMouseListener = null;
+ }
+ }
+
+ /**
+ * Handles a property change event describing a change of the java core's
+ * preferences and updates the preference related editor properties.
+ *
+ * @param event
+ * the property change event
+ */
+ protected void handlePreferencePropertyChanged(
+ org.eclipse.core.runtime.Preferences.PropertyChangeEvent event) {
+ if (COMPILER_TASK_TAGS.equals(event.getProperty())) {
+ ISourceViewer sourceViewer = getSourceViewer();
+ if (sourceViewer != null
+ && affectsTextPresentation(new PropertyChangeEvent(event
+ .getSource(), event.getProperty(), event
+ .getOldValue(), event.getNewValue())))
+ sourceViewer.invalidateTextPresentation();
+ }
+ if (PreferenceConstants.EDITOR_WRAP_WORDS.equals(event.getProperty())) {
+ setWordWrap();
+ }
+ }
+
+ /**
+ * Return whether the line number ruler column should be visible according
+ * to the preference store settings.
+ *
+ * @return <code>true</code> if the line numbers should be visible
+ */
+ // protected boolean isLineNumberRulerVisible() {
+ // IPreferenceStore store = getPreferenceStore();
+ // return store.getBoolean(LINE_NUMBER_RULER);
+ // }
+ /**
+ * Hides the line number ruler column.
+ */
+ // private void hideLineNumberRuler() {
+ // IVerticalRuler v = getVerticalRuler();
+ // if (v instanceof CompositeRuler) {
+ // CompositeRuler c = (CompositeRuler) v;
+ // try {
+ // c.removeDecorator(1);
+ // } catch (Throwable e) {
+ // }
+ // }
+ // }
+ /*
+ * @see AbstractTextEditor#handleCursorPositionChanged()
+ */
+ // protected void handleCursorPositionChanged() {
+ // super.handleCursorPositionChanged();
+ // if (!isEditingScriptRunning() && fUpdater != null)
+ // fUpdater.post();
+ // }
+ /*
+ * @see org.eclipse.ui.texteditor.AbstractTextEditor#handleElementContentReplaced()
+ */
+ protected void handleElementContentReplaced() {
+ super.handleElementContentReplaced();
+ if (fProjectionModelUpdater != null)
+ fProjectionModelUpdater.initialize();
+ }
+
+ /**
+ * Initializes the given line number ruler column from the preference store.
+ *
+ * @param rulerColumn
+ * the ruler column to be initialized
+ */
+ // protected void initializeLineNumberRulerColumn(LineNumberRulerColumn
+ // rulerColumn) {
+ // JavaTextTools textTools =
+ // PHPeclipsePlugin.getDefault().getJavaTextTools();
+ // IColorManager manager = textTools.getColorManager();
+ //
+ // IPreferenceStore store = getPreferenceStore();
+ // if (store != null) {
+ //
+ // RGB rgb = null;
+ // // foreground color
+ // if (store.contains(LINE_NUMBER_COLOR)) {
+ // if (store.isDefault(LINE_NUMBER_COLOR))
+ // rgb = PreferenceConverter.getDefaultColor(store, LINE_NUMBER_COLOR);
+ // else
+ // rgb = PreferenceConverter.getColor(store, LINE_NUMBER_COLOR);
+ // }
+ // rulerColumn.setForeground(manager.getColor(rgb));
+ //
+ // rgb = null;
+ // // background color
+ // if (!store.getBoolean(PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT)) {
+ // if (store.contains(PREFERENCE_COLOR_BACKGROUND)) {
+ // if (store.isDefault(PREFERENCE_COLOR_BACKGROUND))
+ // rgb = PreferenceConverter.getDefaultColor(store,
+ // PREFERENCE_COLOR_BACKGROUND);
+ // else
+ // rgb = PreferenceConverter.getColor(store, PREFERENCE_COLOR_BACKGROUND);
+ // }
+ // }
+ // rulerColumn.setBackground(manager.getColor(rgb));
+ // }
+ // }
+ /**
+ * Creates a new line number ruler column that is appropriately initialized.
+ */
+ // protected IVerticalRulerColumn createLineNumberRulerColumn() {
+ // fLineNumberRulerColumn = new LineNumberRulerColumn();
+ // initializeLineNumberRulerColumn(fLineNumberRulerColumn);
+ // return fLineNumberRulerColumn;
+ // }
+ /*
+ * @see AbstractTextEditor#createVerticalRuler()
+ */
+ // protected IVerticalRuler createVerticalRuler() {
+ // CompositeRuler ruler = new CompositeRuler();
+ // ruler.addDecorator(0, new AnnotationRulerColumn(VERTICAL_RULER_WIDTH));
+ // if (isLineNumberRulerVisible())
+ // ruler.addDecorator(1, createLineNumberRulerColumn());
+ // return ruler;
+ // }
+ // private static IRegion getSignedSelection(ITextViewer viewer) {
+ //
+ // StyledText text = viewer.getTextWidget();
+ // int caretOffset = text.getCaretOffset();
+ // Point selection = text.getSelection();
+ //
+ // // caret left
+ // int offset, length;
+ // if (caretOffset == selection.x) {
+ // offset = selection.y;
+ // length = selection.x - selection.y;
+ //
+ // // caret right
+ // } else {
+ // offset = selection.x;
+ // length = selection.y - selection.x;
+ // }
+ //
+ // return new Region(offset, length);
+ // }
+ protected IRegion getSignedSelection(ISourceViewer sourceViewer) {
+ StyledText text = sourceViewer.getTextWidget();
+ Point selection = text.getSelectionRange();
+
+ if (text.getCaretOffset() == selection.x) {
+ selection.x = selection.x + selection.y;
+ selection.y = -selection.y;
+ }
+
+ selection.x = widgetOffset2ModelOffset(sourceViewer, selection.x);
+
+ return new Region(selection.x, selection.y);
+ }
+
+ /** Preference key for matching brackets */
+ protected final static String MATCHING_BRACKETS = PreferenceConstants.EDITOR_MATCHING_BRACKETS;
+
+ /** Preference key for matching brackets color */
+ protected final static String MATCHING_BRACKETS_COLOR = PreferenceConstants.EDITOR_MATCHING_BRACKETS_COLOR;
+
+ /** Preference key for highlighting current line */
+ // protected final static String CURRENT_LINE =
+ // PreferenceConstants.EDITOR_CURRENT_LINE;
+ /** Preference key for highlight color of current line */
+ // protected final static String CURRENT_LINE_COLOR =
+ // PreferenceConstants.EDITOR_CURRENT_LINE_COLOR;
+ /** Preference key for showing print marging ruler */
+ // protected final static String PRINT_MARGIN =
+ // PreferenceConstants.EDITOR_PRINT_MARGIN;
+ /** Preference key for print margin ruler color */
+ // protected final static String PRINT_MARGIN_COLOR =
+ // PreferenceConstants.EDITOR_PRINT_MARGIN_COLOR;
+ /** Preference key for print margin ruler column */
+ // protected final static String PRINT_MARGIN_COLUMN =
+ // PreferenceConstants.EDITOR_PRINT_MARGIN_COLUMN;
+ /** Preference key for error indication */
+ // protected final static String ERROR_INDICATION =
+ // PreferenceConstants.EDITOR_PROBLEM_INDICATION;
+ /** Preference key for error color */
+ // protected final static String ERROR_INDICATION_COLOR =
+ // PreferenceConstants.EDITOR_PROBLEM_INDICATION_COLOR;
+ /** Preference key for warning indication */
+ // protected final static String WARNING_INDICATION =
+ // PreferenceConstants.EDITOR_WARNING_INDICATION;
+ /** Preference key for warning color */
+ // protected final static String WARNING_INDICATION_COLOR =
+ // PreferenceConstants.EDITOR_WARNING_INDICATION_COLOR;
+ /** Preference key for task indication */
+ protected final static String TASK_INDICATION = PreferenceConstants.EDITOR_TASK_INDICATION;
+
+ /** Preference key for task color */
+ protected final static String TASK_INDICATION_COLOR = PreferenceConstants.EDITOR_TASK_INDICATION_COLOR;
+
+ /** Preference key for bookmark indication */
+ protected final static String BOOKMARK_INDICATION = PreferenceConstants.EDITOR_BOOKMARK_INDICATION;
+
+ /** Preference key for bookmark color */
+ protected final static String BOOKMARK_INDICATION_COLOR = PreferenceConstants.EDITOR_BOOKMARK_INDICATION_COLOR;
+
+ /** Preference key for search result indication */
+ protected final static String SEARCH_RESULT_INDICATION = PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION;
+
+ /** Preference key for search result color */
+ protected final static String SEARCH_RESULT_INDICATION_COLOR = PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION_COLOR;
+
+ /** Preference key for unknown annotation indication */
+ protected final static String UNKNOWN_INDICATION = PreferenceConstants.EDITOR_UNKNOWN_INDICATION;
+
+ /** Preference key for unknown annotation color */
+ protected final static String UNKNOWN_INDICATION_COLOR = PreferenceConstants.EDITOR_UNKNOWN_INDICATION_COLOR;
+
+ /** Preference key for shwoing the overview ruler */
+ protected final static String OVERVIEW_RULER = PreferenceConstants.EDITOR_OVERVIEW_RULER;
+
+ /** Preference key for error indication in overview ruler */
+ protected final static String ERROR_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_ERROR_INDICATION_IN_OVERVIEW_RULER;
+
+ /** Preference key for warning indication in overview ruler */
+ protected final static String WARNING_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_WARNING_INDICATION_IN_OVERVIEW_RULER;
+
+ /** Preference key for task indication in overview ruler */
+ protected final static String TASK_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_TASK_INDICATION_IN_OVERVIEW_RULER;
+
+ /** Preference key for bookmark indication in overview ruler */
+ protected final static String BOOKMARK_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_BOOKMARK_INDICATION_IN_OVERVIEW_RULER;
+
+ /** Preference key for search result indication in overview ruler */
+ protected final static String SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER;
+
+ /** Preference key for unknown annotation indication in overview ruler */
+ protected final static String UNKNOWN_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_UNKNOWN_INDICATION_IN_OVERVIEW_RULER;
+
+ // /** Preference key for compiler task tags */
+ // private final static String COMPILER_TASK_TAGS=
+ // JavaCore.COMPILER_TASK_TAGS;
+ /** Preference key for browser like links */
+ private final static String BROWSER_LIKE_LINKS = PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS;
+
+ /** Preference key for key modifier of browser like links */
+ private final static String BROWSER_LIKE_LINKS_KEY_MODIFIER = PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER;
+
+ /**
+ * Preference key for key modifier mask of browser like links. The value is
+ * only used if the value of <code>EDITOR_BROWSER_LIKE_LINKS</code> cannot
+ * be resolved to valid SWT modifier bits.
+ *
+ * @since 2.1.1
+ */
+ private final static String BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK = PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK;
+
+ private final static char[] BRACKETS = { '{', '}', '(', ')', '[', ']' };
+
+ private static boolean isBracket(char character) {
+ for (int i = 0; i != BRACKETS.length; ++i)
+ if (character == BRACKETS[i])
+ return true;
+ return false;
+ }
+
+ private static boolean isSurroundedByBrackets(IDocument document, int offset) {
+ if (offset == 0 || offset == document.getLength())
+ return false;
+
+ try {
+ return isBracket(document.getChar(offset - 1))
+ && isBracket(document.getChar(offset));
+
+ } catch (BadLocationException e) {
+ return false;
+ }
+ }
+
+ // protected void configureSourceViewerDecorationSupport() {
+ //
+ // fSourceViewerDecorationSupport.setCharacterPairMatcher(fBracketMatcher);
+ //
+ // fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys(
+ // AnnotationType.UNKNOWN,
+ // UNKNOWN_INDICATION_COLOR,
+ // UNKNOWN_INDICATION,
+ // UNKNOWN_INDICATION_IN_OVERVIEW_RULER,
+ // 0);
+ // fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys(
+ // AnnotationType.BOOKMARK,
+ // BOOKMARK_INDICATION_COLOR,
+ // BOOKMARK_INDICATION,
+ // BOOKMARK_INDICATION_IN_OVERVIEW_RULER,
+ // 1);
+ // fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys(
+ // AnnotationType.TASK,
+ // TASK_INDICATION_COLOR,
+ // TASK_INDICATION,
+ // TASK_INDICATION_IN_OVERVIEW_RULER,
+ // 2);
+ // fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys(
+ // AnnotationType.SEARCH,
+ // SEARCH_RESULT_INDICATION_COLOR,
+ // SEARCH_RESULT_INDICATION,
+ // SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER,
+ // 3);
+ // fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys(
+ // AnnotationType.WARNING,
+ // WARNING_INDICATION_COLOR,
+ // WARNING_INDICATION,
+ // WARNING_INDICATION_IN_OVERVIEW_RULER,
+ // 4);
+ // fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys(
+ // AnnotationType.ERROR,
+ // ERROR_INDICATION_COLOR,
+ // ERROR_INDICATION,
+ // ERROR_INDICATION_IN_OVERVIEW_RULER,
+ // 5);
+ //
+ // fSourceViewerDecorationSupport.setCursorLinePainterPreferenceKeys(CURRENT_LINE,
+ // CURRENT_LINE_COLOR);
+ // fSourceViewerDecorationSupport.setMarginPainterPreferenceKeys(PRINT_MARGIN,
+ // PRINT_MARGIN_COLOR, PRINT_MARGIN_COLUMN);
+ // fSourceViewerDecorationSupport.setMatchingCharacterPainterPreferenceKeys(MATCHING_BRACKETS,
+ // MATCHING_BRACKETS_COLOR);
+ //
+ // fSourceViewerDecorationSupport.setSymbolicFontName(getFontPropertyPreferenceKey());
+ //
+ // }
+ /**
+ * Returns the Java element wrapped by this editors input.
+ *
+ * @return the Java element wrapped by this editors input.
+ * @since 3.0
+ */
+ abstract protected IJavaElement getInputJavaElement();
+
+ protected void updateStatusLine() {
+ ITextSelection selection = (ITextSelection) getSelectionProvider()
+ .getSelection();
+ Annotation annotation = getAnnotation(selection.getOffset(), selection
+ .getLength());
+ setStatusLineErrorMessage(null);
+ setStatusLineMessage(null);
+ if (annotation != null) {
+ try {
+ fIsUpdatingAnnotationViews = true;
+ updateAnnotationViews(annotation);
+ } finally {
+ fIsUpdatingAnnotationViews = false;
+ }
+ if (annotation instanceof IJavaAnnotation
+ && ((IJavaAnnotation) annotation).isProblem())
+ setStatusLineMessage(annotation.getText());
+ }
+ }
+
+ /**
+ * Jumps to the matching bracket.
+ */
+ public void gotoMatchingBracket() {
+
+ ISourceViewer sourceViewer = getSourceViewer();
+ IDocument document = sourceViewer.getDocument();
+ if (document == null)
+ return;
+
+ IRegion selection = getSignedSelection(sourceViewer);
+
+ int selectionLength = Math.abs(selection.getLength());
+ if (selectionLength > 1) {
+ setStatusLineErrorMessage(PHPEditorMessages
+ .getString("GotoMatchingBracket.error.invalidSelection")); //$NON-NLS-1$
+ sourceViewer.getTextWidget().getDisplay().beep();
+ return;
+ }
+
+ // #26314
+ int sourceCaretOffset = selection.getOffset() + selection.getLength();
+ if (isSurroundedByBrackets(document, sourceCaretOffset))
+ sourceCaretOffset -= selection.getLength();
+
+ IRegion region = fBracketMatcher.match(document, sourceCaretOffset);
+ if (region == null) {
+ setStatusLineErrorMessage(PHPEditorMessages
+ .getString("GotoMatchingBracket.error.noMatchingBracket")); //$NON-NLS-1$
+ sourceViewer.getTextWidget().getDisplay().beep();
+ return;
+ }
+
+ int offset = region.getOffset();
+ int length = region.getLength();
+
+ if (length < 1)
+ return;
+
+ int anchor = fBracketMatcher.getAnchor();
+ int targetOffset = (PHPPairMatcher.RIGHT == anchor) ? offset : offset
+ + length - 1;
+
+ boolean visible = false;
+ if (sourceViewer instanceof ITextViewerExtension5) {
+ ITextViewerExtension5 extension = (ITextViewerExtension5) sourceViewer;
+ visible = (extension.modelOffset2WidgetOffset(targetOffset) > -1);
+ } else {
+ IRegion visibleRegion = sourceViewer.getVisibleRegion();
+ visible = (targetOffset >= visibleRegion.getOffset() && targetOffset < visibleRegion
+ .getOffset()
+ + visibleRegion.getLength());
+ }
+
+ if (!visible) {
+ setStatusLineErrorMessage(PHPEditorMessages
+ .getString("GotoMatchingBracket.error.bracketOutsideSelectedElement")); //$NON-NLS-1$
+ sourceViewer.getTextWidget().getDisplay().beep();
+ return;
+ }
+
+ if (selection.getLength() < 0)
+ targetOffset -= selection.getLength();
+
+ sourceViewer.setSelectedRange(targetOffset, selection.getLength());
+ sourceViewer.revealRange(targetOffset, selection.getLength());
+ }
+
+ /**
+ * Ses the given message as error message to this editor's status line.
+ *
+ * @param msg
+ * message to be set
+ */
+ protected void setStatusLineErrorMessage(String msg) {
+ IEditorStatusLine statusLine = (IEditorStatusLine) getAdapter(IEditorStatusLine.class);
+ if (statusLine != null)
+ statusLine.setMessage(true, msg, null);
+ }
+
+ /**
+ * Sets the given message as message to this editor's status line.
+ *
+ * @param msg
+ * message to be set
+ * @since 3.0
+ */
+ protected void setStatusLineMessage(String msg) {
+ IEditorStatusLine statusLine = (IEditorStatusLine) getAdapter(IEditorStatusLine.class);
+ if (statusLine != null)
+ statusLine.setMessage(false, msg, null);
+ }
+
+ /**
+ * Returns the annotation closest to the given range respecting the given
+ * direction. If an annotation is found, the annotations current position is
+ * copied into the provided annotation position.
+ *
+ * @param offset
+ * the region offset
+ * @param length
+ * the region length
+ * @param forward
+ * <code>true</code> for forwards, <code>false</code> for
+ * backward
+ * @param annotationPosition
+ * the position of the found annotation
+ * @return the found annotation
+ */
+ private Annotation getNextAnnotation(final int offset, final int length,
+ boolean forward, Position annotationPosition) {
+
+ Annotation nextAnnotation = null;
+ Position nextAnnotationPosition = null;
+ Annotation containingAnnotation = null;
+ Position containingAnnotationPosition = null;
+ boolean currentAnnotation = false;
+
+ IDocument document = getDocumentProvider()
+ .getDocument(getEditorInput());
+ int endOfDocument = document.getLength();
+ int distance = Integer.MAX_VALUE;
+
+ IAnnotationModel model = getDocumentProvider().getAnnotationModel(
+ getEditorInput());
+ Iterator e = new JavaAnnotationIterator(model, true, true);
+ while (e.hasNext()) {
+ Annotation a = (Annotation) e.next();
+ if ((a instanceof IJavaAnnotation)
+ && ((IJavaAnnotation) a).hasOverlay()
+ || !isNavigationTarget(a))
+ continue;
+
+ Position p = model.getPosition(a);
+ if (p == null)
+ continue;
+
+ if (forward && p.offset == offset || !forward
+ && p.offset + p.getLength() == offset + length) {// ||
+ // p.includes(offset))
+ // {
+ if (containingAnnotation == null
+ || (forward
+ && p.length >= containingAnnotationPosition.length || !forward
+ && p.length >= containingAnnotationPosition.length)) {
+ containingAnnotation = a;
+ containingAnnotationPosition = p;
+ currentAnnotation = p.length == length;
+ }
+ } else {
+ int currentDistance = 0;
+
+ if (forward) {
+ currentDistance = p.getOffset() - offset;
+ if (currentDistance < 0)
+ currentDistance = endOfDocument + currentDistance;
+
+ if (currentDistance < distance
+ || currentDistance == distance
+ && p.length < nextAnnotationPosition.length) {
+ distance = currentDistance;
+ nextAnnotation = a;
+ nextAnnotationPosition = p;
+ }
+ } else {
+ currentDistance = offset + length
+ - (p.getOffset() + p.length);
+ if (currentDistance < 0)
+ currentDistance = endOfDocument + currentDistance;
+
+ if (currentDistance < distance
+ || currentDistance == distance
+ && p.length < nextAnnotationPosition.length) {
+ distance = currentDistance;
+ nextAnnotation = a;
+ nextAnnotationPosition = p;
+ }
+ }
+ }
+ }
+ if (containingAnnotationPosition != null
+ && (!currentAnnotation || nextAnnotation == null)) {
+ annotationPosition.setOffset(containingAnnotationPosition
+ .getOffset());
+ annotationPosition.setLength(containingAnnotationPosition
+ .getLength());
+ return containingAnnotation;
+ }
+ if (nextAnnotationPosition != null) {
+ annotationPosition.setOffset(nextAnnotationPosition.getOffset());
+ annotationPosition.setLength(nextAnnotationPosition.getLength());
+ }
+
+ return nextAnnotation;
+ }
+
+ /**
+ * Returns the annotation overlapping with the given range or
+ * <code>null</code>.
+ *
+ * @param offset
+ * the region offset
+ * @param length
+ * the region length
+ * @return the found annotation or <code>null</code>
+ * @since 3.0
+ */
+ private Annotation getAnnotation(int offset, int length) {
+ IAnnotationModel model = getDocumentProvider().getAnnotationModel(
+ getEditorInput());
+ Iterator e = new JavaAnnotationIterator(model, true, true);
+ while (e.hasNext()) {
+ Annotation a = (Annotation) e.next();
+ if (!isNavigationTarget(a))
+ continue;
+
+ Position p = model.getPosition(a);
+ if (p != null && p.overlapsWith(offset, length))
+ return a;
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns whether the given annotation is configured as a target for the
+ * "Go to Next/Previous Annotation" actions
+ *
+ * @param annotation
+ * the annotation
+ * @return <code>true</code> if this is a target, <code>false</code>
+ * otherwise
+ * @since 3.0
+ */
+ protected boolean isNavigationTarget(Annotation annotation) {
+ Preferences preferences = EditorsUI.getPluginPreferences();
+ AnnotationPreference preference = getAnnotationPreferenceLookup()
+ .getAnnotationPreference(annotation);
+ // See bug 41689
+ // String key= forward ? preference.getIsGoToNextNavigationTargetKey() :
+ // preference.getIsGoToPreviousNavigationTargetKey();
+ String key = preference == null ? null : preference
+ .getIsGoToNextNavigationTargetKey();
+ return (key != null && preferences.getBoolean(key));
+ }
+
+ /**
+ * Returns a segmentation of the line of the given document appropriate for
+ * bidi rendering. The default implementation returns only the string
+ * literals of a php code line as segments.
+ *
+ * @param document
+ * the document
+ * @param lineOffset
+ * the offset of the line
+ * @return the line's bidi segmentation
+ * @throws BadLocationException
+ * in case lineOffset is not valid in document
+ */
+ public static int[] getBidiLineSegments(IDocument document, int lineOffset)
+ throws BadLocationException {
+
+ IRegion line = document.getLineInformationOfOffset(lineOffset);
+ ITypedRegion[] linePartitioning = document.computePartitioning(
+ lineOffset, line.getLength());
+
+ List segmentation = new ArrayList();
+ for (int i = 0; i < linePartitioning.length; i++) {
+ if (IPHPPartitions.PHP_STRING_DQ.equals(linePartitioning[i]
+ .getType())) {
+ segmentation.add(linePartitioning[i]);
+ } else if (IPHPPartitions.PHP_STRING_HEREDOC
+ .equals(linePartitioning[i].getType())) {
+ segmentation.add(linePartitioning[i]);
+ }
+ }
+
+ if (segmentation.size() == 0)
+ return null;
+
+ int size = segmentation.size();
+ int[] segments = new int[size * 2 + 1];
+
+ int j = 0;
+ for (int i = 0; i < size; i++) {
+ ITypedRegion segment = (ITypedRegion) segmentation.get(i);
+
+ if (i == 0)
+ segments[j++] = 0;
+
+ int offset = segment.getOffset() - lineOffset;
+ if (offset > segments[j - 1])
+ segments[j++] = offset;
+
+ if (offset + segment.getLength() >= line.getLength())
+ break;
+
+ segments[j++] = offset + segment.getLength();
+ }
+
+ if (j < segments.length) {
+ int[] result = new int[j];
+ System.arraycopy(segments, 0, result, 0, j);
+ segments = result;
+ }
+
+ return segments;
+ }
+
+ /**
+ * Returns a segmentation of the given line appropriate for bidi rendering.
+ * The default implementation returns only the string literals of a php code
+ * line as segments.
+ *
+ * @param lineOffset
+ * the offset of the line
+ * @param line
+ * the content of the line
+ * @return the line's bidi segmentation
+ */
+ protected int[] getBidiLineSegments(int lineOffset, String line) {
+ IDocumentProvider provider = getDocumentProvider();
+ if (provider != null && line != null && line.length() > 0) {
+ IDocument document = provider.getDocument(getEditorInput());
+ if (document != null)
+ try {
+ return getBidiLineSegments(document, lineOffset);
+ } catch (BadLocationException x) {
+ // ignore
+ }
+ }
+ return null;
+ }
+
+ /*
+ * @see AbstractTextEditor#createSourceViewer(Composite, IVerticalRuler,
+ * int)
+ */
+ // protected final ISourceViewer createSourceViewer(
+ // Composite parent,
+ // IVerticalRuler ruler,
+ // int styles) {
+ // ISourceViewer viewer = createJavaSourceViewer(parent, ruler, styles);
+ // StyledText text = viewer.getTextWidget();
+ // text.addBidiSegmentListener(new BidiSegmentListener() {
+ // public void lineGetSegments(BidiSegmentEvent event) {
+ // event.segments = getBidiLineSegments(event.lineOffset, event.lineText);
+ // }
+ // });
+ // // JavaUIHelp.setHelp(this, text, IJavaHelpContextIds.JAVA_EDITOR);
+ // return viewer;
+ // }
+ public final ISourceViewer getViewer() {
+ return getSourceViewer();
+ }
+
+ // protected void showOverviewRuler() {
+ // if (fOverviewRuler != null) {
+ // if (getSourceViewer() instanceof ISourceViewerExtension) {
+ // ((ISourceViewerExtension)
+ // getSourceViewer()).showAnnotationsOverview(true);
+ // fSourceViewerDecorationSupport.updateOverviewDecorations();
+ // }
+ // }
+ // }
+ //
+ // protected void hideOverviewRuler() {
+ // if (getSourceViewer() instanceof ISourceViewerExtension) {
+ // fSourceViewerDecorationSupport.hideAnnotationOverview();
+ // ((ISourceViewerExtension)
+ // getSourceViewer()).showAnnotationsOverview(false);
+ // }
+ // }
+
+ // protected boolean isOverviewRulerVisible() {
+ // IPreferenceStore store = getPreferenceStore();
+ // return store.getBoolean(OVERVIEW_RULER);
+ // }
+ /*
+ * @see AbstractTextEditor#createSourceViewer(Composite, IVerticalRuler,
+ * int)
+ */
+ // protected ISourceViewer createJavaSourceViewer(
+ // Composite parent,
+ // IVerticalRuler ruler,
+ // IOverviewRuler overviewRuler,
+ // boolean isOverviewRulerVisible,
+ // int styles) {
+ // return new SourceViewer(parent, ruler, overviewRuler,
+ // isOverviewRulerVisible(), styles);
+ // }
+ /*
+ * @see AbstractTextEditor#createSourceViewer(Composite, IVerticalRuler,
+ * int)
+ */
+ protected ISourceViewer createJavaSourceViewer(Composite parent,
+ IVerticalRuler verticalRuler, IOverviewRuler overviewRuler,
+ boolean isOverviewRulerVisible, int styles, IPreferenceStore store) {
+ return new JavaSourceViewer(parent, verticalRuler, getOverviewRuler(),
+ isOverviewRulerVisible(), styles, store);
+ }
+
+ /*
+ * @see AbstractTextEditor#createSourceViewer(Composite, IVerticalRuler,
+ * int)
+ */
+ protected final ISourceViewer createSourceViewer(Composite parent,
+ IVerticalRuler verticalRuler, int styles) {
+
+ ISourceViewer viewer = createJavaSourceViewer(parent, verticalRuler,
+ getOverviewRuler(), isOverviewRulerVisible(), styles,
+ getPreferenceStore());
+
+ StyledText text = viewer.getTextWidget();
+ text.addBidiSegmentListener(new BidiSegmentListener() {
+ public void lineGetSegments(BidiSegmentEvent event) {
+ event.segments = getBidiLineSegments(event.lineOffset,
+ event.lineText);
+ }
+ });
+
+ // JavaUIHelp.setHelp(this, text, IJavaHelpContextIds.JAVA_EDITOR);
+
+ // ensure source viewer decoration support has been created and
+ // configured
+ getSourceViewerDecorationSupport(viewer);
+
+ return viewer;
+ }
+
+ /*
+ * @see AbstractTextEditor#affectsTextPresentation(PropertyChangeEvent)
+ */
+ protected boolean affectsTextPresentation(PropertyChangeEvent event) {
+ return ((PHPSourceViewerConfiguration) getSourceViewerConfiguration())
+ .affectsTextPresentation(event)
+ || super.affectsTextPresentation(event);
+ }
+
+ //
+ // protected boolean affectsTextPresentation(PropertyChangeEvent event) {
+ // JavaTextTools textTools =
+ // PHPeclipsePlugin.getDefault().getJavaTextTools();
+ // return textTools.affectsBehavior(event);
+ // }
+ /**
+ * Creates and returns the preference store for this Java editor with the
+ * given input.
+ *
+ * @param input
+ * The editor input for which to create the preference store
+ * @return the preference store for this editor
+ *
+ * @since 3.0
+ */
+ private IPreferenceStore createCombinedPreferenceStore(IEditorInput input) {
+ List stores = new ArrayList(3);
+
+ IJavaProject project = EditorUtility.getJavaProject(input);
+ if (project != null)
+ stores.add(new OptionsAdapter(project.getOptions(false),
+ PHPeclipsePlugin.getDefault().getMockupPreferenceStore(),
+ new OptionsAdapter.IPropertyChangeEventFilter() {
+
+ public boolean isFiltered(PropertyChangeEvent event) {
+ IJavaElement inputJavaElement = getInputJavaElement();
+ IJavaProject javaProject = inputJavaElement != null ? inputJavaElement
+ .getJavaProject()
+ : null;
+ if (javaProject == null)
+ return true;
+
+ return !javaProject.getProject().equals(
+ event.getSource());
+ }
+
+ }));
+
+ stores.add(PHPeclipsePlugin.getDefault().getPreferenceStore());
+ stores.add(new PreferencesAdapter(JavaCore.getPlugin()
+ .getPluginPreferences()));
+ stores.add(EditorsUI.getPreferenceStore());
+
+ return new ChainedPreferenceStore((IPreferenceStore[]) stores
+ .toArray(new IPreferenceStore[stores.size()]));
+ }
+
+ /**
+ * Jumps to the error next according to the given direction.
+ */
+ public void gotoError(boolean forward) {
+
+ ISelectionProvider provider = getSelectionProvider();
+
+ ITextSelection s = (ITextSelection) provider.getSelection();
+ Position errorPosition = new Position(0, 0);
+ IJavaAnnotation nextError = getNextError(s.getOffset(), forward,
+ errorPosition);
+
+ if (nextError != null) {
+
+ IMarker marker = null;
+ if (nextError instanceof MarkerAnnotation)
+ marker = ((MarkerAnnotation) nextError).getMarker();
+ else {
+ Iterator e = nextError.getOverlaidIterator();
+ if (e != null) {
+ while (e.hasNext()) {
+ Object o = e.next();
+ if (o instanceof MarkerAnnotation) {
+ marker = ((MarkerAnnotation) o).getMarker();
+ break;
+ }
+ }
+ }
+ }
+
+ if (marker != null) {
+ IWorkbenchPage page = getSite().getPage();
+ IViewPart view = view = page
+ .findView("org.eclipse.ui.views.TaskList"); //$NON-NLS-1$
+ if (view instanceof TaskList) {
+ StructuredSelection ss = new StructuredSelection(marker);
+ ((TaskList) view).setSelection(ss, true);
+ }
+ }
+
+ selectAndReveal(errorPosition.getOffset(), errorPosition
+ .getLength());
+ // setStatusLineErrorMessage(nextError.getMessage());
+
+ } else {
+
+ setStatusLineErrorMessage(null);
+
+ }
+ }
+
+ private IJavaAnnotation getNextError(int offset, boolean forward,
+ Position errorPosition) {
+
+ IJavaAnnotation nextError = null;
+ Position nextErrorPosition = null;
+
+ IDocument document = getDocumentProvider()
+ .getDocument(getEditorInput());
+ int endOfDocument = document.getLength();
+ int distance = 0;
+
+ IAnnotationModel model = getDocumentProvider().getAnnotationModel(
+ getEditorInput());
+ Iterator e = new JavaAnnotationIterator(model, false);
+ while (e.hasNext()) {
+
+ IJavaAnnotation a = (IJavaAnnotation) e.next();
+ if (a.hasOverlay() || !a.isProblem())
+ continue;
+
+ Position p = model.getPosition((Annotation) a);
+ if (!p.includes(offset)) {
+
+ int currentDistance = 0;
+
+ if (forward) {
+ currentDistance = p.getOffset() - offset;
+ if (currentDistance < 0)
+ currentDistance = endOfDocument - offset
+ + p.getOffset();
+ } else {
+ currentDistance = offset - p.getOffset();
+ if (currentDistance < 0)
+ currentDistance = offset + endOfDocument
+ - p.getOffset();
+ }
+
+ if (nextError == null || currentDistance < distance) {
+ distance = currentDistance;
+ nextError = a;
+ nextErrorPosition = p;
+ }
+ }
+ }
+
+ if (nextErrorPosition != null) {
+ errorPosition.setOffset(nextErrorPosition.getOffset());
+ errorPosition.setLength(nextErrorPosition.getLength());
+ }
+
+ return nextError;
+ }
+
+ protected void uninstallOverrideIndicator() {
+ // if (fOverrideIndicatorManager != null) {
+ // fOverrideIndicatorManager.removeAnnotations();
+ // fOverrideIndicatorManager= null;
+ // }
+ }
+
+ protected void installOverrideIndicator(boolean waitForReconcilation) {
+ uninstallOverrideIndicator();
+ IAnnotationModel model = getDocumentProvider().getAnnotationModel(
+ getEditorInput());
+ final IJavaElement inputElement = getInputJavaElement();
+
+ if (model == null || inputElement == null)
+ return;
+
+ // fOverrideIndicatorManager= new OverrideIndicatorManager(model,
+ // inputElement, null);
+ //
+ // if (provideAST) {
+ // Job job= new
+ // Job(JavaEditorMessages.getString("OverrideIndicatorManager.intallJob"))
+ // {
+ // //$NON-NLS-1$
+ // /*
+ // * @see
+ // org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
+ // * @since 3.0
+ // */
+ // protected IStatus run(IProgressMonitor monitor) {
+ // CompilationUnit ast=
+ // JavaPlugin.getDefault().getASTProvider().getAST(inputElement, true,
+ // null);
+ // if (fOverrideIndicatorManager != null) // editor might have been
+ // closed
+ // in the meanwhile
+ // fOverrideIndicatorManager.reconciled(ast, true, monitor);
+ // return Status.OK_STATUS;
+ // }
+ // };
+ // job.setPriority(Job.DECORATE);
+ // job.setSystem(true);
+ // job.schedule();
+ // }
+ }
+
+ /**
+ * Tells whether override indicators are shown.
+ *
+ * @return <code>true</code> if the override indicators are shown
+ * @since 3.0
+ */
+ // protected boolean isShowingOverrideIndicators() {
+ // AnnotationPreference preference=
+ // getAnnotationPreferenceLookup().getAnnotationPreference(OverrideIndicatorManager.ANNOTATION_TYPE);
+ // IPreferenceStore store= getPreferenceStore();
+ // return getBoolean(store, preference.getHighlightPreferenceKey())
+ // || getBoolean(store, preference.getVerticalRulerPreferenceKey())
+ // || getBoolean(store, preference.getOverviewRulerPreferenceKey())
+ // || getBoolean(store, preference.getTextPreferenceKey());
+ // }
+ /**
+ * Returns the boolean preference for the given key.
+ *
+ * @param store
+ * the preference store
+ * @param key
+ * the preference key
+ * @return <code>true</code> if the key exists in the store and its value
+ * is <code>true</code>
+ * @since 3.0
+ */
+ private boolean getBoolean(IPreferenceStore store, String key) {
+ return key != null && store.getBoolean(key);
+ }
+
+ protected boolean isPrefQuickDiffAlwaysOn() {
+ return false; // never show change ruler for the non-editable java
+ // editor.
+ // Overridden in subclasses like PHPUnitEditor
+ }
+
+ /*
+ * @see org.eclipse.ui.texteditor.AbstractTextEditor#createNavigationActions()
+ */
+ protected void createNavigationActions() {
+ super.createNavigationActions();
+
+ final StyledText textWidget = getSourceViewer().getTextWidget();
+
+ IAction action = new SmartLineStartAction(textWidget, false);
+ action.setActionDefinitionId(ITextEditorActionDefinitionIds.LINE_START);
+ setAction(ITextEditorActionDefinitionIds.LINE_START, action);
+
+ action = new SmartLineStartAction(textWidget, true);
+ action
+ .setActionDefinitionId(ITextEditorActionDefinitionIds.SELECT_LINE_START);
+ setAction(ITextEditorActionDefinitionIds.SELECT_LINE_START, action);
+
+ action = new NavigatePreviousSubWordAction();
+ action
+ .setActionDefinitionId(ITextEditorActionDefinitionIds.WORD_PREVIOUS);
+ setAction(ITextEditorActionDefinitionIds.WORD_PREVIOUS, action);
+ textWidget.setKeyBinding(SWT.CTRL | SWT.ARROW_LEFT, SWT.NULL);
+
+ action = new NavigateNextSubWordAction();
+ action.setActionDefinitionId(ITextEditorActionDefinitionIds.WORD_NEXT);
+ setAction(ITextEditorActionDefinitionIds.WORD_NEXT, action);
+ textWidget.setKeyBinding(SWT.CTRL | SWT.ARROW_RIGHT, SWT.NULL);
+
+ action = new SelectPreviousSubWordAction();
+ action
+ .setActionDefinitionId(ITextEditorActionDefinitionIds.SELECT_WORD_PREVIOUS);
+ setAction(ITextEditorActionDefinitionIds.SELECT_WORD_PREVIOUS, action);
+ textWidget.setKeyBinding(SWT.CTRL | SWT.SHIFT | SWT.ARROW_LEFT,
+ SWT.NULL);
+
+ action = new SelectNextSubWordAction();
+ action
+ .setActionDefinitionId(ITextEditorActionDefinitionIds.SELECT_WORD_NEXT);
+ setAction(ITextEditorActionDefinitionIds.SELECT_WORD_NEXT, action);
+ textWidget.setKeyBinding(SWT.CTRL | SWT.SHIFT | SWT.ARROW_RIGHT,
+ SWT.NULL);
+ }
+
+ /*
+ * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#createCompositeRuler()
+ */
+ // protected CompositeRuler createCompositeRuler() {
+ // if
+ // (!getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_ANNOTATION_ROLL_OVER))
+ // return super.createCompositeRuler();
+ //
+ // CompositeRuler ruler = new CompositeRuler();
+ // AnnotationRulerColumn column = new
+ // AnnotationRulerColumn(VERTICAL_RULER_WIDTH, getAnnotationAccess());
+ // column.setHover(new JavaExpandHover(ruler, getAnnotationAccess(), new
+ // IDoubleClickListener() {
+ //
+ // public void doubleClick(DoubleClickEvent event) {
+ // // for now: just invoke ruler double click action
+ // triggerAction(ITextEditorActionConstants.RULER_DOUBLE_CLICK);
+ // }
+ //
+ // private void triggerAction(String actionID) {
+ // IAction action = getAction(actionID);
+ // if (action != null) {
+ // if (action instanceof IUpdate)
+ // ((IUpdate) action).update();
+ // // hack to propagate line change
+ // if (action instanceof ISelectionListener) {
+ // ((ISelectionListener) action).selectionChanged(null, null);
+ // }
+ // if (action.isEnabled())
+ // action.run();
+ // }
+ // }
+ //
+ // }));
+ // ruler.addDecorator(0, column);
+ //
+ // if (isLineNumberRulerVisible())
+ // ruler.addDecorator(1, createLineNumberRulerColumn());
+ // else if (isPrefQuickDiffAlwaysOn())
+ // ruler.addDecorator(1, createChangeRulerColumn());
+ //
+ // return ruler;
+ // }
+ /*
+ * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#createAnnotationRulerColumn(org.eclipse.jface.text.source.CompositeRuler)
+ * @since 3.2
+ */
+ protected IVerticalRulerColumn createAnnotationRulerColumn(
+ CompositeRuler ruler) {
+ if (!getPreferenceStore().getBoolean(
+ PreferenceConstants.EDITOR_ANNOTATION_ROLL_OVER))
+ return super.createAnnotationRulerColumn(ruler);
+
+ AnnotationRulerColumn column = new AnnotationRulerColumn(
+ VERTICAL_RULER_WIDTH, getAnnotationAccess());
+ column.setHover(new JavaExpandHover(ruler, getAnnotationAccess(),
+ new IDoubleClickListener() {
+
+ public void doubleClick(DoubleClickEvent event) {
+ // for now: just invoke ruler double click action
+ triggerAction(ITextEditorActionConstants.RULER_DOUBLE_CLICK);
+ }
+
+ private void triggerAction(String actionID) {
+ IAction action = getAction(actionID);
+ if (action != null) {
+ if (action instanceof IUpdate)
+ ((IUpdate) action).update();
+ // hack to propagate line change
+ if (action instanceof ISelectionListener) {
+ ((ISelectionListener) action).selectionChanged(
+ null, null);
+ }
+ if (action.isEnabled())
+ action.run();
+ }
+ }
+
+ }));
+
+ return column;
+ }
+
+ /**
+ * Returns the folding action group, or <code>null</code> if there is
+ * none.
+ *
+ * @return the folding action group, or <code>null</code> if there is none
+ * @since 3.0
+ */
+ protected FoldingActionGroup getFoldingActionGroup() {
+ return fFoldingGroup;
+ }
+
+ /*
+ * @see org.eclipse.ui.texteditor.AbstractTextEditor#performRevert()
+ */
+ protected void performRevert() {
+ ProjectionViewer projectionViewer = (ProjectionViewer) getSourceViewer();
+ projectionViewer.setRedraw(false);
+ try {
+
+ boolean projectionMode = projectionViewer.isProjectionMode();
+ if (projectionMode) {
+ projectionViewer.disableProjection();
+ if (fProjectionModelUpdater != null)
+ fProjectionModelUpdater.uninstall();
+ }
+
+ super.performRevert();
+
+ if (projectionMode) {
+ if (fProjectionModelUpdater != null)
+ fProjectionModelUpdater.install(this, projectionViewer);
+ projectionViewer.enableProjection();
+ }
+
+ } finally {
+ projectionViewer.setRedraw(true);
+ }
+ }
+
+ /**
+ * React to changed selection.
+ *
+ * @since 3.0
+ */
+ protected void selectionChanged() {
+ if (getSelectionProvider() == null)
+ return;
+ ISourceReference element = computeHighlightRangeSourceReference();
+ if (getPreferenceStore().getBoolean(
+ PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE))
+ synchronizeOutlinePage(element);
+ setSelection(element, false);
+ updateStatusLine();
+ }
+
+ private boolean isJavaOutlinePageActive() {
+ IWorkbenchPart part = getActivePart();
+ return part instanceof ContentOutline
+ && ((ContentOutline) part).getCurrentPage() == fOutlinePage;
+ }
+
+ private IWorkbenchPart getActivePart() {
+ IWorkbenchWindow window = getSite().getWorkbenchWindow();
+ IPartService service = window.getPartService();
+ IWorkbenchPart part = service.getActivePart();
+ return part;
+ }
+
+ /**
+ * Computes and returns the source reference that includes the caret and
+ * serves as provider for the outline page selection and the editor range
+ * indication.
+ *
+ * @return the computed source reference
+ * @since 3.0
+ */
+ protected ISourceReference computeHighlightRangeSourceReference() {
+ ISourceViewer sourceViewer = getSourceViewer();
+ if (sourceViewer == null)
+ return null;
+
+ StyledText styledText = sourceViewer.getTextWidget();
+ if (styledText == null)
+ return null;
+
+ int caret = 0;
+ if (sourceViewer instanceof ITextViewerExtension5) {
+ ITextViewerExtension5 extension = (ITextViewerExtension5) sourceViewer;
+ caret = extension.widgetOffset2ModelOffset(styledText
+ .getCaretOffset());
+ } else {
+ int offset = sourceViewer.getVisibleRegion().getOffset();
+ caret = offset + styledText.getCaretOffset();
+ }
+
+ IJavaElement element = getElementAt(caret, false);
+
+ if (!(element instanceof ISourceReference))
+ return null;
+
+ if (element.getElementType() == IJavaElement.IMPORT_DECLARATION) {
+
+ IImportDeclaration declaration = (IImportDeclaration) element;
+ IImportContainer container = (IImportContainer) declaration
+ .getParent();
+ ISourceRange srcRange = null;
+
+ try {
+ srcRange = container.getSourceRange();
+ } catch (JavaModelException e) {
+ }
+
+ if (srcRange != null && srcRange.getOffset() == caret)
+ return container;
+ }
+
+ return (ISourceReference) element;
+ }
+
+ /**
+ * Returns the most narrow java element including the given offset.
+ *
+ * @param offset
+ * the offset inside of the requested element
+ * @param reconcile
+ * <code>true</code> if editor input should be reconciled in
+ * advance
+ * @return the most narrow java element
+ * @since 3.0
+ */
+ protected IJavaElement getElementAt(int offset, boolean reconcile) {
+ return getElementAt(offset);
+ }
+
+ public ShowInContext getShowInContext() {
+ FileEditorInput fei = (FileEditorInput) getEditorInput();
+ ShowInContext context = BrowserUtil.getShowInContext(fei.getFile(),
+ false, "");
+ if (context != null) {
+ return context;
+ }
+ return new ShowInContext(fei.getFile(), null);
+ }
+
+ public String[] getShowInTargetIds() {
+ return new String[] { BrowserView.ID_BROWSER };
+ }
+
+ /**
+ * Updates the occurrences annotations based on the current selection.
+ *
+ * @param selection
+ * the text selection
+ * @param astRoot
+ * the compilation unit AST
+ * @since 3.0
+ */
+ protected void updateOccurrenceAnnotations(ITextSelection selection) {// ,
+ // CompilationUnit
+ // astRoot)
+ // {
+
+ if (fOccurrencesFinderJob != null)
+ fOccurrencesFinderJob.cancel();
+
+ if (!fMarkOccurrenceAnnotations)
+ return;
+
+ // if (astRoot == null || selection == null)
+ if (selection == null)
+ return;
+
+ IDocument document = getSourceViewer().getDocument();
+ if (document == null)
+ return;
+
+ fMarkOccurrenceTargetRegion = null;
+ if (document instanceof IDocumentExtension4) {
+ int offset = selection.getOffset();
+ long currentModificationStamp = ((IDocumentExtension4) document)
+ .getModificationStamp();
+ if (fMarkOccurrenceTargetRegion != null
+ && currentModificationStamp == fMarkOccurrenceModificationStamp) {
+ if (fMarkOccurrenceTargetRegion.getOffset() <= offset
+ && offset <= fMarkOccurrenceTargetRegion.getOffset()
+ + fMarkOccurrenceTargetRegion.getLength())
+ return;
+ }
+ fMarkOccurrenceTargetRegion = JavaWordFinder.findWord(document,
+ offset);
+ fMarkOccurrenceModificationStamp = currentModificationStamp;
+ }
+
+ if (fMarkOccurrenceTargetRegion == null
+ || fMarkOccurrenceTargetRegion.getLength() == 0) {
+ return;
+ }
+
+ List matches = null;
+
+ if (matches == null) {
+ try {
+ matches = new ArrayList();
+
+ Scanner fScanner = new Scanner();
+ fScanner.setSource(document.get().toCharArray());
+ fScanner.setPHPMode(false);
+ String wordStr;
+ char[] word;
+
+ wordStr = document.get(fMarkOccurrenceTargetRegion.getOffset(),
+ fMarkOccurrenceTargetRegion.getLength());
+ if (wordStr != null) {
+ word = wordStr.toCharArray();
+ int fToken = ITerminalSymbols.TokenNameEOF;
+ try {
+ fToken = fScanner.getNextToken();
+ while (fToken != ITerminalSymbols.TokenNameEOF) { // &&
+ // fToken
+ // !=
+ // TokenNameERROR) {
+ if (fToken == ITerminalSymbols.TokenNameVariable
+ || fToken == ITerminalSymbols.TokenNameIdentifier) {
+ // global variable
+ if (fScanner.equalsCurrentTokenSource(word)) {
+ matches
+ .add(new Region(
+ fScanner
+ .getCurrentTokenStartPosition(),
+ fScanner
+ .getCurrentTokenEndPosition()
+ - fScanner
+ .getCurrentTokenStartPosition()
+ + 1));
+ }
+ }
+ fToken = fScanner.getNextToken();
+ }
+ } catch (InvalidInputException e) {
+ // ignore errors
+ } catch (SyntaxError e) {
+ // ignore errors
+ }
+ }
+ } catch (BadLocationException e1) {
+ // ignore errors
+ } catch (Exception e) {
+ e.printStackTrace();
+ // ignore errors
+ }
+
+ }
+
+ if (matches == null || matches.size() == 0) {
+ if (!fStickyOccurrenceAnnotations)
+ removeOccurrenceAnnotations();
+ return;
+ }
+
+ Position[] positions = new Position[matches.size()];
+ int i = 0;
+ for (Iterator each = matches.iterator(); each.hasNext();) {
+ IRegion currentNode = (IRegion) each.next();
+ positions[i++] = new Position(currentNode.getOffset(), currentNode
+ .getLength());
+ }
+
+ fOccurrencesFinderJob = new OccurrencesFinderJob(document, positions,
+ selection);
+ // fOccurrencesFinderJob.setPriority(Job.DECORATE);
+ // fOccurrencesFinderJob.setSystem(true);
+ // fOccurrencesFinderJob.schedule();
+ fOccurrencesFinderJob.run(new NullProgressMonitor());
+ }
+
+ protected void installOccurrencesFinder() {
+ fMarkOccurrenceAnnotations = true;
+
+ fPostSelectionListenerWithAST = new ISelectionListenerWithAST() {
+ public void selectionChanged(IEditorPart part,
+ ITextSelection selection) { // ,
+ // CompilationUnit
+ // astRoot)
+ // {
+ updateOccurrenceAnnotations(selection);// , astRoot);
+ }
+ };
+ SelectionListenerWithASTManager.getDefault().addListener(this,
+ fPostSelectionListenerWithAST);
+ if (getSelectionProvider() != null) {
+ fForcedMarkOccurrencesSelection = getSelectionProvider()
+ .getSelection();
+ SelectionListenerWithASTManager.getDefault().forceSelectionChange(
+ this, (ITextSelection) fForcedMarkOccurrencesSelection);
+ }
+
+ if (fOccurrencesFinderJobCanceler == null) {
+ fOccurrencesFinderJobCanceler = new OccurrencesFinderJobCanceler();
+ fOccurrencesFinderJobCanceler.install();
+ }
+ }
+
+ protected void uninstallOccurrencesFinder() {
+ fMarkOccurrenceAnnotations = false;
+
+ if (fOccurrencesFinderJob != null) {
+ fOccurrencesFinderJob.cancel();
+ fOccurrencesFinderJob = null;
+ }
+
+ if (fOccurrencesFinderJobCanceler != null) {
+ fOccurrencesFinderJobCanceler.uninstall();
+ fOccurrencesFinderJobCanceler = null;
+ }
+
+ if (fPostSelectionListenerWithAST != null) {
+ SelectionListenerWithASTManager.getDefault().removeListener(this,
+ fPostSelectionListenerWithAST);
+ fPostSelectionListenerWithAST = null;
+ }
+
+ removeOccurrenceAnnotations();
+ }
+
+ protected boolean isMarkingOccurrences() {
+ return fMarkOccurrenceAnnotations;
+ }
+
+ void removeOccurrenceAnnotations() {
+ fMarkOccurrenceModificationStamp = IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP;
+ fMarkOccurrenceTargetRegion = null;
+
+ IDocumentProvider documentProvider = getDocumentProvider();
+ if (documentProvider == null)
+ return;
+
+ IAnnotationModel annotationModel = documentProvider
+ .getAnnotationModel(getEditorInput());
+ if (annotationModel == null || fOccurrenceAnnotations == null)
+ return;
+
+ synchronized (getLockObject(annotationModel)) {
+ if (annotationModel instanceof IAnnotationModelExtension) {
+ ((IAnnotationModelExtension) annotationModel)
+ .replaceAnnotations(fOccurrenceAnnotations, null);
+ } else {
+ for (int i = 0, length = fOccurrenceAnnotations.length; i < length; i++)
+ annotationModel.removeAnnotation(fOccurrenceAnnotations[i]);
+ }
+ fOccurrenceAnnotations = null;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. 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 implementation
+ www.phpeclipse.de
+ **********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import net.sourceforge.phpdt.internal.corext.phpdoc.PHPDocUtil;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.builder.IdentifierIndexManager;
+import net.sourceforge.phpeclipse.builder.PHPIdentifierLocation;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPElement;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPFunction;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPWordExtractor;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * Implementation for an <code>ITextHover</code> which hovers over PHP code.
+ */
+public class PHPTextHover implements ITextHover {
+ private static HashMap functionDescriptions = null;
+
+ private static HashMap identDescriptions = null;
+
+ /**
+ * The current project; maybe <code>null</code> for preference pages
+ */
+ private IProject fProject;
+
+ public PHPTextHover(IProject project) {
+ fProject = project;
+ }
+
+ /*
+ * (non-Javadoc) Method declared on ITextHover
+ */
+ public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
+ if (hoverRegion != null) {
+ try {
+ if (hoverRegion.getLength() > -1) {
+ String word = textViewer.getDocument().get(
+ hoverRegion.getOffset(), hoverRegion.getLength());
+ if (functionDescriptions == null) {
+ functionDescriptions = new HashMap();
+ identDescriptions = new HashMap();
+ ArrayList syntaxbuffer = PHPSyntaxRdr.getSyntaxData();
+ PHPElement elbuffer = null;
+ if (syntaxbuffer != null) {
+ for (int i = 0; i < syntaxbuffer.size(); i++) {
+ elbuffer = (PHPElement) syntaxbuffer.get(i);
+ if (elbuffer instanceof PHPFunction) {
+ functionDescriptions.put(
+ elbuffer.getName(), elbuffer
+ .getHoverText());
+ } else {
+ identDescriptions.put(elbuffer.getName(),
+ elbuffer.getHoverText());
+ }
+ }
+ }
+ //
+ // while ((syntaxbuffer != null)
+ // && (!syntaxbuffer.isEmpty() && ((elbuffer =
+ // (PHPElement)
+ // syntaxbuffer.remove(0)) != null))) {
+ // functionDescriptions.put(elbuffer.getName(),
+ // elbuffer.getHoverText());
+ // }
+ }
+ String hoverInfo = (String) identDescriptions.get(word);
+ if (hoverInfo == null & word.length() > 0) {
+ hoverInfo = (String) functionDescriptions.get(word
+ .toLowerCase());
+ }
+ if (hoverInfo == null && fProject != null) {
+ // get the possible PHPDoc information from the index
+ // file
+ IdentifierIndexManager indexManager = PHPeclipsePlugin
+ .getDefault().getIndexManager(fProject);
+ List list = indexManager.getLocations(word);
+ if (list.size() > 0) {
+ try {
+ PHPIdentifierLocation location;
+ String filename;
+ StringBuffer hoverInfoBuffer = new StringBuffer();
+ String workspaceLocation;
+ if (fProject != null) {
+ workspaceLocation = fProject.getLocation()
+ .toString() + '/';
+ } else {
+ // should never happen?
+ workspaceLocation = PHPeclipsePlugin
+ .getWorkspace().getRoot()
+ .getLocation().toString();
+ }
+ // boolean foundPHPdoc = false;
+ for (int i = 0; i < list.size(); i++) {
+ location = (PHPIdentifierLocation) list
+ .get(i);
+ filename = workspaceLocation
+ + location.getFilename();
+ PHPDocUtil.appendPHPDoc(hoverInfoBuffer,
+ filename, location);
+ }
+ hoverInfo = hoverInfoBuffer.toString();
+ } catch (Throwable e) {
+ // ignore exceptions
+ // e.printStackTrace();
+ }
+ }
+ }
+ return hoverInfo;
+ }
+ // } catch (BadLocationException x) {
+ } catch (Exception x) {
+ }
+ }
+ return null;
+ // don't show this annoying text
+ // return "empty selection";
+ }
+
+ /*
+ * (non-Javadoc) Method declared on ITextHover
+ */
+ public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
+ Point selection = PHPWordExtractor.findWord(textViewer.getDocument(),
+ offset);
+ // show the extracted word as a tooltip
+ if (selection != null && selection.x <= offset
+ && offset < selection.x + selection.y)
+ return new Region(selection.x, selection.y);
+ return new Region(offset, 0);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2004 Christopher Lenz 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:
+ * Christopher Lenz - initial implementation
+ *
+ * $Id: WebUI.java,v 1.7 2006-10-21 23:13:54 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.ui;
+
+import java.io.IOException;
+import java.net.URL;
+
+import net.sourceforge.phpeclipse.ui.templates.template.HTMLContextType;
+import net.sourceforge.phpeclipse.ui.templates.template.JSContextType;
+import net.sourceforge.phpeclipse.ui.templates.template.SmartyContextType;
+import net.sourceforge.phpeclipse.ui.templates.template.XMLContextType;
+
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.jface.text.templates.ContextTypeRegistry;
+import org.eclipse.jface.text.templates.persistence.TemplateStore;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.editors.text.templates.ContributionContextTypeRegistry;
+import org.eclipse.ui.editors.text.templates.ContributionTemplateStore;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+/**
+ * The web development tools UI plugin.
+ */
+public class WebUI extends AbstractUIPlugin implements IPreferenceConstants {
+ private static final String CUSTOM_TEMPLATES_KEY = "net.sourceforge.phpeclipse.ui.templates"; //$NON-NLS-1$
+
+ // Constants ---------------------------------------------------------------
+
+ public static final String ICON_OVERLAY_ERROR = "full/ovr16/error_co.gif"; //$NON-NLS-1$
+
+ public static final String ICON_OVERLAY_WARNING = "full/ovr16/warning_co.gif"; //$NON-NLS-1$
+
+ // Instance Variables ------------------------------------------------------
+
+ /** The shared instance. */
+ private static WebUI plugin;
+
+ public static IWorkbenchPage getActivePage() {
+ return getDefault().internalGetActivePage();
+ }
+
+ private IWorkbenchPage internalGetActivePage() {
+ return getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ }
+
+ public static Shell getActiveWorkbenchShell() {
+ return getActiveWorkbenchWindow().getShell();
+ }
+
+ public static IWorkbenchWindow getActiveWorkbenchWindow() {
+ return getDefault().getWorkbench().getActiveWorkbenchWindow();
+ }
+
+ // Public Methods ----------------------------------------------------------
+
+ /**
+ * Returns the shared instance.
+ */
+ public static WebUI getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Returns the workspace instance.
+ */
+ public static IWorkspace getWorkspace() {
+ return ResourcesPlugin.getWorkspace();
+ }
+
+ /** The context type registry. */
+ private ContributionContextTypeRegistry fRegistry;
+
+ /** The template store. */
+ private TemplateStore fStore;
+
+ // Constructors ------------------------------------------------------------
+
+ /**
+ * The constructor.
+ */
+ public WebUI() {
+ plugin = this;
+ }
+
+ /**
+ * Returns this plug-in's context type registry.
+ *
+ * @return the context type registry for this plug-in instance
+ */
+ public ContextTypeRegistry getContextTypeRegistry() {
+ if (fRegistry == null) {
+ // create an configure the contexts available in the editor
+ fRegistry = new ContributionContextTypeRegistry();
+ fRegistry.addContextType(XMLContextType.XML_CONTEXT_TYPE);
+ fRegistry.addContextType(HTMLContextType.HTML_CONTEXT_TYPE);
+ fRegistry.addContextType(SmartyContextType.SMARTY_CONTEXT_TYPE);
+ fRegistry.addContextType(JSContextType.JS_CONTEXT_TYPE);
+ }
+ return fRegistry;
+ }
+
+ // Private Methods ---------------------------------------------------------
+
+ /**
+ * Returns an image descriptor for the image corresponding to the specified
+ * key (which is the name of the image file).
+ *
+ * @param key
+ * The key of the image
+ * @return The descriptor for the requested image, or <code>null</code> if
+ * the image could not be found
+ */
+ private ImageDescriptor getImageDescriptor(String key) {
+ try {
+ URL url = getBundle().getEntry("/icons/" + key); //$NON-NLS-1$
+ return ImageDescriptor.createFromURL(url);
+ } catch (IllegalStateException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Returns this plug-in's template store.
+ *
+ * @return the template store of this plug-in instance
+ */
+ public TemplateStore getTemplateStore() {
+ if (fStore == null) {
+ fStore = new ContributionTemplateStore(getContextTypeRegistry(),
+ getDefault().getPreferenceStore(), CUSTOM_TEMPLATES_KEY);
+ try {
+ fStore.load();
+ } catch (IOException e) {
+ WebUI
+ .getDefault()
+ .getLog()
+ .log(
+ new Status(
+ IStatus.ERROR,
+ "net.sourceforge.phpeclipse.ui", IStatus.OK, "", e)); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+ return fStore;
+ }
+
+ protected void initializeDefaultPreferences(IPreferenceStore store) {
+ store.setDefault(PHP_LOCALHOST_PREF, "http://localhost");
+ store.setDefault(PHP_DOCUMENTROOT_PREF, getWorkspace().getRoot()
+ .getLocation().toString());
+ // store.setDefault(PHP_BOOKMARK_DEFAULT, "");
+
+ store.setDefault(PHP_AUTO_PREVIEW_DEFAULT, "true");
+ store.setDefault(PHP_BRING_TO_TOP_PREVIEW_DEFAULT, "true");
+ // store.setDefault(PHP_SHOW_HTML_FILES_LOCAL, "true");
+ // store.setDefault(PHP_SHOW_XML_FILES_LOCAL, "false");
+ }
+
+ /*
+ * @see AbstractUIPlugin#initializeImageRegistry(ImageRegistry)
+ */
+ protected void initializeImageRegistry(ImageRegistry reg) {
+ reg.put(ICON_OVERLAY_ERROR, getImageDescriptor(ICON_OVERLAY_ERROR));
+ reg.put(ICON_OVERLAY_WARNING, getImageDescriptor(ICON_OVERLAY_WARNING));
+ }
+ // private IWorkbenchPage internalGetActivePage() {
+ // IWorkbenchWindow window = getWorkbench().getActiveWorkbenchWindow();
+ // if (window != null)
+ // return window.getActivePage();
+ // return null;
+ // }
+}
\ No newline at end of file
--- /dev/null
+package net.sourceforge.phpeclipse.ui.editor;
+
+import net.sourceforge.phpeclipse.ui.IPreferenceConstants;
+import net.sourceforge.phpeclipse.ui.WebUI;
+import net.sourceforge.phpeclipse.ui.overlaypages.ProjectPrefUtil;
+import net.sourceforge.phpeclipse.webbrowser.views.BrowserView;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.TextEditorAction;
+
+/**
+ * ClassDeclaration that defines the action for parsing the current PHP file
+ */
+public class ShowExternalPreviewAction extends TextEditorAction {
+ public final static int XML_TYPE = 1;
+
+ public final static int HTML_TYPE = 2;
+
+ public final static int SMARTY_TYPE = 3;
+
+ public final static int PHP_TYPE = 4;
+
+ private static ShowExternalPreviewAction instance = new ShowExternalPreviewAction();
+
+ /**
+ * Constructs and updates the action.
+ */
+ private ShowExternalPreviewAction() {
+ super(EditorMessages.getResourceBundle(), "ParserAction.", null); //$NON-NLS-1$
+ update();
+ }
+
+ public static ShowExternalPreviewAction getInstance() {
+ return instance;
+ }
+
+ /**
+ * Code called when the action is fired.
+ */
+ public void run() {
+ doRun(PHP_TYPE);
+ }
+
+ public void doRun(int type) {
+ IFile previewFile = getFile();
+ BrowserUtil.showPreview(previewFile, false, "");
+ }
+
+ public void refresh(int type) {
+ IFile fileToParse = getFile();
+ if (fileToParse == null) {
+ // should never happen
+ return;
+ }
+ boolean autoPreview = ProjectPrefUtil.getPreviewBooleanValue(
+ fileToParse, IPreferenceConstants.PHP_AUTO_PREVIEW_DEFAULT);
+ boolean bringToTopPreview = ProjectPrefUtil.getPreviewBooleanValue(
+ fileToParse,
+ IPreferenceConstants.PHP_BRING_TO_TOP_PREVIEW_DEFAULT);
+
+ if (autoPreview) {
+ IWorkbenchPage page = WebUI.getActivePage();
+ try {
+ IViewPart part = page.findView(BrowserView.ID_BROWSER);
+ if (part == null) {
+ part = page.showView(BrowserView.ID_BROWSER);
+ } else {
+ if (bringToTopPreview) {
+ page.bringToTop(part);
+ }
+ }
+ if (part != null) {
+ ((BrowserView) part).refresh();
+ }
+ } catch (Exception e) {
+ // PHPeclipsePlugin.log(e);
+ }
+ }
+ }
+
+ /**
+ * Finds the file that's currently opened in the PHP Text Editor
+ */
+ protected IFile getFile() {
+ ITextEditor editor = getTextEditor();
+ IEditorInput editorInput = null;
+ if (editor != null) {
+ editorInput = editor.getEditorInput();
+ }
+ if (editorInput instanceof IFileEditorInput)
+ return ((IFileEditorInput) editorInput).getFile();
+ // if nothing was found, which should never happen
+ return null;
+ }
+
+ public static String getLocalhostURL(IPreferenceStore store, IFile file) {
+ if (file != null) {
+ if (store == null) {
+ store = WebUI.getDefault().getPreferenceStore();
+ }
+ // IPath path = file.getFullPath();
+ String localhostURL = file.getLocation().toString();
+ String lowerCaseFileName = localhostURL.toLowerCase();
+ // String documentRoot =
+ // store.getString(PHPeclipsePlugin.DOCUMENTROOT_PREF);
+ IPath documentRootPath = ProjectPrefUtil.getDocumentRoot(file
+ .getProject());
+ String documentRoot = documentRootPath.toString().toLowerCase();
+ if (lowerCaseFileName.startsWith(documentRoot)) {
+ localhostURL = localhostURL.substring(documentRoot.length());
+ } else {
+ return null;
+ }
+ // return store.getString(PHPeclipsePlugin.LOCALHOST_PREF) +
+ // localhostURL;
+ return ProjectPrefUtil.getMiscProjectsPreferenceValue(file
+ .getProject(), IPreferenceConstants.PHP_LOCALHOST_PREF)
+ + localhostURL;
+ }
+ return "http://localhost";
+ }
+}
\ No newline at end of file
--- /dev/null
+/**
+ * Copyright (c) 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 - Initial API and implementation
+ */
+package net.sourceforge.phpeclipse.webbrowser.internal;
+
+import java.net.URL;
+import java.util.Iterator;
+
+import net.sourceforge.phpeclipse.webbrowser.WebBrowser;
+import net.sourceforge.phpeclipse.webbrowser.WebBrowserEditorInput;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.IActionDelegate;
+
+/**
+ * Action to open the Web broswer on a resource.
+ */
+public class OpenWithBrowserActionDelegate implements IActionDelegate {
+ private IResource resource;
+
+ /**
+ * OpenBrowserAction constructor comment.
+ */
+ public OpenWithBrowserActionDelegate() {
+ super();
+ }
+
+ /**
+ * Performs this action.
+ * <p>
+ * This method is called when the delegating action has been triggered.
+ * Implement this method to do the actual work.
+ * </p>
+ *
+ * @param action
+ * the action proxy that handles the presentation portion of the
+ * action
+ */
+ public void run(IAction action) {
+ URL url = null;
+ try {
+ url = new URL("file://" + resource.getLocation());
+ WebBrowser.openURL(new WebBrowserEditorInput(url,
+ WebBrowserEditorInput.SHOW_ALL
+ | WebBrowserEditorInput.FORCE_NEW_PAGE));
+ } catch (Exception e) {
+ Trace.trace(Trace.SEVERE, "Error opening browser on file", e);
+ }
+ }
+
+ /**
+ * Notifies this action delegate that the selection in the workbench has
+ * changed.
+ * <p>
+ * Implementers can use this opportunity to change the availability of the
+ * action or to modify other presentation properties.
+ * </p>
+ *
+ * @param action
+ * the action proxy that handles presentation portion of the
+ * action
+ * @param selection
+ * the current selection in the workbench
+ */
+ public void selectionChanged(IAction action, ISelection sel) {
+ if (sel.isEmpty() || !(sel instanceof IStructuredSelection)) {
+ action.setEnabled(false);
+ return;
+ }
+
+ IStructuredSelection select = (IStructuredSelection) sel;
+ Iterator iterator = select.iterator();
+ Object selection = iterator.next();
+ if (iterator.hasNext()) { // more than one selection (should never
+ // happen)
+ action.setEnabled(false);
+ return;
+ }
+
+ if (!(selection instanceof IResource)) {
+ action.setEnabled(false);
+ return;
+ }
+
+ resource = (IResource) selection;
+ action.setEnabled(true);
+ }
+}
\ No newline at end of file
--- /dev/null
+/**
+ * Copyright (c) 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 - Initial API and implementation
+ */
+package net.sourceforge.phpeclipse.webbrowser.internal;
+
+import java.net.URL;
+
+import net.sourceforge.phpeclipse.webbrowser.IWebBrowserEditorInput;
+import net.sourceforge.phpeclipse.webbrowser.WebBrowserEditorInput;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.part.EditorPart;
+
+/**
+ * An integrated Web browser, defined as an editor to make better use of the
+ * desktop.
+ */
+public class WebBrowserEditor extends EditorPart {
+ public static final String WEB_BROWSER_EDITOR_ID = "net.sourceforge.phpeclipse.webbrowser";
+
+ protected WebBrowser webBrowser;
+
+ protected String initialURL;
+
+ protected Image image;
+
+ protected TextAction cutAction;
+
+ protected TextAction copyAction;
+
+ protected TextAction pasteAction;
+
+ protected IResourceChangeListener resourceListener;
+
+ /**
+ * WebBrowserEditor constructor comment.
+ */
+ public WebBrowserEditor() {
+ super();
+ }
+
+ /**
+ * Creates the SWT controls for this workbench part.
+ * <p>
+ * Clients should not call this method (the workbench calls this method at
+ * appropriate times).
+ * </p>
+ * <p>
+ * For implementors this is a multi-step process:
+ * <ol>
+ * <li>Create one or more controls within the parent.</li>
+ * <li>Set the parent layout as needed.</li>
+ * <li>Register any global actions with the <code>IActionService</code>.</li>
+ * <li>Register any popup menus with the <code>IActionService</code>.</li>
+ * <li>Register a selection provider with the
+ * <code>ISelectionService</code> (optional). </li>
+ * </ol>
+ * </p>
+ *
+ * @param parent
+ * the parent control
+ */
+ public void createPartControl(Composite parent) {
+ IWebBrowserEditorInput input = getWebBrowserEditorInput();
+
+ if (input == null || input.isToolbarVisible() == false)
+ webBrowser = new WebBrowser(parent, false, input
+ .isStatusbarVisible());
+ else {
+ webBrowser = new WebBrowser(parent, true, input
+ .isStatusbarVisible());
+ cutAction = new TextAction(webBrowser, TextAction.CUT);
+ copyAction = new TextAction(webBrowser, TextAction.COPY);
+ pasteAction = new TextAction(webBrowser, TextAction.PASTE);
+ }
+
+ webBrowser.setURL(initialURL);
+ webBrowser.editor = this;
+ }
+
+ public void dispose() {
+ if (image != null && !image.isDisposed())
+ image.dispose();
+ image = null;
+
+ if (resourceListener != null)
+ ResourcesPlugin.getWorkspace().removeResourceChangeListener(
+ resourceListener);
+ }
+
+ /*
+ * (non-Javadoc) Saves the contents of this editor. <p> Subclasses must
+ * override this method to implement the open-save-close lifecycle for an
+ * editor. For greater details, see <code>IEditorPart</code> </p>
+ *
+ * @see IEditorPart
+ */
+ public void doSave(IProgressMonitor monitor) {
+ }
+
+ /*
+ * (non-Javadoc) Saves the contents of this editor to another object. <p>
+ * Subclasses must override this method to implement the open-save-close
+ * lifecycle for an editor. For greater details, see <code>IEditorPart</code>
+ * </p>
+ *
+ * @see IEditorPart
+ */
+ public void doSaveAs() {
+ }
+
+ /**
+ * Returns the copy action.
+ *
+ * @return org.eclipse.jface.action.IAction
+ */
+ public IAction getCopyAction() {
+ return copyAction;
+ }
+
+ /**
+ * Returns the cut action.
+ *
+ * @return org.eclipse.jface.action.IAction
+ */
+ public IAction getCutAction() {
+ return cutAction;
+ }
+
+ /**
+ * Returns the paste action.
+ *
+ * @return org.eclipse.jface.action.IAction
+ */
+ public IAction getPasteAction() {
+ return pasteAction;
+ }
+
+ /**
+ * Returns the web editor input, if available.
+ *
+ * @return net.sourceforge.phpeclipse.webbrowser.IWebBrowserEditorInput
+ */
+ protected IWebBrowserEditorInput getWebBrowserEditorInput() {
+ IEditorInput input = getEditorInput();
+ if (input instanceof IWebBrowserEditorInput)
+ return (IWebBrowserEditorInput) input;
+ return null;
+ }
+
+ /*
+ * (non-Javadoc) Sets the cursor and selection state for this editor to the
+ * passage defined by the given marker. <p> Subclasses may override. For
+ * greater details, see <code>IEditorPart</code> </p>
+ *
+ * @see IEditorPart
+ */
+ public void gotoMarker(IMarker marker) {
+ }
+
+ /*
+ * (non-Javadoc) Initializes the editor part with a site and input. <p>
+ * Subclasses of <code>EditorPart</code> must implement this method.
+ * Within the implementation subclasses should verify that the input type is
+ * acceptable and then save the site and input. Here is sample code: </p>
+ * <pre> if (!(input instanceof IFileEditorInput)) throw new
+ * PartInitException("Invalid Input: Must be IFileEditorInput");
+ * setSite(site); setInput(editorInput); </pre>
+ */
+ public void init(IEditorSite site, IEditorInput input) {
+ Trace.trace(Trace.FINEST, "Opening browser: " + input);
+ if (input instanceof IFileEditorInput) {
+ IFileEditorInput fei = (IFileEditorInput) input;
+ IFile file = fei.getFile();
+ URL url = null;
+ try {
+ if (file != null && file.exists())
+ url = file.getLocation().toFile().toURL();
+ } catch (Exception e) {
+ Trace.trace(Trace.SEVERE, "Error getting URL to file");
+ }
+ addResourceListener(file);
+ input = new WebBrowserEditorInput(url,
+ WebBrowserEditorInput.SHOW_ALL
+ | WebBrowserEditorInput.SAVE_URL);
+ }
+ if (input instanceof IWebBrowserEditorInput) {
+ IWebBrowserEditorInput wbei = (IWebBrowserEditorInput) input;
+ initialURL = null;
+ if (wbei.getURL() != null)
+ initialURL = wbei.getURL().toExternalForm();
+ if (webBrowser != null) {
+ webBrowser.setURL(initialURL);
+ site.getWorkbenchWindow().getActivePage().bringToTop(this);
+ }
+
+ setPartName(wbei.getName());
+ setTitleToolTip(wbei.getToolTipText());
+
+ Image oldImage = image;
+ ImageDescriptor id = wbei.getImageDescriptor();
+ image = id.createImage();
+
+ setTitleImage(image);
+ if (oldImage != null && !oldImage.isDisposed())
+ oldImage.dispose();
+ }
+ setSite(site);
+ setInput(input);
+ }
+
+ /*
+ * (non-Javadoc) Returns whether the contents of this editor have changed
+ * since the last save operation. <p> Subclasses must override this method
+ * to implement the open-save-close lifecycle for an editor. For greater
+ * details, see <code>IEditorPart</code> </p>
+ *
+ * @see IEditorPart
+ */
+ public boolean isDirty() {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc) Returns whether the "save as" operation is supported by
+ * this editor. <p> Subclasses must override this method to implement the
+ * open-save-close lifecycle for an editor. For greater details, see <code>IEditorPart</code>
+ * </p>
+ *
+ * @see IEditorPart
+ */
+ public boolean isSaveAsAllowed() {
+ return false;
+ }
+
+ /**
+ * Returns true if this editor has a toolbar.
+ *
+ * @return boolean
+ */
+ public boolean isToolbarVisible() {
+ IWebBrowserEditorInput input = getWebBrowserEditorInput();
+ if (input == null || input.isToolbarVisible())
+ return true;
+ else
+ return false;
+ }
+
+ /**
+ * Open the input in the internal Web browser.
+ */
+ public static void open(IWebBrowserEditorInput input) {
+ IWorkbenchWindow workbenchWindow = WebBrowserUIPlugin.getInstance()
+ .getWorkbench().getActiveWorkbenchWindow();
+ IWorkbenchPage page = workbenchWindow.getActivePage();
+
+ try {
+ IEditorReference[] editors = page.getEditorReferences();
+ int size = editors.length;
+ for (int i = 0; i < size; i++) {
+ if (WEB_BROWSER_EDITOR_ID.equals(editors[i].getId())) {
+ IEditorPart editor = editors[i].getEditor(true);
+ if (editor != null && editor instanceof WebBrowserEditor) {
+ WebBrowserEditor webEditor = (WebBrowserEditor) editor;
+ if (input.canReplaceInput(webEditor
+ .getWebBrowserEditorInput())) {
+ editor.init(editor.getEditorSite(), input);
+ return;
+ }
+ }
+ }
+ }
+
+ page.openEditor(input, WebBrowserEditor.WEB_BROWSER_EDITOR_ID);
+ } catch (Exception e) {
+ Trace.trace(Trace.SEVERE, "Error opening Web browser", e);
+ }
+ }
+
+ /**
+ * Asks this part to take focus within the workbench.
+ * <p>
+ * Clients should not call this method (the workbench calls this method at
+ * appropriate times).
+ * </p>
+ */
+ public void setFocus() {
+ if (webBrowser != null) {
+ if (webBrowser.combo != null)
+ webBrowser.combo.setFocus();
+ else
+ webBrowser.browser.setFocus();
+ webBrowser.updateHistory();
+ }
+ }
+
+ /**
+ * Update the actions.
+ */
+ protected void updateActions() {
+ if (cutAction != null)
+ cutAction.update();
+ if (copyAction != null)
+ copyAction.update();
+ if (pasteAction != null)
+ pasteAction.update();
+ }
+
+ /**
+ * Close the editor correctly.
+ */
+ protected void closeEditor() {
+ Display.getDefault().asyncExec(new Runnable() {
+ public void run() {
+ getEditorSite().getPage().closeEditor(WebBrowserEditor.this,
+ false);
+ }
+ });
+ }
+
+ /**
+ * Adds a resource change listener to see if the file is deleted.
+ */
+ protected void addResourceListener(final IResource resource) {
+ if (resource == null)
+ return;
+
+ resourceListener = new IResourceChangeListener() {
+ public void resourceChanged(IResourceChangeEvent event) {
+ try {
+ event.getDelta().accept(new IResourceDeltaVisitor() {
+ public boolean visit(IResourceDelta delta) {
+ IResource res = delta.getResource();
+
+ if (res == null || !res.equals(resource))
+ return true;
+
+ if (delta.getKind() != IResourceDelta.REMOVED)
+ return true;
+
+ Display.getDefault().asyncExec(new Runnable() {
+ public void run() {
+ String title = WebBrowserUIPlugin
+ .getResource("%dialogResourceDeletedTitle");
+ String message = WebBrowserUIPlugin
+ .getResource(
+ "%dialogResourceDeletedMessage",
+ resource.getName());
+ String[] labels = new String[] {
+ WebBrowserUIPlugin
+ .getResource("%dialogResourceDeletedIgnore"),
+ IDialogConstants.CLOSE_LABEL };
+ MessageDialog dialog = new MessageDialog(
+ getEditorSite().getShell(), title,
+ null, message,
+ MessageDialog.INFORMATION, labels,
+ 0);
+
+ if (dialog.open() != 0)
+ closeEditor();
+ }
+ });
+ return false;
+ }
+ });
+ } catch (Exception e) {
+ Trace.trace(Trace.SEVERE,
+ "Error listening for resource deletion", e);
+ }
+ }
+ };
+ ResourcesPlugin.getWorkspace().addResourceChangeListener(
+ resourceListener);
+ }
+}
\ 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.phpeclipse.webbrowser.views;
+
+import net.sourceforge.phpeclipse.webbrowser.internal.WebBrowser;
+import net.sourceforge.phpeclipse.webbrowser.internal.WebBrowserUtil;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.swt.browser.ProgressListener;
+import org.eclipse.swt.browser.StatusTextListener;
+import org.eclipse.swt.browser.TitleListener;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.part.IShowInTarget;
+import org.eclipse.ui.part.ShowInContext;
+import org.eclipse.ui.part.ViewPart;
+
+/**
+ * <code>BrowserView</code> is a simple demonstration of the SWT Browser
+ * widget. It consists of a workbench view and tab folder where each tab in the
+ * folder allows the user to interact with a control.
+ *
+ * @see ViewPart
+ */
+public class BrowserView extends ViewPart implements IShowInTarget {
+ public final static String ID_BROWSER = "net.sourceforge.phpeclipse.webbrowser.views";
+
+ WebBrowser fInstance = null;
+
+ String fUrl = null;
+
+ /**
+ * Create the example
+ *
+ * @see ViewPart#createPartControl
+ */
+ public void createPartControl(Composite frame) {
+ try {
+ if (WebBrowserUtil.isInternalBrowserOperational()) {
+ fInstance = new WebBrowser(frame, true, true);
+ }
+ } catch (Exception e) {
+ fInstance = null;
+ }
+ }
+
+ /**
+ * Called when we must grab focus.
+ *
+ * @see org.eclipse.ui.part.ViewPart#setFocus
+ */
+ public void setFocus() {
+ if (fInstance != null) {
+ fInstance.setFocus();
+ }
+ }
+
+ /**
+ * Called when the View is to be disposed
+ */
+ public void dispose() {
+ if (fInstance != null) {
+ fInstance.dispose();
+ fInstance = null;
+ }
+ super.dispose();
+ }
+
+ public void setUrl(final String url) {
+ if (fInstance != null) {
+ fUrl = url;
+ fInstance.setURL(url);
+ // try {
+ // ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
+ // public void run(IProgressMonitor monitor) throws CoreException {
+ // instance.setURL(url);
+ // }
+ // }, null);
+ // } catch (CoreException e) {
+ // // TODO Auto-generated catch block
+ // e.printStackTrace();
+ // }
+ }
+ }
+
+ public void refresh() {
+ if (fInstance != null) {
+ fInstance.refresh();
+ // try {
+ // ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
+ // public void run(IProgressMonitor monitor) throws CoreException {
+ // instance.refresh();
+ // }
+ // }, null);
+ // } catch (CoreException e) {
+ // // TODO Auto-generated catch block
+ // e.printStackTrace();
+ // }
+ }
+ }
+
+ public void refresh(String url) {
+ if (fInstance != null) {
+ if (fUrl == null || !fUrl.equals(url)) {
+ setUrl(url);
+ } else {
+ refresh();
+ }
+ }
+ }
+
+ public void addProgressListener(ProgressListener listener) {
+ if (fInstance != null) {
+ fInstance.addProgressListener(listener);
+ }
+ }
+
+ public void addStatusTextListener(StatusTextListener listener) {
+ if (fInstance != null) {
+ fInstance.addStatusTextListener(listener);
+ }
+ }
+
+ public void addTitleListener(TitleListener listener) {
+ if (fInstance != null) {
+ fInstance.addTitleListener(listener);
+ }
+ }
+
+ public boolean show(ShowInContext context) {
+ if (context instanceof ShowInContextBrowser) {
+ ShowInContextBrowser contextBrowser = (ShowInContextBrowser) context;
+ String localhostURL = contextBrowser.getLocalhostUrl();
+ if (localhostURL != null) {
+ setUrl(localhostURL);
+ return true;
+ }
+ }
+ if (context.getInput() instanceof IFile) {
+ IFile file = (IFile) context.getInput();
+ String localhostURL;
+ localhostURL = "file:///" + file.getLocation().toString();
+ setUrl(localhostURL);
+ return true;
+ }
+ return false;
+ }
+}
\ No newline at end of file
--- /dev/null
+package net.sourceforge.phpeclipse.wizards;
+
+import java.lang.reflect.InvocationTargetException;
+
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.ui.actions.OpenPHPPerspectiveAction;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExecutableExtension;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.ui.INewWizard;
+import org.eclipse.ui.actions.WorkspaceModifyDelegatingOperation;
+import org.eclipse.ui.dialogs.WizardNewProjectCreationPage;
+import org.eclipse.ui.wizards.newresource.BasicNewProjectResourceWizard;
+import org.eclipse.ui.wizards.newresource.BasicNewResourceWizard;
+
+public class NewProjectCreationWizard extends BasicNewResourceWizard implements
+ INewWizard, IExecutableExtension {
+ protected WizardNewProjectCreationPage projectPage;
+
+ protected IConfigurationElement configurationElement;
+
+ protected IProject newProject;
+
+ public NewProjectCreationWizard() {
+ setWindowTitle(PHPWizardMessages
+ .getString("NewProjectCreationWizard.windowTitle"));
+ }
+
+ public boolean performFinish() {
+ IRunnableWithProgress projectCreationOperation = new WorkspaceModifyDelegatingOperation(
+ getProjectCreationRunnable());
+
+ try {
+ getContainer().run(false, true, projectCreationOperation);
+ } catch (Exception e) {
+ PHPeclipsePlugin.log(e);
+ return false;
+ }
+
+ BasicNewProjectResourceWizard.updatePerspective(configurationElement);
+ selectAndReveal(newProject);
+ // open the PHP perspective
+ new OpenPHPPerspectiveAction().run();
+ return true;
+ }
+
+ protected IRunnableWithProgress getProjectCreationRunnable() {
+ return new IRunnableWithProgress() {
+ public void run(IProgressMonitor monitor)
+ throws InvocationTargetException, InterruptedException {
+ int remainingWorkUnits = 10;
+ monitor
+ .beginTask(
+ PHPWizardMessages
+ .getString("NewProjectCreationWizard.projectCreationMessage"),
+ remainingWorkUnits);
+
+ IWorkspace workspace = PHPeclipsePlugin.getWorkspace();
+ newProject = projectPage.getProjectHandle();
+
+ IProjectDescription description = workspace
+ .newProjectDescription(newProject.getName());
+ IPath path = Platform.getLocation();
+ IPath customPath = projectPage.getLocationPath();
+ if (!path.equals(customPath)) {
+ path = customPath;
+ description.setLocation(path);
+ }
+
+ try {
+ if (!newProject.exists()) {
+ newProject.create(description, new SubProgressMonitor(
+ monitor, 1));
+ remainingWorkUnits--;
+ }
+ if (!newProject.isOpen()) {
+ newProject.open(new SubProgressMonitor(monitor, 1));
+ remainingWorkUnits--;
+ }
+ JavaCore.addPHPNature(newProject, new SubProgressMonitor(
+ monitor, remainingWorkUnits));
+ } catch (CoreException e) {
+ throw new InvocationTargetException(e);
+ } finally {
+ monitor.done();
+ }
+ }
+ };
+ }
+
+ public void addPages() {
+ super.addPages();
+
+ projectPage = new WizardNewProjectCreationPage(PHPWizardMessages
+ .getString("WizardNewProjectCreationPage.pageName"));
+ projectPage.setTitle(PHPWizardMessages
+ .getString("WizardNewProjectCreationPage.pageTitle"));
+ projectPage.setDescription(PHPWizardMessages
+ .getString("WizardNewProjectCreationPage.pageDescription"));
+
+ addPage(projectPage);
+ }
+
+ public void setInitializationData(IConfigurationElement config,
+ String propertyName, Object data) throws CoreException {
+ configurationElement = config;
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. 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 implementation
+ Vicente Fernando - www.alfersoft.com.ar
+ **********************************************************************/
+package net.sourceforge.phpeclipse.xdebug.php.launching;
+
+import java.io.File;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import net.sourceforge.phpeclipse.xdebug.core.IXDebugPreferenceConstants;
+import net.sourceforge.phpeclipse.xdebug.core.XDebugCorePlugin;
+import net.sourceforge.phpeclipse.xdebug.php.model.XDebugTarget;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.debug.core.model.IDebugTarget;
+import org.eclipse.debug.core.model.ILaunchConfigurationDelegate;
+import org.eclipse.debug.core.model.IProcess;
+import org.eclipse.debug.core.model.LaunchConfigurationDelegate;
+
+public class PHPLaunchConfigurationDelegate extends LaunchConfigurationDelegate {
+
+ /**
+ * @see ILaunchConfigurationDelegate#launch(ILaunchConfiguration, String,
+ * ILaunch, IProgressMonitor)
+ */
+ public void launch(ILaunchConfiguration configuration, String mode,
+ ILaunch launch, IProgressMonitor monitor) throws CoreException {
+ List commandList = new ArrayList();
+
+ String phpInterpreter = configuration.getAttribute(
+ IXDebugConstants.ATTR_PHP_INTERPRETER, (String) null);
+ boolean useDefaultInterpreter = configuration.getAttribute(
+ IXDebugConstants.ATTR_PHP_DEFAULT_INTERPRETER, true);
+
+ if (useDefaultInterpreter)
+ phpInterpreter = XDebugCorePlugin
+ .getDefault()
+ .getPreferenceStore()
+ .getString(
+ IXDebugPreferenceConstants.PHP_INTERPRETER_PREFERENCE);
+
+ File exe = new File(phpInterpreter);
+ // Just to get sure that the interpreter exists
+ if (!exe.exists()) {
+ abort(
+ MessageFormat
+ .format(
+ "Specified PHP executable {0} does not exist. Check value of PHP-Interpreter.",
+ new String[] { phpInterpreter }), null);
+ }
+ commandList.add(phpInterpreter);
+
+ // Project name
+ String projectName = configuration.getAttribute(
+ IXDebugConstants.ATTR_PHP_PROJECT, (String) null);
+ IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(
+ projectName);
+ // Just to get sure that the project exists
+ if (project == null) {
+ abort("Project does not exist.", null);
+ }
+ String fileName = configuration.getAttribute(
+ IXDebugConstants.ATTR_PHP_FILE, (String) null);
+
+ IFile file = project.getFile(fileName);
+ // Just to get sure that the script exists
+ if (!file.exists()) {
+ abort(MessageFormat.format("PHP-Script {0} does not exist.",
+ new String[] { file.getFullPath().toString() }), null);
+ }
+
+ commandList.add(file.getLocation().toOSString());
+
+ // Get de Debugport form the Launchconfiguration or from the preferences
+ int debugPort = configuration.getAttribute(
+ IXDebugConstants.ATTR_PHP_DEBUGPORT, -1);
+ boolean useDefaultPort = configuration.getAttribute(
+ IXDebugConstants.ATTR_PHP_DEFAULT_DEBUGPORT, true);
+ if (useDefaultPort)
+ debugPort = XDebugCorePlugin.getDefault().getPreferenceStore()
+ .getInt(IXDebugPreferenceConstants.DEBUGPORT_PREFERENCE);
+ if (debugPort < 1024)
+ debugPort = IXDebugPreferenceConstants.DEFAULT_DEBUGPORT;
+
+ String[] envp = DebugPlugin.getDefault().getLaunchManager()
+ .getEnvironment(configuration);
+ // appends the environment to the native environment
+ if (envp == null) {
+ Map stringVars = DebugPlugin.getDefault().getLaunchManager()
+ .getNativeEnvironment();
+ int idx = 0;
+ envp = new String[stringVars.size()];
+ for (Iterator i = stringVars.keySet().iterator(); i.hasNext();) {
+ String key = (String) i.next();
+ String value = (String) stringVars.get(key);
+ envp[idx++] = key + "=" + value;
+ }
+ }
+ if (mode.equals(ILaunchManager.DEBUG_MODE)) {
+ String[] env = new String[envp.length + 1];
+ for (int i = 0; i < envp.length; i++)
+ env[i + 1] = envp[i];
+ env[0] = "XDEBUG_CONFIG=idekey=xdebug_test remote_enable=1";
+ envp = env;
+ }
+
+ String[] commandLine = (String[]) commandList
+ .toArray(new String[commandList.size()]);
+ Process process = DebugPlugin.exec(commandLine, null, envp);
+ IProcess p = DebugPlugin.newProcess(launch, process, phpInterpreter);
+ if (mode.equals(ILaunchManager.DEBUG_MODE)) {
+ IDebugTarget target = new XDebugTarget(launch, p, debugPort);
+ launch.addDebugTarget(target);
+ }
+ }
+
+ /**
+ * Throws an exception with a new status containing the given message and
+ * optional exception.
+ *
+ * @param message
+ * error message
+ * @param e
+ * underlying exception
+ * @throws CoreException
+ */
+ private void abort(String message, Throwable e) throws CoreException {
+ // TODO: the plug-in code should be the example plug-in, not Perl debug
+ // model id
+ throw new CoreException(new Status(IStatus.ERROR,
+ IXDebugConstants.ID_PHP_DEBUG_MODEL, 0, message, e));
+ }
+
+}
--- /dev/null
+package net.sourceforge.phpeclipse.xdebug.php.launching;
+
+import net.sourceforge.phpeclipse.xdebug.php.model.XDebugStackFrame;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupParticipant;
+
+public class PHPSourceLookupParticipant extends AbstractSourceLookupParticipant {
+
+ public String getSourceName(Object object) throws CoreException {
+ if (object instanceof XDebugStackFrame) {
+ return ((XDebugStackFrame) object).getSourceName();
+ }
+ return null;
+ }
+
+}
--- /dev/null
+/**
+ *
+ */
+package net.sourceforge.phpeclipse.xdebug.php.model;
+
+import net.sourceforge.phpeclipse.xdebug.core.Base64;
+import net.sourceforge.phpeclipse.xdebug.core.DebugConnection;
+import net.sourceforge.phpeclipse.xdebug.core.PHPDebugUtils;
+import net.sourceforge.phpeclipse.xdebug.core.XDebugCorePlugin;
+import net.sourceforge.phpeclipse.xdebug.core.DebugConnection.DebugResponse;
+import net.sourceforge.phpeclipse.xdebug.php.launching.IXDebugConstants;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IMarkerDelta;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.DebugEvent;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.IDebugEventSetListener;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.core.model.IDebugTarget;
+import org.eclipse.debug.core.model.ILineBreakpoint;
+import org.eclipse.debug.core.model.IMemoryBlock;
+import org.eclipse.debug.core.model.IProcess;
+import org.eclipse.debug.core.model.IStackFrame;
+import org.eclipse.debug.core.model.IThread;
+import org.eclipse.debug.core.model.IValue;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * @author Christian
+ *
+ */
+public class XDebugTarget extends XDebugElement implements IDebugTarget,
+ IDebugEventSetListener {
+ // associated system process (VM)
+ private IProcess fProcess;
+
+ // containing launch object
+ private ILaunch fLaunch;
+
+ // debugPort
+ private int fDebugPort;
+
+ // program name
+ // private String fName;
+
+ // suspend state
+ private boolean fSuspended = true;
+
+ // terminated state
+ private boolean fTerminated = false;
+
+ // threads
+ private XDebugThread fThread;
+
+ private IThread[] fThreads;
+
+ // event dispatch job
+ // private EventDispatchJob fEventDispatch;
+
+ private DebugConnection fDebugConnection;
+
+ // private DebugResponse lastResponse;
+
+ /**
+ * Constructs a new debug target in the given launch for the associated PDA
+ * VM process.
+ *
+ * @param launch
+ * containing launch
+ * @param debugPort
+ * port to read events from
+ * @exception CoreException
+ * if unable to connect to host
+ */
+ public XDebugTarget(ILaunch launch, IProcess process, int debugPort)
+ throws CoreException {
+ super(null);
+ fLaunch = launch;
+ fProcess = process;
+ fTarget = this;
+ fDebugConnection = new DebugConnection(this, debugPort);
+ fThread = new XDebugThread(this);
+ fThreads = new IThread[] { fThread };
+ DebugPlugin.getDefault().getBreakpointManager().addBreakpointListener(
+ this);
+ DebugPlugin.getDefault().addDebugEventListener(this);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.debug.core.model.IDebugTarget#getProcess()
+ */
+ public IProcess getProcess() {
+ return fProcess;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.debug.core.model.IDebugTarget#getThreads()
+ */
+ public IThread[] getThreads() throws DebugException {
+ return fThreads;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.debug.core.model.IDebugTarget#hasThreads()
+ */
+ public boolean hasThreads() throws DebugException {
+ return (fThreads.length > 0);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.debug.core.model.IDebugTarget#getName()
+ */
+ public String getName() throws DebugException {
+ return "PHP XDebug Client at localhost:" + fDebugPort;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.debug.core.model.IDebugTarget#supportsBreakpoint(org.eclipse.debug.core.model.IBreakpoint)
+ */
+ public boolean supportsBreakpoint(IBreakpoint breakpoint) {
+ if (breakpoint.getModelIdentifier().equals(
+ IXDebugConstants.ID_PHP_DEBUG_MODEL)) {
+ return true;
+ }
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.debug.core.model.IDebugElement#getDebugTarget()
+ */
+ public IDebugTarget getDebugTarget() {
+ return this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.debug.core.model.IDebugElement#getLaunch()
+ */
+ public ILaunch getLaunch() {
+ return fLaunch;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.debug.core.model.ITerminate#canTerminate()
+ */
+ public boolean canTerminate() {
+ return getProcess().canTerminate();
+ // return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.debug.core.model.ITerminate#isTerminated()
+ */
+ public boolean isTerminated() {
+ // return getProcess().isTerminated();
+ return fTerminated;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.debug.core.model.ITerminate#terminate()
+ */
+ public void terminate() throws DebugException {
+ fDebugConnection.sendRequest("stop");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.debug.core.model.ISuspendResume#canResume()
+ */
+ public boolean canResume() {
+ return !isTerminated() && isSuspended();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.debug.core.model.ISuspendResume#canSuspend()
+ */
+ public boolean canSuspend() {
+ return !isTerminated() && !isSuspended();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.debug.core.model.ISuspendResume#isSuspended()
+ */
+ public boolean isSuspended() {
+ return fSuspended;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.debug.core.model.ISuspendResume#resume()
+ */
+ public void resume() throws DebugException {
+ fDebugConnection.sendRequest("run");
+ }
+
+ /**
+ * Notification the target has resumed for the given reason
+ *
+ * @param detail
+ * reason for the resume
+ */
+ private void resumed(int detail) {
+ fSuspended = false;
+ fThread.fireResumeEvent(detail);
+ }
+
+ /**
+ * Notification the target has suspended for the given reason
+ *
+ * @param detail
+ * reason for the suspend
+ */
+ public void suspended(int detail) {
+ fSuspended = true;
+ fThread.fireSuspendEvent(detail);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.debug.core.model.ISuspendResume#suspend()
+ */
+ public void suspend() throws DebugException {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.debug.core.IBreakpointListener#breakpointAdded(org.eclipse.debug.core.model.IBreakpoint)
+ */
+ public void breakpointAdded(IBreakpoint breakpoint) {
+
+ if (supportsBreakpoint(breakpoint)) {
+ try {
+ if (breakpoint.isEnabled()) {
+ IMarker marker = breakpoint.getMarker();
+ if (marker != null) {
+ try {
+ String fileName = PHPDebugUtils.escapeString(marker
+ .getResource().getLocation().toString());
+ String arg = "-t line -f file:///"
+ + fileName
+ + " -n "
+ + ((ILineBreakpoint) breakpoint)
+ .getLineNumber();
+ int id = fDebugConnection.sendRequest(
+ "breakpoint_set", arg);
+ // set the marker Attribute to make later
+ // idetification possible
+ // TODO: make sure that attribute is set before
+ // response from debugger is beeing prosessed
+ marker.setAttribute(
+ XDebugLineBreakpoint.BREAKPOINT_ID, id);
+
+ } catch (CoreException e) {
+ }
+ }
+ }
+ } catch (CoreException e) {
+
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.debug.core.IBreakpointListener#breakpointRemoved(org.eclipse.debug.core.model.IBreakpoint,
+ * org.eclipse.core.resources.IMarkerDelta)
+ */
+ public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta delta) {
+ if (supportsBreakpoint(breakpoint)) {
+ try {
+ int id = ((XDebugLineBreakpoint) breakpoint).getID();
+ if (id > 0)
+ fDebugConnection.sendRequest("breakpoint_remove", "-d "
+ + id);
+ } catch (CoreException e) {
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.debug.core.IBreakpointListener#breakpointChanged(org.eclipse.debug.core.model.IBreakpoint,
+ * org.eclipse.core.resources.IMarkerDelta)
+ */
+ public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta) {
+ // if (supportsBreakpoint(breakpoint)) {
+ // try {
+ // if (breakpoint.isEnabled()) {
+ // breakpointAdded(breakpoint);
+ // } else {
+ // breakpointRemoved(breakpoint, null);
+ // }
+ // } catch (CoreException e) {
+ // }
+ // }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.debug.core.model.IDisconnect#canDisconnect()
+ */
+ public boolean canDisconnect() {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.debug.core.model.IDisconnect#disconnect()
+ */
+ public void disconnect() throws DebugException {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.debug.core.model.IDisconnect#isDisconnected()
+ */
+ public boolean isDisconnected() {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.debug.core.model.IMemoryBlockRetrieval#supportsStorageRetrieval()
+ */
+ public boolean supportsStorageRetrieval() {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.debug.core.model.IMemoryBlockRetrieval#getMemoryBlock(long,
+ * long)
+ */
+ public IMemoryBlock getMemoryBlock(long startAddress, long length)
+ throws DebugException {
+ return null;
+ }
+
+ /**
+ * Notification we have connected to the PHP debugger and it has started.
+ * Resume the the debugger.
+ */
+ public void started() {
+
+ fThread.setBreakpoints(null);
+ fThread.setStepping(false);
+
+ installDeferredBreakpoints();
+ try {
+ resume();
+ // step();
+ } catch (DebugException e) {
+ }
+ }
+
+ /**
+ * Install breakpoints that are already registered with the breakpoint
+ * manager.
+ */
+ private void installDeferredBreakpoints() {
+ IBreakpoint[] breakpoints = XDebugCorePlugin.getBreakpoints();
+ for (int i = 0; i < breakpoints.length; i++) {
+ breakpointAdded(breakpoints[i]);
+ }
+ }
+
+ /**
+ * Called when this debug target terminates.
+ */
+ public void terminated() {
+ fTerminated = true;
+ fSuspended = false;
+ XDebugCorePlugin.getBreakpointManager().removeBreakpointListener(this);
+ fireTerminateEvent();
+ DebugPlugin.getDefault().removeDebugEventListener(this);
+ fThread.removeEventListeners();
+ }
+
+ /**
+ * Returns the current stack frames in the target.
+ *
+ * @return the current stack frames in the target
+ * @throws DebugException
+ * if unable to perform the request
+ */
+ protected IStackFrame[] getStackFrames() throws DebugException {
+ int id = fDebugConnection.sendRequest("stack_get");
+ DebugResponse lastResponse = fDebugConnection.waitforTransID(id);
+ if (lastResponse.isError())
+ return new IStackFrame[0];
+ Node response = lastResponse.getParentNode();
+ NodeList frames = response.getChildNodes();
+ IStackFrame[] theFrames = new IStackFrame[frames.getLength()];
+ for (int i = 0; i < frames.getLength(); i++) {
+ Node stackNode = frames.item(i);
+ theFrames[i] = new XDebugStackFrame(fThread, stackNode, i);
+ }
+ return theFrames;
+ }
+
+ /**
+ * Single step the interpreter.
+ *
+ * @throws DebugException
+ * if the request fails
+ */
+ protected void step_over() throws DebugException {
+ fThread.setStepping(true);
+ resumed(DebugEvent.STEP_OVER);
+ fDebugConnection.sendRequest("step_over");
+ }
+
+ /**
+ * Single step the interpreter.
+ *
+ * @throws DebugException
+ * if the request fails
+ */
+ protected void step_into() throws DebugException {
+ fThread.setStepping(true);
+ resumed(DebugEvent.STEP_INTO);
+ fDebugConnection.sendRequest("step_into");
+ }
+
+ /**
+ * Single step the interpreter.
+ *
+ * @throws DebugException
+ * if the request fails
+ */
+ protected void step_out() throws DebugException {
+ fThread.setStepping(true);
+ resumed(DebugEvent.STEP_RETURN);
+ fDebugConnection.sendRequest("step_out");
+ }
+
+ /**
+ * Returns the current value of the given variable.
+ *
+ * @param variable
+ * @return variable value
+ * @throws DebugException
+ * if the request fails
+ */
+ protected IValue getVariableValue(XDebugVariable variable)
+ throws DebugException {
+ // synchronized (fDebugSocket) {
+ // fDebugConnection.sendRequest("var","" +
+ // variable.getStackFrame().getIdentifier() + " " + variable.getName());
+ // try {
+ // String value = fDebugReader.readLine();
+ // //return new XDebugValue(this, value);
+ //
+ // } catch (IOException e) {
+ // abort(MessageFormat.format("Unable to retrieve value for variable
+ // {0}", new String[]{variable.getName()}), e);
+ // }
+ // }
+ return null;
+ }
+
+ /**
+ * Returns the values on the data stack (top down)
+ *
+ * @return the values on the data stack (top down)
+ */
+ public IValue[] getDataStack() throws DebugException {
+ // synchronized (fDebugSocket) {
+ // fDebugConnection.sendRequest ("data");
+ // try {
+ // String valueString = fDebugReader.readLine();
+ // if (valueString != null && valueString.length() > 0) {
+ // String[] values = valueString.split("\\|");
+ // IValue[] theValues = new IValue[values.length];
+ // for (int i = 0; i < values.length; i++) {
+ // String value = values[values.length - i - 1];
+ // // theValues[i] = new XDebugValue(this, value);
+ // }
+ // return theValues;
+ // }
+ // } catch (IOException e) {
+ // abort("Unable to retrieve data stack", e);
+ // }
+ // }
+ return new IValue[0];
+ }
+
+ public boolean setVarValue(String name, String value) {
+ int id = -1;
+ String str = Base64.encodeBytes(value.getBytes());
+ int len = str.length();
+
+ try {
+ id = fDebugConnection.sendRequest("property_set", "-n " + name
+ + " -l " + len + " -- " + str);
+ } catch (DebugException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ DebugResponse dr = getResponse(id);
+ if ((dr.getAttributeValue("success")).equals("1"))
+ return true;
+
+ return false;
+ }
+
+ public DebugResponse getResponse(int id) {
+ return fDebugConnection.waitforTransID(id);
+ }
+
+ /**
+ * Sends a request to the Debugengine and waits for an OK.
+ *
+ * @param command
+ * debug command
+ * @throws DebugException
+ * if the request fails
+ */
+
+ public int sendRequest(String command) throws DebugException {
+ return fDebugConnection.sendRequest(command, "");
+ }
+
+ /**
+ * Sends a request to the Debugengine and waits for an OK.
+ *
+ * @param command
+ * debug command
+ * @arguments arguments for the command
+ * @throws DebugException
+ * if the request fails
+ */
+
+ public int sendRequest(String command, String arguments)
+ throws DebugException {
+ return fDebugConnection.sendRequest(command, arguments);
+ }
+
+ /**
+ * Notification a breakpoint was encountered. Determine which breakpoint was
+ * hit and fire a suspend event.
+ *
+ * @param event
+ * debug event
+ */
+ public void breakpointHit(Node node) {
+ // determine which breakpoint was hit, and set the thread's breakpoint
+ Node child = node.getFirstChild();
+ if (child.getNodeName().equals("stack")) {
+ int lineNumber = Integer.parseInt(PHPDebugUtils.getAttributeValue(
+ child, "lineno"));
+ String filename = PHPDebugUtils
+ .getAttributeValue(child, "filename").substring(8); // remove
+ // file:///
+ IBreakpoint[] breakpoints = XDebugCorePlugin.getBreakpoints();
+ for (int i = 0; i < breakpoints.length; i++) {
+ IBreakpoint breakpoint = breakpoints[i];
+ if (supportsBreakpoint(breakpoint)) {
+ if (breakpoint instanceof ILineBreakpoint) {
+ ILineBreakpoint lineBreakpoint = (ILineBreakpoint) breakpoint;
+ try {
+ if (breakpoint.isEnabled()) {
+ IMarker marker = breakpoint.getMarker();
+ if (marker != null) {
+
+ String name = marker.getResource()
+ .getLocation().toOSString();
+ if (name.equals(PHPDebugUtils
+ .unescapeString(filename))
+ && (lineBreakpoint.getLineNumber() == lineNumber)) {
+ fThread
+ .setBreakpoints(new IBreakpoint[] { breakpoint });
+ break;
+ }
+ }
+
+ }
+ } catch (CoreException e) {
+ }
+ }
+ }
+ }
+ }
+ suspended(DebugEvent.BREAKPOINT);
+ }
+
+ public void handleDebugEvents(DebugEvent[] events) {
+ for (int i = 0; i < events.length; i++) {
+ DebugEvent event = events[i];
+ if ((event.getKind() == DebugEvent.CREATE)
+ && (event.getSource() instanceof XDebugElement)) {
+ if (((XDebugElement) event.getSource()).getModelIdentifier() == IXDebugConstants.ID_PHP_DEBUG_MODEL) {
+ if (event.getKind() == DebugEvent.CREATE)
+ started();
+ }
+ }
+ }
+
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2004 Christopher Lenz 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:
+ * Christopher Lenz - initial API
+ *
+ * $Id: XMLDocument.java,v 1.2 2006-10-21 23:13:43 pombredanne Exp $
+ */
+
+package net.sourceforge.phpeclipse.xml.core.internal.model;
+
+import net.sourceforge.phpeclipse.core.model.SourceReference;
+import net.sourceforge.phpeclipse.xml.core.internal.parser.XMLParser;
+import net.sourceforge.phpeclipse.xml.core.model.IXMLDocument;
+import net.sourceforge.phpeclipse.xml.core.model.IXMLElement;
+import net.sourceforge.phpeclipse.xml.core.parser.IProblemCollector;
+import net.sourceforge.phpeclipse.xml.core.parser.IXMLParser;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentListener;
+
+/**
+ *
+ */
+public class XMLDocument extends SourceReference implements IXMLDocument,
+ IDocumentListener {
+ // Instance Variables ------------------------------------------------------
+
+ private IXMLElement root;
+
+ private String systemId;
+
+ private Object dirtyLock = new Object();
+
+ private boolean dirty = true;
+
+ // Constructors ------------------------------------------------------------
+
+ public XMLDocument(IDocument document, String systemId) {
+ super(document, 0, document.getLength());
+ this.systemId = systemId;
+ }
+
+ // IXMLDocument Implementation ---------------------------------------------
+
+ /*
+ * @see IXMLDocument#getRoot()
+ */
+ public IXMLElement getRoot() {
+ return root;
+ }
+
+ /*
+ * @see net.sourceforge.phpeclipse.xml.core.model.IXMLDocument#getSystemId()
+ */
+ public String getSystemId() {
+ return systemId;
+ }
+
+ /*
+ * @see IStyleSheet#reconcile(IProblemCollector)
+ */
+ public void reconcile(IProblemCollector problemCollector, IFile file) {
+ synchronized (dirtyLock) {
+ if (!dirty) {
+ return;
+ }
+ dirty = false;
+ }
+
+ synchronized (this) {
+ boolean doParse = false;
+ root = null;
+ if (file != null) {
+ String filename = file.getLocation().toString();
+ int len = filename.length();
+ if (len >= 4) {
+ if ((filename.charAt(len - 1) != 'l' && filename
+ .charAt(len - 1) != 'L')
+ || (filename.charAt(len - 2) != 'p' && filename
+ .charAt(len - 2) != 'P')
+ || (filename.charAt(len - 3) != 't' && filename
+ .charAt(len - 3) != 'T')
+ || (filename.charAt(len - 4) != '.')) {
+ if ((filename.charAt(len - 1) != 'm' && filename
+ .charAt(len - 1) != 'M')
+ || (filename.charAt(len - 2) != 't' && filename
+ .charAt(len - 2) != 'T')
+ || (filename.charAt(len - 3) != 'h' && filename
+ .charAt(len - 3) != 'H')
+ || (filename.charAt(len - 4) != '.')) {
+ if (len >= 5) {
+ if ((filename.charAt(len - 1) != 'l' && filename
+ .charAt(len - 1) != 'L')
+ || (filename.charAt(len - 2) != 'm' && filename
+ .charAt(len - 2) != 'M')
+ || (filename.charAt(len - 3) != 't' && filename
+ .charAt(len - 3) != 'T')
+ || (filename.charAt(len - 4) != 'h' && filename
+ .charAt(len - 4) != 'H')
+ || (filename.charAt(len - 5) != '.')) {
+ doParse = true;
+ }
+ }
+ }
+ }
+ } else {
+ doParse = true;
+ }
+ }
+ if (doParse) {
+ IXMLParser parser = new XMLParser();
+ parser.setProblemCollector(problemCollector);
+ parser.setSource(getDocument());
+ parser.setSystemId(systemId);
+ IXMLDocument model = parser.parse();
+ if (model != null) {
+ root = model.getRoot();
+ }
+ }
+ }
+ }
+
+ // IDocumentListener Implementation ----------------------------------------
+
+ /*
+ * @see IDocumentListener#documentAboutToBeChanged(DocumentEvent)
+ */
+ public void documentAboutToBeChanged(DocumentEvent event) {
+ // do nothing
+ }
+
+ /*
+ * @see IDocumentListener#documentChanged(DocumentEvent)
+ */
+ public void documentChanged(DocumentEvent event) {
+ synchronized (dirtyLock) {
+ dirty = true;
+ }
+ }
+
+ // Public Methods ----------------------------------------------------------
+
+ /**
+ * Sets the root element.
+ *
+ * @param root
+ * the root element to set
+ */
+ public void setRoot(IXMLElement root) {
+ this.root = root;
+ }
+
+}
\ No newline at end of file