package bluej.stride.framedjava.ast;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.stream.Stream;

import bluej.stride.framedjava.elements.CodeElement;
import bluej.stride.framedjava.elements.LocatableElement.LocationMap;
import bluej.stride.framedjava.errors.*;
import bluej.stride.framedjava.slots.ExpressionSlot;
import bluej.stride.framedjava.slots.TypeSlot;
import bluej.stride.generic.InteractionManager;
import bluej.utility.javafx.FXPlatformConsumer;
import threadchecker.OnThread;
import threadchecker.Tag;

public class TypeSlotFragment
extends StructuredSlotFragment{    
   private TypeSlot slot;
   
   private boolean hasEarlyErrors;

   
   public TypeSlotFragment(String content, String javaCode, TypeSlot slot)
   {
      super(content, javaCode);
       
      this.slot = slot;     
      }
    
   
   public TypeSlotFragment(String content, String javaCode)
   {
      this(content, javaCode, null);     
      }

   
   @Override
   
   public Map getVars()
   {
      return Collections.emptyMap();     
      }

   
   @Override
   
   public String getJavaCode(Destination dest, ExpressionSlot<?> completing, Parser.DummyNameGenerator dummyNameGenerator)
   {
      if (!dest.substitute() || (content != null && Parser.parseableAsType(content)))
           
      return content;
       
      else{ 
         return dummyNameGenerator.generateNewDummyName();
         }     
      }

   
   @Override
   
   public Stream findEarlyErrors()
   {        
      
      hasEarlyErrors = true;
      if (content != null && content.isEmpty())
           
      return Stream.of(new EmptyError(this, "Type cannot be empty"));
      else if (content != null && content.endsWith(";"))
           
      
      return Stream.of(new UnneededSemiColonError(this, () -> getSlot().setText(content.substring(0, content.length() - 1))));
      else if (content == null || !Parser.parseableAsType(content))
           
      return Stream.of(new SyntaxCodeError(this, "Invalid type"));

       
      
      hasEarlyErrors = false;
      return Stream.empty();     
      }

   
   @Override
   @OnThread(Tag.FXPlatform)
   
   public Future> findLateErrors(InteractionManager editor, CodeElement parent,
                                                       
   LocationMap rootPathMap)
   {        
      CompletableFuture<List<DirectSlotError>> f = new CompletableFuture<>();

       
      ArrayList<Integer> indexOfErrors = new ArrayList<>();
       
      ArrayList<String> typesList = new ArrayList<>();

      if (hasEarlyErrors)
       {
         f.complete(Collections.emptyList());
           
         return f;         
         }

       
      
      if ((content.contains("<") && content.contains(">")) ||
      (content.contains("[") && content.contains("]")))
       {            
         
         
         String modifiedContent = content.replaceAll("[<>\\]\\[]", ",");
           
         int index = 0;
         while (!modifiedContent.equals(""))
           {
            String type = modifiedContent.substring(0, modifiedContent.indexOf(","));
            if (!type.equals(""))
               {
               indexOfErrors.add(index);
               typesList.add(type);                 
               }
            index = index + type.length() + 1;
            modifiedContent = modifiedContent.substring(modifiedContent.indexOf(",") + 1);
            if (!modifiedContent.contains(",") && !modifiedContent.equals(""))
               {
               indexOfErrors.add(index);
               typesList.add(modifiedContent);
                   
               break;                 
               }             
            }

         return checkForTypeErrors(typesList, indexOfErrors, editor, rootPathMap);         
         }

       
      
      
      if (content.contains("[") || content.contains("<") || content.contains("."))
       {
         f.complete(Collections.emptyList());
           
         return f;         
         }

      editor.withTypes(types -> {

      if (types.containsKey(content))
           {                
         
         f.complete(Collections.emptyList());
               
         return;             
         }
           
      
      final UnknownTypeError error = new UnknownTypeError(this, content, slot::setText, editor,
      types.values().stream(), editor.getImportSuggestions().values().stream().
                   
      flatMap(Collection::stream)) {
      };
   error.recordPath(rootPathMap.locationFor(this));
   f.complete(Arrays.asList(error));         
   });
return f;     
}

   

| It checks for type errors and it returns a list of errors (wrapped as a Future). | @param typesList the list of found types | @param indexList the list of type indexes in the slot | @param editor the editor of the class | @param rootPathMap the root map from JavaFragment to XPath String identifying the location of that fragment. | @return the Future list of errors | @OnThread(Tag.FXPlatform) private Future> checkForTypeErrors( ArrayList<String> typesList, ArrayList<Integer> indexList, InteractionManager editor, LocationMap rootPathMap) { CompletableFuture<List<DirectSlotError>> f = new CompletableFuture<>(); ArrayList<DirectSlotError> listOfErrors = new ArrayList<>(); editor.withTypes(types -> { int i = 0; for (String t : typesList) { if (types.containsKey(t)) { i = i + 1; continue; } int startPosInSlot = indexList.get(i); int endPosInSlot = startPosInSlot + t.length(); FXPlatformConsumer<String> replace = s -> slot.replace(startPosInSlot, endPosInSlot, false, s); final UnknownTypeError error = new UnknownTypeError(this, t, replace, editor, types.values().stream(), editor.getImportSuggestions().values().stream(). flatMap(Collection::stream)); error.recordPath(rootPathMap.locationFor(this)); listOfErrors.add(error); i = i + 1; } f.complete(listOfErrors); }); return f; } @Override public TypeSlot getSlot() { return slot; } public void registerSlot(TypeSlot slot) { if (this.slot == null) this.slot = slot; } }
top, use, map, class TypeSlotFragment

.   TypeSlotFragment
.   TypeSlotFragment
.   getVars
.   getJavaCode
.   findEarlyErrors
.   findLateErrors
.   checkForTypeErrors
.   getSlot
.   registerSlot




229 neLoCode + 6 LoComm