Skip to content

Commit

Permalink
https://github.com/manifold-systems/manifold/issues/371
Browse files Browse the repository at this point in the history
- Provide `auto` type inference for local vars, fields, and method return types

#372
- Support type-safe tuple expressions

#373
- Support multiple return types via `auto` and enhanced tuple expressions

#375
- Support only LTS versions of JDKs and the latest release
  • Loading branch information
rsmckinney committed Jun 17, 2022
1 parent 8ab4e4e commit d499838
Show file tree
Hide file tree
Showing 68 changed files with 4,841 additions and 1,048 deletions.
5 changes: 5 additions & 0 deletions manifold-all/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
<artifactId>manifold</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>systems.manifold</groupId>
<artifactId>manifold-tuple</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>systems.manifold</groupId>
<artifactId>manifold-collections</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package manifold.rt.api.util;

import manifold.util.JreUtil;
import manifold.util.ManExceptionUtil;
import manifold.util.ReflectUtil;

import java.util.Iterator;
Expand Down Expand Up @@ -47,6 +48,14 @@ public static <C> Set<C> loadRegisteredServices( Set<C> services, Class<C> servi
C service = iterator.next();
services.add( service );
}
catch( UnsupportedClassVersionError ucve )
{
// if manifold compiles within IJ, it picks up the IJ plugin's impl, which is compiled with a later version of Java
if( !ucve.getMessage().contains( "manifold/ij/android/BuildVariantSymbols" ) )
{
throw ManExceptionUtil.unchecked( ucve );
}
}
catch( ServiceConfigurationError e )
{
// not in the loader, check thread ctx loader next
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@
*/
public interface IFileConnected
{
/**
* Are the types produced from this type manifold backed by project files such as resource files?
*/
default boolean isFileBacked()
{
return false;
}

/**
* @return True if this type manifold handles files having the given {@code fileExtension}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public interface ITypeManifold extends IFileConnected, ISelfCompiled
String ARG_DUMP_SOURCE = "manifold.dump.source";

/**
* A module calls this method to determine whether or not to include this type manifold in its collection of type
* A module calls this method to determine whether to include this type manifold in its collection of type
* manifolds. Gives this type manifold an opportunity to opt out of inclusion based on the module. For instance,
* if a module should only operate in a runtime environment, it should return false if the module's host is not
* an instance of {@link IRuntimeManifoldHost}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ protected void init( IModule module, BiFunction<String, Set<IFile>, M> modelMapp
getModule().getHost().addTypeSystemListenerAsWeakRef( getModule(), _cacheClearer = createCacheClearer() );
}

@Override
public boolean isFileBacked()
{
return true;
}

protected CacheClearer createCacheClearer()
{
return new CacheClearer();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ public class IssueMsg
{
public static final IssueMsg MSG_COULD_NOT_FIND_TYPE_FOR_FILE = new IssueMsg( "Could not find type for file: {0}" );

public static final IssueMsg MSG_AUTO_CANNOT_INFER_WO_INIT = new IssueMsg( "Cannot infer 'auto' variable type without initializer" );
public static final IssueMsg MSG_AUTO_CANNOT_RETURN_AUTO_FROM_ABSTRACT_METHOD = new IssueMsg( "Cannot return 'auto' from abstract method" );
public static final IssueMsg MSG_AUTO_RETURN_MORE_SPECIFIC_TYPE = new IssueMsg( "Cannot return 'auto', return a more specific type" );
public static final IssueMsg MSG_AUTO_UNABLE_TO_RESOLVE_TYPE = new IssueMsg( "Unable to infer 'auto' type here" );
public static final IssueMsg MSG_AUTO_CANNOT_INFER_FROM_NULL = new IssueMsg( "'auto' cannot infer from just 'null', cast 'null' or replace 'auto' with a type" );

private final String _msg;

public IssueMsg( String msg )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ public Tree getParent( Tree node )
{
return _parents.getParent( node );
}
public Tree getParent( Tree node, CompilationUnitTree compUnit )
{
return _parents.getParent( node, compUnit );
}

public JCTree.JCClassDecl getClassDecl( Tree node )
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,25 +82,22 @@ class Instance
try
{
String fqnIssueReporter;
if( JreUtil.isJava8() )
if( JreUtil.isJava8() ) // Java 8
{
fqnIssueReporter = "manifold.internal.javac.JavaDynamicJdk_8";
}
else if( JreUtil.JAVA_VERSION < 11 ) // Java 9 & 10
{
fqnIssueReporter = "manifold.internal.javac.JavaDynamicJdk_9";
}
else if( JreUtil.isJava11() ) // Java 11 - 15
else if( JreUtil.isJava11() ) // Java 11
{
fqnIssueReporter = "manifold.internal.javac.JavaDynamicJdk_11";
}
else if( JreUtil.isJava16() ) // Java 16
else if( JreUtil.isJava17orLater() )// Java 17+
{
fqnIssueReporter = "manifold.internal.javac.JavaDynamicJdk_16";
fqnIssueReporter = "manifold.internal.javac.JavaDynamicJdk_17";
}
else // Java 17+
else
{
fqnIssueReporter = "manifold.internal.javac.JavaDynamicJdk_17";
throw new RuntimeException( "Unsupported JDK version " + JreUtil.JAVA_VERSION +
". Only LTS versions starting with Java 8 and the latest release are supported." );
}
return (IDynamicJdk)Class.forName( fqnIssueReporter ).newInstance();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@
* {@link LetExpr#expr}. Manifold uses LetExpr to handle JCUnary inc/dec and JCAssignOp (+=, *=, etc.) with advanced
* features such as operator overloading and properties. In some cases, such as properties, we need the LetExpr to
* have defs that are not JCVarDecl e.g., setXxx() to handle JCAssignOp. All of this mumbo jumbo here and in LetExpr_8
* and LetExpr_9 is to make that work.
* and LetExpr_11 is to make that work.
*/
public interface ILetExpr
{
/**
* Always use this method to make a new LetExpr, which must be an instance of either LetExpr_8 or LetExpr_9.
* Always use this method to make a new LetExpr, which must be an instance of either LetExpr_8 or LetExpr_11.
*/
static LetExpr makeLetExpr(
TreeMaker make, List<? extends JCTree> tempVars, JCTree.JCExpression value, Type type, int pos )
Expand All @@ -54,7 +54,7 @@ static LetExpr makeLetExpr(
letExpr.setPos( pos );
return (LetExpr)(JreUtil.isJava8()
? (JCTree)ReflectUtil.constructor( "manifold.internal.javac.LetExpr_8", LetExpr.class ).newInstance( letExpr )
: (JCTree)ReflectUtil.constructor( "manifold.internal.javac.LetExpr_9", LetExpr.class ).newInstance( letExpr ));
: (JCTree)ReflectUtil.constructor( "manifold.internal.javac.LetExpr_11", LetExpr.class ).newInstance( letExpr ));
}

List<JCTree.JCStatement> getDefs();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2022 - Manifold Systems LLC
*
* 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 manifold.internal.javac;

import manifold.rt.api.util.ServiceUtil;
import manifold.util.concurrent.LocklessLazyVar;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public interface ITupleTypeProvider
{
LocklessLazyVar<ITupleTypeProvider> INSTANCE =
LocklessLazyVar.make( () -> {
Set<ITupleTypeProvider> registered = new HashSet<>();
ServiceUtil.loadRegisteredServices( registered, ITupleTypeProvider.class, ITupleTypeProvider.class.getClassLoader() );
return registered.iterator().next(); // should only be one
} );

String makeType( String pkg, Map<String, String> fieldNameToTypeName );

Set<String> getTypes();

Map<String, String> getFields( String fqn );
}
Loading

0 comments on commit d499838

Please sign in to comment.