Skip to content

Commit

Permalink
https://github.com/manifold-systems/manifold/issues/396
Browse files Browse the repository at this point in the history
- Handle expression in foreach stmt where the expression type structurally implements Iterator and a class extension exists that makes Iterable structural

manifold-systems/manifold#395
- Support property inference on record types

Bump version
  • Loading branch information
rsmckinney committed Nov 18, 2022
1 parent 4a4e39a commit f8d60c3
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 6 deletions.
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#
#

version=2022.3.23
manifoldVersion=2022.1.23-SNAPSHOT
version=2022.3.24
manifoldVersion=2022.1.24-SNAPSHOT
org.gradle.jvmargs=-Dfile.encoding=UTF-8
defaultIjVersion=LATEST-EAP-SNAPSHOT
49 changes: 49 additions & 0 deletions src/main/java/manifold/ij/extensions/ManHighlightInfoFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.PsiClassReferenceType;
import com.intellij.psi.impl.source.PsiJavaFileBaseImpl;
import com.intellij.psi.impl.source.tree.java.PsiArrayAccessExpressionImpl;
import com.intellij.psi.impl.source.tree.java.PsiAssignmentExpressionImpl;
Expand Down Expand Up @@ -205,6 +206,11 @@ public boolean accept( @NotNull HighlightInfo hi, @Nullable PsiFile file )
return false;
}

if( filterForeachExpressionErrors( hi, elem, firstElem ) )
{
return false;
}

//##
//## structural interface extensions cannot be added to the psiClass, so for now we suppress "incompatible type
//## errors" or similar involving a structural interface extension :(
Expand Down Expand Up @@ -414,6 +420,49 @@ private boolean filterIncompatibleReturnType( HighlightInfo hi, PsiElement elem,
hi.getDescription().contains( "incompatible return type" );
}

private boolean filterForeachExpressionErrors( HighlightInfo hi, PsiElement elem, PsiElement firstElem )
{
if( !hi.getDescription().contains( "foreach not applicable to type" ) )
{
return false;
}

PsiForeachStatement foreachStmt = getForeachStmt( elem );
if( foreachStmt != null )
{
PsiExpression expr = foreachStmt.getIteratedValue();
if( expr.getType() instanceof PsiClassReferenceType refType )
{
PsiClass psiClass = refType.resolve();
if( psiClass != null )
{
for( PsiMethod m: psiClass.findMethodsByName( "iterator", true ) )
{
if( !m.hasParameters() && m.getReturnType() != null )
{
//## todo: determine the parameterized return type and match it against the foreach stmt's var type
return true;
}
}
}
}
}
return false;
}

private PsiForeachStatement getForeachStmt( PsiElement elem )
{
if( elem == null )
{
return null;
}
if( elem instanceof PsiForeachStatement )
{
return (PsiForeachStatement)elem;
}
return getForeachStmt( elem.getParent() );
}

private boolean filterUnclosedComment( HighlightInfo hi, PsiElement firstElem )
{
// Preprocessor directives mask away text source in the lexer as comment tokens, obviously these will not
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@

package manifold.ij.extensions;

import com.intellij.codeInsight.completion.CompletionContributor;
import com.intellij.codeInsight.completion.CompletionParameters;
import com.intellij.codeInsight.completion.CompletionResult;
import com.intellij.codeInsight.completion.CompletionResultSet;
import com.intellij.codeInsight.completion.*;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.module.Module;
import com.intellij.psi.*;
import com.intellij.psi.impl.light.LightRecordField;
import com.intellij.psi.impl.source.PsiClassReferenceType;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.Consumer;
import manifold.ij.core.ManModule;
Expand All @@ -50,10 +51,38 @@ public void fillCompletionVariants( @NotNull CompletionParameters parameters, @N
return;
}

// Record fields are treated as public val properties
addRecordFields( parameters.getPosition(), result );

result.runRemainingContributors( parameters, new MyConsumer( parameters, result ) );
result.stopHere();
}

private void addRecordFields( @NotNull PsiElement position, CompletionResultSet result )
{
PsiElement parent = position.getParent();
if( parent instanceof PsiReferenceExpression ref )
{
PsiElement qualifier = ref.getQualifier();
PsiType type = qualifier instanceof PsiReferenceExpression refq ? refq.getType() : null;
if( type instanceof PsiClassReferenceType refType )
{
PsiClass psiClass = refType.resolve();
if( psiClass != null && psiClass.isRecord() )
{
for( PsiField c : psiClass.getFields() )
{
if( c instanceof LightRecordField )
{
result.addElement( LookupElementBuilder.create( c )
.withIcon( AllIcons.Nodes.PropertyRead ) );
}
}
}
}
}
}

static class MyConsumer implements Consumer<CompletionResult>
{
private final CompletionResultSet _result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.intellij.codeInsight.daemon.impl.HighlightInfoFilter;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.psi.*;
import com.intellij.psi.impl.light.LightRecordMember;
import manifold.ext.props.rt.api.get;
import manifold.ext.props.rt.api.set;
import manifold.ext.props.rt.api.val;
Expand Down Expand Up @@ -105,6 +106,11 @@ public boolean accept( @NotNull HighlightInfo hi, @Nullable PsiFile file )
return false;
}

if( filterRecordComponentPrivateAccess( hi, firstElem ) )
{
return false;
}

return true;
}

Expand All @@ -126,6 +132,22 @@ private boolean filterCannotAssignToFinalError( HighlightInfo hi, PsiElement fir
return !isReadOnly( field );
}

private boolean filterRecordComponentPrivateAccess( HighlightInfo hi, PsiElement firstElem )
{
String msg = hi.getDescription();
if( !msg.contains( " has private access" ) )
{
return false;
}

PsiElement expr = firstElem.getParent();
if( expr instanceof PsiReferenceExpression )
{
return ((PsiReferenceExpression)expr).resolve() instanceof LightRecordMember;
}
return false;
}

private boolean filterAbstractError( HighlightInfo hi, PsiElement firstElem )
{
String msg = hi.getDescription();
Expand Down
6 changes: 6 additions & 0 deletions src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,12 @@ a discussion, ask questions, provide feedback, etc. Someone is usually there to
<h3>Change notes:</h3>
<h4>
<br>
<a href="https://github.com/manifold-systems/manifold/issues/396">#396</a>: Handle expression in foreach stmt where the expression type structurally implements Iterator and a class extension exists that makes Iterable structural
<br>
<a href="https://github.com/manifold-systems/manifold/issues/395">#395</a>: Support property inference on record types
<br>
<a href="https://github.com/manifold-systems/manifold/issues/394">#394</a>: Support EA release of JDK 20
<br>
<a href="https://github.com/manifold-systems/manifold/issues/393">#393</a>: Java 17+: fix $ escape char for string templates
<br>
<a href="https://github.com/manifold-systems/manifold/issues/392">#392</a>: Cast as raw generic type
Expand Down

0 comments on commit f8d60c3

Please sign in to comment.