blob: c118b8ef5231e0761c7b6a15fa5b72a361ebd3a5 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.modules.php.editor.csl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.netbeans.modules.csl.api.InstantRenamer;
import org.netbeans.modules.csl.api.OffsetRange;
import org.netbeans.modules.csl.spi.ParserResult;
import org.netbeans.modules.php.editor.api.PhpModifiers;
import org.netbeans.modules.php.editor.api.elements.FieldElement;
import org.netbeans.modules.php.editor.api.elements.MethodElement;
import org.netbeans.modules.php.editor.api.elements.PhpElement;
import org.netbeans.modules.php.editor.model.Model;
import org.netbeans.modules.php.editor.model.Occurence;
import org.netbeans.modules.php.editor.model.Occurence.Accuracy;
import org.netbeans.modules.php.editor.model.OccurencesSupport;
import org.netbeans.modules.php.editor.model.VariableName;
import org.netbeans.modules.php.editor.parser.PHPParseResult;
/**
*
* @author Jan Lahoda, Radek Matous
*/
public class InstantRenamerImpl implements InstantRenamer {
//TODO: instant rename isn't proper refactoring but cause it was released this way in 6.5
// and because rename refactoring won't be implemented, so I've reverted it into
//6.5 shape to supress the feeling there is a regression
private static final boolean IS_RENAME_REFACTORING_ENABLED = true;
private List<Occurence> allOccurences = Collections.emptyList();
@Override
public boolean isRenameAllowed(ParserResult info, int caretOffset, String[] explanationRetValue) {
allOccurences.clear();
PHPParseResult result = (PHPParseResult) info;
final Model model = result.getModel();
OccurencesSupport occurencesSupport = model.getOccurencesSupport(caretOffset);
Occurence caretOccurence = occurencesSupport.getOccurence();
if (caretOccurence != null) {
final Accuracy accuracy = caretOccurence.degreeOfAccuracy();
if (accuracy.equals(Occurence.Accuracy.EXACT) || accuracy.equals(Occurence.Accuracy.UNIQUE)) {
if (IS_RENAME_REFACTORING_ENABLED) {
final Collection<? extends PhpElement> allDeclarations = caretOccurence.getAllDeclarations();
if (allDeclarations.size() != 1) {
return false;
}
PhpElement decl = allDeclarations.iterator().next();
if (decl instanceof VariableName) {
VariableName varName = (VariableName) decl;
if (!varName.isGloballyVisible() && !varName.representsThis()) {
return checkAll(caretOccurence);
}
} else if (decl instanceof MethodElement) {
MethodElement meth = (MethodElement) decl;
PhpModifiers phpModifiers = meth.getPhpModifiers();
if (phpModifiers.isPrivate()) {
return checkAll(caretOccurence);
}
} else if (decl instanceof FieldElement) {
FieldElement fld = (FieldElement) decl;
PhpModifiers phpModifiers = fld.getPhpModifiers();
if (phpModifiers.isPrivate()) {
return checkAll(caretOccurence);
}
}
} else {
return checkAll(caretOccurence);
}
}
}
return false;
}
@Override
public Set<OffsetRange> getRenameRegions(ParserResult info, int caretOffset) {
Set<OffsetRange> retval = new HashSet<>();
for (Occurence occurence : allOccurences) {
retval.add(occurence.getOccurenceRange());
}
allOccurences.clear();
return retval;
}
private boolean checkAll(Occurence caretOccurence) {
List<Occurence> collected = new ArrayList<>();
Collection<Occurence> all = caretOccurence.getAllOccurences();
for (Occurence occurence : all) {
if (IS_RENAME_REFACTORING_ENABLED) {
if (occurence.getAllDeclarations().size() == 1) {
collected.add(occurence);
} else {
allOccurences.clear();
return false;
}
} else {
collected.add(occurence);
}
}
allOccurences = collected;
return true;
}
}