Skip to content

Commit

Permalink
Added support for implicit delegating declarations
Browse files Browse the repository at this point in the history
  • Loading branch information
hurricup committed Jun 23, 2019
1 parent e9fa6e2 commit e1bedda
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ else if (element instanceof PerlPolyNamedElement) {
subAttribute = PerlSyntaxHighlighter.PERL_CONSTANT;
}
for (PerlDelegatingLightNamedElement lightNamedElement : ((PerlPolyNamedElement<?>)element).getLightElements()) {
if (lightNamedElement.isImplicit()) {
continue;
}
TextAttributesKey currentKey =
lightNamedElement instanceof PerlSubDefinition ? subAttribute : PerlSyntaxHighlighter.PERL_PACKAGE_DEFINITION;
PsiElement navigationElement = lightNamedElement.getNavigationElement();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Objects;

/**
* Represents one of the declarations of {@link PerlPolyNamedElement}
*/
Expand All @@ -39,10 +41,11 @@ public class PerlDelegatingLightNamedElement<Delegate extends PerlPolyNamedEleme

@NotNull
protected String myName;

@Nullable
private PsiElement myNameIdentifier;

private boolean myIsImplicit = false;

@NotNull
private Function<String, String> myNameComputation = DEFAULT_NAME_COMPUTATION;

Expand Down Expand Up @@ -77,9 +80,12 @@ public PerlDelegatingLightNamedElement withNameComputation(@NotNull Function<Str
return this;
}

@NotNull
@Nullable
@Override
public PsiElement getNameIdentifier() {
if (myIsImplicit) {
return null;
}
if (myNameIdentifier != null && myNameIdentifier.isValid()) {
return myNameIdentifier;
}
Expand All @@ -99,6 +105,9 @@ public PsiElement getNameIdentifier() {
public PsiElement setName(@NonNls @NotNull String newBaseName) throws IncorrectOperationException {
// fixme should be in com.perl5.lang.perl.psi.utils.PerlPsiUtil.renameElement()
PsiElement nameIdentifier = getNameIdentifier();
if (nameIdentifier == null) {
return this;
}
ElementManipulator<PsiElement> manipulator = ElementManipulators.getManipulator(nameIdentifier);
TextRange identifierRange = this instanceof PerlIdentifierRangeProvider
? ((PerlIdentifierRangeProvider)this).getRangeInIdentifier()
Expand All @@ -124,42 +133,60 @@ public void navigate(boolean requestFocus) {
}
}

public boolean isImplicit() {
return myIsImplicit;
}

public void setImplicit(boolean implicit) {
myIsImplicit = implicit;
}

@NotNull
@Override
public PsiElement getNavigationElement() {
return getNameIdentifier();
return myIsImplicit ? getDelegate() : Objects.requireNonNull(getNameIdentifier());
}

@Override
public int getTextOffset() {
return getNameIdentifier().getTextOffset();
return getNavigationElement().getTextOffset();
}

@Override
public TextRange getTextRange() {
return getNameIdentifier().getTextRange();
return myIsImplicit ? super.getTextRange() : Objects.requireNonNull(getNameIdentifier()).getTextRange();
}

@Override
public boolean isValid() {
return getDelegate().isValid() && (myNameIdentifier == null || myNameIdentifier.isValid());
return getDelegate().isValid() && (myIsImplicit || myNameIdentifier == null || myNameIdentifier.isValid());
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof PerlDelegatingLightNamedElement)) return false;
if (!super.equals(o)) return false;
if (this == o) {
return true;
}
if (!(o instanceof PerlDelegatingLightNamedElement)) {
return false;
}
if (!super.equals(o)) {
return false;
}

PerlDelegatingLightNamedElement<?> element = (PerlDelegatingLightNamedElement<?>)o;

return getName().equals(element.getName());
if (myIsImplicit != element.myIsImplicit) {
return false;
}
return myName.equals(element.myName);
}

@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + getName().hashCode();
result = 31 * result + myName.hashCode();
result = 31 * result + (myIsImplicit ? 1 : 0);
return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public static PsiElement getLightNameIdentifierOwner(@NotNull PsiElement element

for (PerlDelegatingLightNamedElement lightNamedElement : polyNamedElement.getLightElements()) {
PsiElement identifier = lightNamedElement.getNameIdentifier();
if (identifier.getTextRange().contains(element.getTextRange())) {
if (identifier != null && identifier.getTextRange().contains(element.getTextRange())) {
return lightNamedElement;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright 2015-2019 Alexandr Evstigneev
*
* Licensed 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 com.perl5.lang.perl.psi.stubs;

/**
* Marks light elements stubs, allows to avoid serializing them into stubs stream
*/
public interface PerlLightElementStub {
/**
* @return true iff data of this stub should not be serialized, but stub should be indexed
*/
boolean isImplicit();

void setImplicit(boolean isImplicit);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import com.intellij.psi.stubs.*;
import com.intellij.util.containers.ContainerUtil;
import com.perl5.lang.perl.PerlLanguage;
import com.perl5.lang.perl.parser.elementTypes.PsiElementProvider;
import com.perl5.lang.perl.psi.impl.PerlPolyNamedElement;
Expand Down Expand Up @@ -63,8 +64,14 @@ public final Stub createStub(@NotNull Psi psi, StubElement parentStub) {
List<StubElement> lightNamedElements = new ArrayList<>();
Stub result = createStub(psi, parentStub, lightNamedElements);

//noinspection unchecked
psi.getLightElements().forEach(lightPsi -> lightNamedElements.add(lightPsi.getElementType().createStub(lightPsi, result)));
psi.getLightElements().forEach(lightPsi -> {
//noinspection unchecked
StubElement lightStubElement = lightPsi.getElementType().createStub(lightPsi, result);
if (lightStubElement instanceof PerlLightElementStub && lightPsi.isImplicit()) {
((PerlLightElementStub)lightStubElement).setImplicit(true);
}
lightNamedElements.add(lightStubElement);
});

return result;
}
Expand All @@ -80,7 +87,8 @@ public final String getExternalId() {

@Override
public final void serialize(@NotNull Stub stub, @NotNull StubOutputStream dataStream) throws IOException {
List<StubElement> childrenStubs = stub.getLightNamedElementsStubs();
List<StubElement> childrenStubs = ContainerUtil.filter(stub.getLightNamedElementsStubs(), it ->
!(it instanceof PerlLightElementStub) || !((PerlLightElementStub)it).isImplicit());
dataStream.writeVarInt(childrenStubs.size());
serializeStub(stub, dataStream);
for (StubElement childStub : childrenStubs) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2015-2017 Alexandr Evstigneev
* Copyright 2015-2019 Alexandr Evstigneev
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,16 @@
import com.intellij.psi.stubs.IStubElementType;
import com.intellij.psi.stubs.StubElement;
import com.intellij.util.IncorrectOperationException;
import com.perl5.lang.perl.psi.stubs.PerlLightElementStub;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class PerlLightNamespaceDefinitionStub extends PerlNamespaceDefinitionStub {
public class PerlLightNamespaceDefinitionStub extends PerlNamespaceDefinitionStub implements PerlLightElementStub {
@Nullable
private final StubElement myParent;

private boolean myIsImplicit = false;

public PerlLightNamespaceDefinitionStub(@Nullable StubElement parent,
IStubElementType elementType,
@NotNull PerlNamespaceDefinitionData data) {
Expand All @@ -49,4 +52,14 @@ public <E extends PsiElement> E getParentStubOfType(@NotNull Class<E> parentClas
public String toString() {
return getStubType() + ":" + super.toString();
}

@Override
public boolean isImplicit() {
return myIsImplicit;
}

@Override
public void setImplicit(boolean isImplicit) {
myIsImplicit = isImplicit;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2015-2017 Alexandr Evstigneev
* Copyright 2015-2019 Alexandr Evstigneev
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,20 @@
import com.intellij.psi.stubs.StubElement;
import com.intellij.util.IncorrectOperationException;
import com.perl5.lang.perl.idea.codeInsight.typeInference.value.PerlValue;
import com.perl5.lang.perl.psi.stubs.PerlLightElementStub;
import com.perl5.lang.perl.psi.utils.PerlSubAnnotations;
import com.perl5.lang.perl.psi.utils.PerlSubArgument;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.List;

public class PerlLightSubDefinitionStub extends PerlSubDefinitionStub {
public class PerlLightSubDefinitionStub extends PerlSubDefinitionStub implements PerlLightElementStub {
@Nullable
private final StubElement myParent;

private boolean myIsImplicit = false;

public PerlLightSubDefinitionStub(@Nullable StubElement parent,
String packageName,
String subName,
Expand All @@ -58,4 +61,14 @@ public <E extends PsiElement> E getParentStubOfType(@NotNull Class<E> parentClas
public String toString() {
return getStubType().toString() + ":" + super.toString();
}

@Override
public boolean isImplicit() {
return myIsImplicit;
}

@Override
public void setImplicit(boolean isImplicit) {
myIsImplicit = isImplicit;
}
}

0 comments on commit e1bedda

Please sign in to comment.