Package org.eclipse.php.internal.core.codeassist.contexts

Source Code of org.eclipse.php.internal.core.codeassist.contexts.AbstractCompletionContext

/*******************************************************************************
* Copyright (c) 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     IBM Corporation - initial API and implementation
*     Zend Technologies
*******************************************************************************/
package org.eclipse.php.internal.core.codeassist.contexts;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.dltk.core.CompletionRequestor;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.php.core.codeassist.ICompletionContext;
import org.eclipse.php.internal.core.PHPCorePlugin;
import org.eclipse.php.internal.core.PHPVersion;
import org.eclipse.php.internal.core.codeassist.CompletionCompanion;
import org.eclipse.php.internal.core.codeassist.IPHPCompletionRequestor;
import org.eclipse.php.internal.core.documentModel.parser.PHPRegionContext;
import org.eclipse.php.internal.core.documentModel.parser.regions.IPhpScriptRegion;
import org.eclipse.php.internal.core.documentModel.parser.regions.PHPRegionTypes;
import org.eclipse.php.internal.core.documentModel.partitioner.PHPPartitionTypes;
import org.eclipse.php.internal.core.project.ProjectOptions;
import org.eclipse.php.internal.core.util.text.PHPTextSequenceUtilities;
import org.eclipse.php.internal.core.util.text.TextSequence;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.exceptions.ResourceAlreadyExists;
import org.eclipse.wst.sse.core.internal.provisional.text.*;

/**
* This is an abstract completion context containing all common utilities.
*
* @author michael
*/
public abstract class AbstractCompletionContext implements ICompletionContext {

  public static final int NONE = 0;
  public static final int TRAIT_NAME = 1;
  public static final int TRAIT_KEYWORD = 2;
  private CompletionCompanion companion;
  private CompletionRequestor requestor;
  private ISourceModule sourceModule;
  private int offset;
  private PHPVersion phpVersion;
  private IStructuredDocument document;
  private IStructuredDocumentRegion structuredDocumentRegion;
  private ITextRegionCollection regionCollection;
  private IPhpScriptRegion phpScriptRegion;
  private String partitionType;

  public void init(CompletionCompanion companion) {
    this.companion = companion;
  }

  protected CompletionCompanion getCompanion() {
    return companion;
  }

  public boolean isValid(ISourceModule sourceModule, int offset,
      CompletionRequestor requestor) {
    if (sourceModule == null) {
      throw new IllegalArgumentException();
    }

    this.requestor = requestor;
    this.sourceModule = sourceModule;
    this.offset = offset;
    this.phpVersion = ProjectOptions.getPhpVersion(sourceModule
        .getScriptProject().getProject());

    try {
      this.document = determineDocument(sourceModule, requestor);
      if (this.document != null) {

        structuredDocumentRegion = determineStructuredDocumentRegion(
            document, offset);
        if (structuredDocumentRegion != null) {

          regionCollection = determineRegionCollection(document,
              structuredDocumentRegion, offset);
          if (regionCollection != null) {

            phpScriptRegion = determinePhpRegion(document,
                regionCollection, offset);
            if (phpScriptRegion != null) {

              partitionType = determinePartitionType(
                  regionCollection, phpScriptRegion, offset);
              if (partitionType != null) {

                String prefix = getPrefix();
                if (prefix.length() > 0
                    && !Character
                        .isJavaIdentifierStart(prefix
                            .charAt(0))) {
                  return false;
                }
                return true;
              }
            }
          }
        }
      }

    } catch (Exception e) {
      PHPCorePlugin.log(e);
    }
    return false;
  }

  public boolean isExclusive() {
    return false;
  }

  /**
   * Determines the structured document region of the place in PHP code where
   * completion was requested
   *
   * @return structured document region or <code>null</code> in case it could
   *         not be determined
   */
  protected IStructuredDocumentRegion determineStructuredDocumentRegion(
      IStructuredDocument document, int offset) {

    IStructuredDocumentRegion sdRegion = null;

    int lastOffset = offset;
    // find the structured document region:
    while (sdRegion == null && lastOffset >= 0) {
      sdRegion = document.getRegionAtCharacterOffset(lastOffset);
      lastOffset--;
    }

    return sdRegion;
  }

  /**
   * Determines the relevant region collection of the place in PHP code where
   * completion was requested
   *
   * @return text region collection or <code>null</code> in case it could not
   *         be determined
   */
  protected ITextRegionCollection determineRegionCollection(
      IStructuredDocument document, IStructuredDocumentRegion sdRegion,
      int offset) {
    ITextRegionCollection regionCollection = sdRegion;

    ITextRegion textRegion = determineTextRegion(document, sdRegion, offset);
    if (textRegion instanceof ITextRegionContainer) {
      regionCollection = (ITextRegionContainer) textRegion;
    }
    return regionCollection;
  }

  /**
   * Determines the text region from the text region collection and offset
   *
   * @param regionCollection
   * @param offset
   */
  protected ITextRegion determineTextRegion(IStructuredDocument document,
      ITextRegionCollection regionCollection, int offset) {
    ITextRegion textRegion;
    // in case we are at the end of the document, asking for completion
    if (offset == document.getLength()) {
      textRegion = regionCollection.getLastRegion();
    } else {
      textRegion = regionCollection.getRegionAtCharacterOffset(offset);
    }
    return textRegion;
  }

  /**
   * Determines the PHP script region of PHP code where completion was
   * requested
   *
   * @return php script region or <code>null</code> in case it could not be
   *         determined
   */
  protected IPhpScriptRegion determinePhpRegion(IStructuredDocument document,
      ITextRegionCollection regionCollection, int offset) {
    ITextRegion textRegion = determineTextRegion(document,
        regionCollection, offset);
    IPhpScriptRegion phpScriptRegion = null;

    if (textRegion != null) {
      if (textRegion.getType() == PHPRegionContext.PHP_OPEN) {
        return null;
      } else if (textRegion.getType() == PHPRegionContext.PHP_CLOSE) {
        if (regionCollection.getStartOffset(textRegion) == offset) {
          textRegion = regionCollection
              .getRegionAtCharacterOffset(offset - 1);
        } else {
          return null;
        }
      }
    }

    if (textRegion instanceof IPhpScriptRegion) {
      phpScriptRegion = (IPhpScriptRegion) textRegion;
    }

    return phpScriptRegion;
  }

  /**
   * Determines the partition type of the code where cursor is located.
   *
   * @param regionCollection
   *            Text region collection
   * @param phpScriptRegion
   *            PHP script region
   * @param offset
   * @return partition type (see {@link PHPRegionTypes})
   * @throws BadLocationException
   */
  protected String determinePartitionType(
      ITextRegionCollection regionCollection,
      IPhpScriptRegion phpScriptRegion, int offset)
      throws BadLocationException {
    int internalOffset = getOffset(offset, regionCollection,
        phpScriptRegion);
    String partitionType = phpScriptRegion.getPartition(internalOffset);

    // if we are at the begining of multi-line comment or docBlock then we
    // should get completion.
    if (partitionType == PHPPartitionTypes.PHP_MULTI_LINE_COMMENT
        || partitionType == PHPPartitionTypes.PHP_DOC) {
      String regionType = phpScriptRegion.getPhpToken(internalOffset)
          .getType();
      if (regionType == PHPRegionTypes.PHP_COMMENT_START
          || regionType == PHPRegionTypes.PHPDOC_COMMENT_START) {
        if (phpScriptRegion.getPhpToken(internalOffset).getStart() == internalOffset) {
          partitionType = phpScriptRegion
              .getPartition(internalOffset - 1);
        }
      }
    }
    return partitionType;
  }

  /**
   * Determines the document associated with the editor where code assist has
   * been invoked.
   *
   * @param module
   *            Source module ({@link ISourceModule})
   * @param requestor
   *            Completion requestor ({@link CompletionRequestor})
   * @return structured document or <code>null</code> if it couldn't be found
   * @throws CoreException
   * @throws IOException
   * @throws ResourceAlreadyExists
   */
  protected IStructuredDocument determineDocument(ISourceModule module,
      CompletionRequestor requestor) throws ResourceAlreadyExists,
      IOException, CoreException {
    IStructuredDocument document = null;

    if (requestor instanceof IPHPCompletionRequestor) {
      IDocument d = ((IPHPCompletionRequestor) requestor).getDocument();
      if (d instanceof IStructuredDocument) {
        document = (IStructuredDocument) d;
      }
    }
    if (document == null) {
      IStructuredModel structuredModel = null;
      try {
        IFile file = (IFile) module.getResource();
        if (file != null) {
          if (file.exists()) {
            structuredModel = StructuredModelManager
                .getModelManager()
                .getExistingModelForRead(file);
            if (structuredModel != null) {
              document = structuredModel.getStructuredDocument();
            } else {
              document = StructuredModelManager.getModelManager()
                  .createStructuredDocumentFor(file);
            }
          } else {
            document = StructuredModelManager.getModelManager()
                .createNewStructuredDocumentFor(file);
            document.set(module.getSource());
          }
        }
      } finally {
        if (structuredModel != null) {
          structuredModel.releaseFromRead();
        }
      }
    }

    return document;
  }

  /**
   * Returns PHP version of the file where code assist was requested
   *
   * @return PHP version
   * @see #isValid(ISourceModule, int, CompletionRequestor)
   */
  public PHPVersion getPhpVersion() {
    return phpVersion;
  }

  /**
   * Returns the file where code assist was requested
   *
   * @return source module
   * @see #isValid(ISourceModule, int, CompletionRequestor)
   */
  public ISourceModule getSourceModule() {
    return sourceModule;
  }

  /**
   * Returns document associated with the editor where code assist was
   * requested
   *
   * @return document
   * @see #isValid(ISourceModule, int, CompletionRequestor)
   */
  public IStructuredDocument getDocument() {
    return document;
  }

  /**
   * Returns the relevant region collection of the place in PHP code where
   * completion was requested
   *
   * @return text region collection
   * @see #isValid(ISourceModule, int, CompletionRequestor)
   */
  public ITextRegionCollection getRegionCollection() {
    return regionCollection;
  }

  /**
   * Returns the PHP script region of PHP code where completion was requested
   *
   * @return php script region (see {@link IPhpScriptRegion})
   * @see #isValid(ISourceModule, int, CompletionRequestor)
   */
  public IPhpScriptRegion getPhpScriptRegion() {
    return phpScriptRegion;
  }

  /**
   * Returns partition type of the code where cursor is located.
   *
   * @return partition type (see {@link PHPRegionTypes})
   * @see #isValid(ISourceModule, int, CompletionRequestor)
   */
  public String getPartitionType() {
    return partitionType;
  }

  /**
   * Returns the statement text that is before the cursor
   *
   * @return statement text
   * @see #isValid(ISourceModule, int, CompletionRequestor)
   */
  public TextSequence getStatementText() {
    return PHPTextSequenceUtilities.getStatement(offset,
        structuredDocumentRegion, true);
  }

  public TextSequence getStatementText(int offset) {
    return PHPTextSequenceUtilities.getStatement(offset,
        structuredDocumentRegion, true);
  }

  /**
   * Returns whether there are whitespace characters before the cursor where
   * code assist was being invoked
   *
   * @return <code>true</code> if there are whitespace characters before the
   *         cursor
   */
  public boolean hasWhitespaceBeforeCursor() {
    TextSequence statementText = getStatementText();

    // determine whether there are whitespaces before the cursor
    int statementLength = statementText.length();
    int statementEnd = PHPTextSequenceUtilities.readBackwardSpaces(
        statementText, statementLength);
    return statementLength != statementEnd;
  }

  /**
   * Returns completion requestor
   *
   * @return completion requestor (see {@link CompletionRequestor})
   * @see #isValid(ISourceModule, int, CompletionRequestor)
   */
  public CompletionRequestor getCompletionRequestor() {
    return requestor;
  }

  /**
   * Returns offset of the cursor position when code assist was invoked
   *
   * @return offset
   */
  public int getOffset() {
    return offset;
  }

  /**
   * Returns previous word before the cursor position
   *
   * @throws BadLocationException
   */
  public String getPreviousWord() throws BadLocationException {
    TextSequence statementText = getStatementText();

    int statementLength = statementText.length();
    int wordEnd = PHPTextSequenceUtilities.readBackwardSpaces(
        statementText, statementLength); // read whitespace
    int wordStart = PHPTextSequenceUtilities.readIdentifierStartIndex(
        phpVersion, statementText, wordEnd, true);
    if (wordStart < 0 || wordEnd < 0 || wordStart > wordEnd) {
      return ""; //$NON-NLS-1$
    }
    String previousWord = statementText.subSequence(wordStart, wordEnd)
        .toString();

    if (hasWhitespaceBeforeCursor()) {
      return previousWord;
    }

    wordEnd = PHPTextSequenceUtilities.readBackwardSpaces(statementText,
        wordStart - 1); // read whitespace
    wordStart = PHPTextSequenceUtilities.readIdentifierStartIndex(
        phpVersion, statementText, wordEnd, true);
    if (wordStart < 0 || wordEnd < 0 || wordStart > wordEnd) {
      return ""; //$NON-NLS-1$
    }
    previousWord = statementText.subSequence(wordStart, wordEnd).toString();

    return previousWord;
  }

  /**
   * Returns previous word before the cursor position
   *
   * @throws BadLocationException
   */
  public String getPreviousWord(int times) throws BadLocationException {
    TextSequence statementText = getStatementText();

    int statementLength = statementText.length();
    int wordEnd = PHPTextSequenceUtilities.readBackwardSpaces(
        statementText, statementLength); // read whitespace
    int wordStart = PHPTextSequenceUtilities.readIdentifierStartIndex(
        phpVersion, statementText, wordEnd, true);

    for (int i = 0; i < times - 1; i++) {
      statementLength = wordStart;
      wordEnd = PHPTextSequenceUtilities.readBackwardSpaces(
          statementText, statementLength); // read whitespace
      wordStart = PHPTextSequenceUtilities.readIdentifierStartIndex(
          phpVersion, statementText, wordEnd, true);

    }
    if (wordStart < 0 || wordEnd < 0 || wordStart > wordEnd) {
      return ""; //$NON-NLS-1$
    }
    String previousWord = statementText.subSequence(wordStart, wordEnd)
        .toString();

    if (hasWhitespaceBeforeCursor()) {
      return previousWord;
    }

    wordEnd = PHPTextSequenceUtilities.readBackwardSpaces(statementText,
        wordStart - 1); // read whitespace
    wordStart = PHPTextSequenceUtilities.readIdentifierStartIndex(
        phpVersion, statementText, wordEnd, true);
    if (wordStart < 0 || wordEnd < 0 || wordStart > wordEnd) {
      return ""; //$NON-NLS-1$
    }
    previousWord = statementText.subSequence(wordStart, wordEnd).toString();

    return previousWord;
  }

  /**
   * Returns previous word before the cursor position
   *
   * @throws BadLocationException
   */
  public int getPreviousWordOffset(int times) throws BadLocationException {
    TextSequence statementText = getStatementText();

    int statementLength = statementText.length();
    int wordEnd = PHPTextSequenceUtilities.readBackwardSpaces(
        statementText, statementLength); // read whitespace
    int wordStart = PHPTextSequenceUtilities.readIdentifierStartIndex(
        phpVersion, statementText, wordEnd, true);

    for (int i = 0; i < times - 1; i++) {
      statementLength = wordStart;
      wordEnd = PHPTextSequenceUtilities.readBackwardSpaces(
          statementText, statementLength); // read whitespace
      wordStart = PHPTextSequenceUtilities.readIdentifierStartIndex(
          phpVersion, statementText, wordEnd, true);

    }
    if (wordStart < 0 || wordEnd < 0 || wordStart > wordEnd) {
      return wordStart;
    }

    if (hasWhitespaceBeforeCursor()) {
      return wordStart;
    }

    wordEnd = PHPTextSequenceUtilities.readBackwardSpaces(statementText,
        wordStart - 1); // read whitespace
    wordStart = PHPTextSequenceUtilities.readIdentifierStartIndex(
        phpVersion, statementText, wordEnd, true);
    // if (wordStart < 0 || wordEnd < 0 || wordStart > wordEnd) {
    // return wordStart;
    // }

    return wordStart;
  }

  /**
   * Returns PHP token under offset
   *
   * @return PHP token
   * @throws BadLocationException
   */
  public ITextRegion getPHPToken() throws BadLocationException {
    return getPHPToken(offset);
  }

  public ITextRegion getPHPToken(int offset) throws BadLocationException {
    return phpScriptRegion.getPhpToken(getOffset(offset, regionCollection,
        phpScriptRegion));
  }

  private int getOffset(int offset, ITextRegionCollection regionCollection,
      IPhpScriptRegion phpScriptRegion) {
    int result = offset - regionCollection.getStartOffset()
        - phpScriptRegion.getStart() - 1;
    if (result < 0) {
      result = 0;
    }
    return result;
  }

  /**
   * Returns the word on which code assist was invoked
   *
   * @return prefix
   * @throws BadLocationException
   */
  public String getPrefix() throws BadLocationException {
    return getPrefixWithoutProcessing();
  }

  public String getPrefixWithoutProcessing() {
    if (hasWhitespaceBeforeCursor()) {
      return ""; //$NON-NLS-1$
    }
    TextSequence statementText = getStatementText();
    int statementLength = statementText.length();
    int prefixEnd = PHPTextSequenceUtilities.readBackwardSpaces(
        statementText, statementLength); // read whitespace
    int prefixStart = PHPTextSequenceUtilities.readIdentifierStartIndex(
        phpVersion, statementText, prefixEnd, true);
    return statementText.subSequence(prefixStart, prefixEnd).toString();
  }

  /**
   * Returns the end of the word on which code assist was invoked
   *
   * @return
   * @throws BadLocationException
   */
  public int getPrefixEnd() throws BadLocationException {
    ITextRegion phpToken = getPHPToken();
    int endOffset = regionCollection.getStartOffset()
        + phpScriptRegion.getStart() + phpToken.getTextEnd();
    if (phpToken.getType() == PHPRegionTypes.PHP_CONSTANT_ENCAPSED_STRING) {
      --endOffset;
    }
    return endOffset;
  }

  /**
   * Returns next PHP token after offset
   *
   * @return PHP token
   * @throws BadLocationException
   */
  public ITextRegion getNextPHPToken() throws BadLocationException {
    ITextRegion phpToken = getPHPToken();
    do {
      phpToken = phpScriptRegion.getPhpToken(phpToken.getEnd());
      if (!PHPPartitionTypes.isPHPCommentState(phpToken.getType())
          && phpToken.getType() != PHPRegionTypes.WHITESPACE) {
        break;
      }
    } while (phpToken.getEnd() < phpScriptRegion.getLength());

    return phpToken;
  }

  public ITextRegion getNextPHPToken(int times) throws BadLocationException {
    ITextRegion phpToken = null;
    int offset = this.offset;
    while (times-- > 0) {
      phpToken = getPHPToken(offset);
      do {
        phpToken = phpScriptRegion.getPhpToken(phpToken.getEnd());
        if (!PHPPartitionTypes.isPHPCommentState(phpToken.getType())
            && phpToken.getType() != PHPRegionTypes.WHITESPACE) {
          break;
        }
      } while (phpToken.getEnd() < phpScriptRegion.getLength());
      if (phpToken == null) {
        return null;
      } else {
        offset = regionCollection.getStartOffset()
            + phpScriptRegion.getStart() + phpToken.getEnd();
      }
    }

    return phpToken;
  }

  /**
   * Returns next word after the cursor position
   *
   * @throws BadLocationException
   */
  public String getNextWord() throws BadLocationException {
    ITextRegion nextPHPToken = getNextPHPToken();
    return document
        .get(regionCollection.getStartOffset()
            + phpScriptRegion.getStart() + nextPHPToken.getStart(),
            nextPHPToken.getTextLength());
  }

  public String getNextWord(int times) throws BadLocationException {
    ITextRegion nextPHPToken = getNextPHPToken(times);
    return document
        .get(regionCollection.getStartOffset()
            + phpScriptRegion.getStart() + nextPHPToken.getStart(),
            nextPHPToken.getTextLength());
  }

  /**
   * Returns next word after the cursor position
   *
   * @throws BadLocationException
   */
  public char getNextChar() throws BadLocationException {
    // if the current location is the end of the document,we return ' ' to
    // avoid the BadLocationException
    if (document.getLength() == offset) {
      return ' ';
    }
    return document.getChar(offset);
  }

  public int getUseTraitStatementContext() {
    return getUseTraitStatementContext(offset, structuredDocumentRegion);
  }

  public int getUseTraitStatementContext(int offset,
      IStructuredDocumentRegion sdRegion) {
    List<String> types = new ArrayList<String>();
    if (sdRegion == null) {
      sdRegion = structuredDocumentRegion;
    }
    int documentOffset = offset;
    if (documentOffset == sdRegion.getEndOffset()) {
      documentOffset -= 1;
    }
    ITextRegion tRegion = sdRegion
        .getRegionAtCharacterOffset(documentOffset);

    ITextRegionCollection container = sdRegion;

    if (tRegion instanceof ITextRegionContainer) {
      container = (ITextRegionContainer) tRegion;
      tRegion = container.getRegionAtCharacterOffset(offset);
    }
    if (tRegion != null && tRegion.getType() == PHPRegionContext.PHP_CLOSE) {
      tRegion = container.getRegionAtCharacterOffset(container
          .getStartOffset() + tRegion.getStart() - 1);
    }

    // This text region must be of type PhpScriptRegion:
    if (tRegion != null
        && tRegion.getType() == PHPRegionContext.PHP_CONTENT) {
      IPhpScriptRegion phpScriptRegion = (IPhpScriptRegion) tRegion;

      try {
        // Set default starting position to the beginning of the
        // PhpScriptRegion:
        int startOffset = container.getStartOffset()
            + phpScriptRegion.getStart();

        // Now, search backwards for the statement start (in this
        // PhpScriptRegion):
        ITextRegion startTokenRegion;
        if (documentOffset == startOffset) {
          startTokenRegion = phpScriptRegion.getPhpToken(0);
        } else {
          startTokenRegion = phpScriptRegion.getPhpToken(offset
              - startOffset - 1);
        }
        // If statement start is at the beginning of the PHP script
        // region:
        while (true) {
          if (startTokenRegion.getStart() == 0) {
            return NONE;
          }
          if (startTokenRegion.getType() != PHPRegionTypes.PHP_LINE_COMMENT
              && startTokenRegion.getType() != PHPRegionTypes.PHP_COMMENT
              && startTokenRegion.getType() != PHPRegionTypes.WHITESPACE
              && !startTokenRegion.getType().startsWith("PHPDOC")) { //$NON-NLS-1$
            types.add(startTokenRegion.getType());
          }
          if (startTokenRegion.getType() == PHPRegionTypes.PHP_CURLY_OPEN
              || startTokenRegion.getType() == PHPRegionTypes.PHP_INSTEADOF
              || startTokenRegion.getType() == PHPRegionTypes.PHP_SEMICOLON
              || startTokenRegion.getType() == PHPRegionTypes.PHP_AS) {
            break;
          }

          startTokenRegion = phpScriptRegion
              .getPhpToken(startTokenRegion.getStart() - 1);
        }

      } catch (BadLocationException e) {
      }
    }
    if (types.size() == 1) {
      String type = types.get(0);
      if (type == PHPRegionTypes.PHP_CURLY_OPEN
          || type == PHPRegionTypes.PHP_INSTEADOF
          || type == PHPRegionTypes.PHP_SEMICOLON) {
        return TRAIT_NAME;
      } else if (type == PHPRegionTypes.PHP_AS) {
        return TRAIT_KEYWORD;
      }
      if (type == PHPRegionTypes.PHP_INSTEADOF) {
        return TRAIT_KEYWORD;
      }
    } else if (types.size() == 2) {
      String type1 = types.get(0);
      String type = types.get(1);
      try {
        if (type == PHPRegionTypes.PHP_SEMICOLON
            && type1 == PHPRegionTypes.PHP_STRING
            && Character.isWhitespace(document.getChar(offset - 1))) {

          return TRAIT_KEYWORD;
        }
      } catch (BadLocationException e) {
      }
      if (type == PHPRegionTypes.PHP_CURLY_OPEN
          || type == PHPRegionTypes.PHP_INSTEADOF
          || type == PHPRegionTypes.PHP_SEMICOLON
          || type1 == PHPRegionTypes.PHP_STRING) {
        return TRAIT_NAME;
      }
    } else if (types.size() == 3) {
      String type = types.get(0);
      String type1 = types.get(1);
      String type2 = types.get(2);
      if (type == PHPRegionTypes.PHP_STRING
          && type1 == PHPRegionTypes.PHP_STRING
          && type2 == PHPRegionTypes.PHP_SEMICOLON) {
        return TRAIT_KEYWORD;
      }
    } else if (types.size() == 4) {
      String type = types.get(0);
      String type1 = types.get(1);
      String type2 = types.get(2);
      if (type == PHPRegionTypes.PHP_STRING
          && type1 == PHPRegionTypes.PHP_PAAMAYIM_NEKUDOTAYIM
          && type2 == PHPRegionTypes.PHP_STRING) {
        return TRAIT_KEYWORD;
      }
    }

    return NONE;
  }

  public boolean isInUseTraitStatement() {
    return isInUseTraitStatement(offset, structuredDocumentRegion);
  }

  private List<String> useTypes;

  public boolean isInUseTraitStatement(int offset,
      IStructuredDocumentRegion sdRegion) {
    PHPVersion phpVersion = ProjectOptions.getPhpVersion(sourceModule
        .getScriptProject().getProject());
    if (phpVersion.isLessThan(PHPVersion.PHP5_4)) {
      return false;
    }
    if (useTypes != null) {
      return true;
    }
    if (sdRegion == null) {
      sdRegion = structuredDocumentRegion;
    }
    int documentOffset = offset;
    if (documentOffset == sdRegion.getEndOffset()) {
      documentOffset -= 1;
    }
    ITextRegion tRegion = sdRegion
        .getRegionAtCharacterOffset(documentOffset);

    ITextRegionCollection container = sdRegion;

    if (tRegion instanceof ITextRegionContainer) {
      container = (ITextRegionContainer) tRegion;
      tRegion = container.getRegionAtCharacterOffset(offset);
    }
    if (tRegion != null && tRegion.getType() == PHPRegionContext.PHP_CLOSE) {
      tRegion = container.getRegionAtCharacterOffset(container
          .getStartOffset() + tRegion.getStart() - 1);
    }

    // This text region must be of type PhpScriptRegion:
    if (tRegion != null
        && tRegion.getType() == PHPRegionContext.PHP_CONTENT) {
      IPhpScriptRegion phpScriptRegion = (IPhpScriptRegion) tRegion;

      try {
        // Set default starting position to the beginning of the
        // PhpScriptRegion:
        int startOffset = container.getStartOffset()
            + phpScriptRegion.getStart();

        // Now, search backwards for the statement start (in this
        // PhpScriptRegion):
        ITextRegion startTokenRegion;
        if (documentOffset == startOffset) {
          startTokenRegion = phpScriptRegion.getPhpToken(0);
        } else {
          startTokenRegion = phpScriptRegion.getPhpToken(offset
              - startOffset - 1);
        }
        // If statement start is at the beginning of the PHP script
        // region:
        while (true) {
          if (startTokenRegion.getStart() == 0) {
            return false;
          }
          if (startTokenRegion.getType() == PHPRegionTypes.PHP_CURLY_OPEN) {
            // Calculate starting position of the statement (it
            // should go right after this startTokenRegion):
            // startOffset += startTokenRegion.getEnd();
            TextSequence statementText1 = getStatementText(startOffset
                + startTokenRegion.getStart() - 1);
            startTokenRegion = phpScriptRegion
                .getPhpToken(startTokenRegion.getStart()
                    - statementText1.length());
            if (startTokenRegion != null
                && startTokenRegion.getType() == PHPRegionTypes.PHP_USE) {
              String[] types = statementText1.toString().trim()
                  .substring(3).trim().split(","); //$NON-NLS-1$
              useTypes = new ArrayList<String>();
              for (String type : types) {
                useTypes.add(type.trim());
              }
              return true;
            } else {
              return false;
            }
          } else if (startTokenRegion.getType() == PHPRegionTypes.PHP_CURLY_CLOSE) {
            return false;
          }

          startTokenRegion = phpScriptRegion
              .getPhpToken(startTokenRegion.getStart() - 1);
        }

      } catch (BadLocationException e) {
      }
    }

    return false;
  }

  public List<String> getUseTypes() {
    return useTypes;
  }

}
TOP

Related Classes of org.eclipse.php.internal.core.codeassist.contexts.AbstractCompletionContext

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.