Skip to content

Commit d00a686

Browse files
committed
Consolidate multi-type lacking heuristics into helper methods
- Consolidate multi-type lacking heuristics into helper methods. - Call mentioned helper methods wherever multi-type TODOs are present.
1 parent 28735d3 commit d00a686

5 files changed

Lines changed: 62 additions & 67 deletions

File tree

src/main/java/com/laytonsmith/core/compiler/analysis/StaticAnalysis.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -452,8 +452,7 @@ public CClassType typecheck(ParseTree ast, Environment env, Set<ConfigCompileExc
452452
}
453453

454454
// Return procedure return type.
455-
// TODO - Get the most specific type when multiple declarations exist.
456-
return procReturnTypes.get(0);
455+
return CClassType.getMostSpecificType(procReturnTypes, env);
457456
} else {
458457
throw new Error("Unsupported " + CFunction.class.getSimpleName()
459458
+ " type in type checking for node with value: " + cFunc.val());
@@ -467,9 +466,14 @@ public CClassType typecheck(ParseTree ast, Environment env, Set<ConfigCompileExc
467466
"Variable cannot be resolved: " + ivar.getVariableName(), ivar.getTarget()));
468467
return CClassType.AUTO;
469468
} else {
470-
// TODO - Get the most specific type when multiple declarations exist.
471-
CClassType varType = decls.iterator().next().getType();
472-
return (varType.isVariadicType() ? CArray.TYPE : varType);
469+
470+
// Return the most specific type of all declarations.
471+
Set<CClassType> varTypes = new HashSet<>();
472+
for(Declaration decl : decls) {
473+
CClassType varType = decl.getType();
474+
varTypes.add(varType.isVariadicType() ? CArray.TYPE : varType);
475+
}
476+
return CClassType.getMostSpecificType(varTypes, env);
473477
}
474478
} else {
475479
// If this runs, then an IVariable reference was created without setting its Scope using setTermScope().

src/main/java/com/laytonsmith/core/constructs/CClassType.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.laytonsmith.core.objects.ObjectDefinitionTable;
2222
import com.laytonsmith.core.objects.UserObject;
2323
import java.util.Arrays;
24+
import java.util.Collection;
2425
import java.util.Comparator;
2526
import java.util.HashMap;
2627
import java.util.HashSet;
@@ -786,4 +787,48 @@ public boolean doesExtend(Environment env, CClassType superClass) {
786787
public static CClassType getFromGenericTypeName(String genericTypeName, Target t) {
787788
throw new UnsupportedOperationException("Not yet implemented");
788789
}
790+
791+
/**
792+
* Get the most specific type for a collection of types. This is the type for which holds that all types are
793+
* instance of this type. None (Java {@code null}) types are ignored.
794+
* When {@link CVoid#TYPE} is present in the types, it is returned.
795+
* Note that the intention of this method is to be replaced by a variant that returns a multi-type instead.
796+
* @param types - The types.
797+
* @param defaultType - The default type.
798+
* @param env - The environment.
799+
* @return The most specific type, or the provided default type if no such type exists.
800+
*/
801+
public static CClassType getMostSpecificType(
802+
Collection<CClassType> types, CClassType defaultType, Environment env) {
803+
// TODO - Change this method to return a multi-type based on the passed types when the type system allows this.
804+
search:
805+
for(CClassType type1 : types) {
806+
if(type1 != null) {
807+
if(type1.equals(CVoid.TYPE)) {
808+
return CVoid.TYPE;
809+
}
810+
for(CClassType type2 : types) {
811+
if(type2 != null && !InstanceofUtil.isInstanceof(type2, type1, env)) {
812+
continue search;
813+
}
814+
}
815+
return type1;
816+
}
817+
}
818+
return defaultType;
819+
}
820+
821+
/**
822+
* Get the most specific type for a collection of types. This is the type for which holds that all types are
823+
* instance of this type. None (Java {@code null}) types are ignored.
824+
* When {@link CVoid#TYPE} is present in the types, it is returned.
825+
* Note that the intention of this method is to be replaced by a variant that returns a multi-type instead.
826+
* @param types - The types.
827+
* @param env - The environment.
828+
* @return The most specific type, or {@link CClassType#AUTO} if no such type exists.
829+
*/
830+
public static CClassType getMostSpecificType(Collection<CClassType> types, Environment env) {
831+
// TODO - Change this method to return a multi-type based on the passed types when the type system allows this.
832+
return getMostSpecificType(types, CClassType.AUTO, env);
833+
}
789834
}

src/main/java/com/laytonsmith/core/functions/BasicLogic.java

Lines changed: 4 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import com.laytonsmith.core.constructs.CString;
2828
import com.laytonsmith.core.constructs.CSymbol;
2929
import com.laytonsmith.core.constructs.CVoid;
30-
import com.laytonsmith.core.constructs.InstanceofUtil;
3130
import com.laytonsmith.core.constructs.Target;
3231
import com.laytonsmith.core.environments.Environment;
3332
import com.laytonsmith.core.environments.GlobalEnv;
@@ -1284,22 +1283,8 @@ public CClassType getReturnType(Target t, List<CClassType> argTypes,
12841283
// Get return type based on the function signatures. This generates all necessary compile errors.
12851284
CClassType retType = super.getReturnType(t, argTypes, argTargets, env, exceptions);
12861285

1287-
// Return an occurring argument type if all argument types extend that type.
1288-
// TODO - Make this return a multitype instead as soon as all typechecking code supports multitypes.
1289-
search:
1290-
for(CClassType type1 : argTypes) {
1291-
if(type1 != null) {
1292-
for(CClassType type2 : argTypes) {
1293-
if(type2 != null && !InstanceofUtil.isInstanceof(type2, type1, env)) {
1294-
continue search;
1295-
}
1296-
}
1297-
return type1;
1298-
}
1299-
}
1300-
1301-
// Return super result.
1302-
return retType;
1286+
// Return the most specific argument type.
1287+
return CClassType.getMostSpecificType(argTypes, retType, env);
13031288
}
13041289

13051290
@Override
@@ -1607,22 +1592,8 @@ public CClassType getReturnType(Target t, List<CClassType> argTypes,
16071592
// Get return type based on the function signatures. This generates all necessary compile errors.
16081593
CClassType retType = super.getReturnType(t, argTypes, argTargets, env, exceptions);
16091594

1610-
// Return an occurring argument type if all argument types extend that type.
1611-
// TODO - Make this return a multitype instead as soon as all typechecking code supports multitypes.
1612-
search:
1613-
for(CClassType type1 : argTypes) {
1614-
if(type1 != null) {
1615-
for(CClassType type2 : argTypes) {
1616-
if(type2 != null && !InstanceofUtil.isInstanceof(type2, type1, env)) {
1617-
continue search;
1618-
}
1619-
}
1620-
return type1;
1621-
}
1622-
}
1623-
1624-
// Return super result.
1625-
return retType;
1595+
// Return the most specific argument type.
1596+
return CClassType.getMostSpecificType(argTypes, retType, env);
16261597
}
16271598

16281599
@Override

src/main/java/com/laytonsmith/core/functions/ControlFlow.java

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -486,20 +486,8 @@ public CClassType getReturnType(Target t, List<CClassType> argTypes,
486486
return null;
487487
}
488488

489-
// Return an occurring return type if all return types extend that type.
490-
// TODO - Make this return a multitype instead as soon as all typechecking code supports multitypes.
491-
search:
492-
for(CClassType type1 : returnTypes) {
493-
if(type1 != null) {
494-
for(CClassType type2 : returnTypes) {
495-
if(type2 != null && !InstanceofUtil.isInstanceof(type2, type1, env)) {
496-
continue search;
497-
}
498-
}
499-
return type1;
500-
}
501-
}
502-
return CClassType.AUTO;
489+
// Return the most specific return type.
490+
return CClassType.getMostSpecificType(returnTypes, env);
503491
}
504492

505493
// Return super result.
@@ -826,20 +814,8 @@ public CClassType getReturnType(Target t, List<CClassType> argTypes,
826814
return null;
827815
}
828816

829-
// Return an occurring return type if all return types extend that type.
830-
// TODO - Make this return a multitype instead as soon as all typechecking code supports multitypes.
831-
search:
832-
for(CClassType type1 : returnTypes) {
833-
if(type1 != null) {
834-
for(CClassType type2 : returnTypes) {
835-
if(type2 != null && !InstanceofUtil.isInstanceof(type2, type1, env)) {
836-
continue search;
837-
}
838-
}
839-
return type1;
840-
}
841-
}
842-
return CClassType.AUTO;
817+
// Return the most specific return type.
818+
return CClassType.getMostSpecificType(returnTypes, env);
843819
}
844820

845821
// Return super result.

src/main/java/com/laytonsmith/core/functions/DataHandling.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1782,7 +1782,6 @@ public Scope linkScope(StaticAnalysis analysis, Scope parentScope, ParseTree ast
17821782
analysis.linkScope(paramScope, code, env, exceptions);
17831783

17841784
// Create proc declaration in a new scope.
1785-
// TODO - Include proc signature (argument types and number of arguments) in declaration.
17861785
Scope declScope = analysis.createNewScope(parentScope);
17871786
ProcDeclaration procDecl = new ProcDeclaration(procName, retType, params,
17881787
ast.getNodeModifiers(), ast.getTarget());

0 commit comments

Comments
 (0)