Ignore:
Timestamp:
03/01/06 17:13:31 (19 years ago)
Author:
remar
Message:
  • IModelicaClass now provides an ISignature of its inputs and outputs
  • OMCProxy now tries three (3) different paths to omc
  • Context Information now takes imports and the Standard Library in consideration
  • ModelicaImport? now works better on Standard Library items
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/org.modelica.mdt.ui/src/org/modelica/mdt/ui/editor/ModelicaCompletionProcessor.java

    r390 r393  
    4545import java.util.LinkedList;
    4646import java.util.StringTokenizer;
    47 import java.util.Vector;
    4847
    4948import org.eclipse.core.runtime.CoreException;
     
    5958import org.eclipse.jface.text.contentassist.IContextInformationPresenter;
    6059import org.eclipse.jface.text.contentassist.IContextInformationValidator;
     60import org.eclipse.swt.SWT;
     61import org.eclipse.swt.custom.StyleRange;
    6162import org.eclipse.ui.IEditorInput;
    6263import org.eclipse.ui.IEditorPart;
    63 import org.modelica.mdt.core.CompilerProxy;
    6464import org.modelica.mdt.core.IModelicaClass;
    6565import org.modelica.mdt.core.IModelicaElement;
     
    6868import org.modelica.mdt.core.IModelicaImport;
    6969import org.modelica.mdt.core.IModelicaSourceFile;
     70import org.modelica.mdt.core.IParameter;
    7071import org.modelica.mdt.core.IParent;
     72import org.modelica.mdt.core.ISignature;
    7173import org.modelica.mdt.core.IStandardLibrary;
    72 import org.modelica.mdt.core.List;
    7374import org.modelica.mdt.core.ModelicaCore;
    7475import org.modelica.mdt.core.compiler.CompilerException;
    7576import org.modelica.mdt.core.compiler.CompilerInstantiationException;
    7677import org.modelica.mdt.core.compiler.ConnectException;
    77 import org.modelica.mdt.core.compiler.ElementsInfo;
    7878import org.modelica.mdt.core.compiler.InvocationError;
    79 import org.modelica.mdt.core.compiler.ModelicaParser;
    8079import org.modelica.mdt.core.compiler.UnexpectedReplyException;
    8180import org.modelica.mdt.internal.core.ErrorManager;
     
    9998{
    10099
    101     private Vector<String> inputParameters = new Vector<String>();
    102     private Vector<String> outputParameters = new Vector<String>();
    103100    private IEditorPart editor;
    104101   
    105     private static String functionProposal;
     102    private static String functionProposal = "";
     103    private static int functionNameStart = 0;
     104    private static int functionNameEnd = 0;
    106105   
    107106    public ModelicaCompletionProcessor(IEditorPart editor)
     
    126125            String stringTyped =
    127126                ModelicaCompletionProcessor.getLine(fViewer, offset);
    128 
     127           
    129128            /* Get start of parameter list. */
    130129            int pos = stringTyped.indexOf('(');
     130           
     131            if(pos == -1)
     132            {
     133                return false;
     134            }
    131135           
    132136            /* Match parens to see if we're done typing. */
     
    139143                    pardepth--;
    140144            }
     145           
    141146            /* The TYPING will go on as long as it has to! */
    142147            /* (or somebody yells stop, goes limb, passes out) */
     
    161166                TextPresentation presentation)
    162167        {
    163             return false;
     168            /* Only apply the style range as we start displaying this
     169             * information*/
     170            if(fInstallOffset != documentPosition)
     171            {
     172                return false;
     173            }
     174           
     175            StyleRange sr;
     176            sr = new StyleRange(functionNameStart,
     177                    functionNameEnd - functionNameStart, null, null, SWT.BOLD);
     178
     179            presentation.addStyleRange(sr);
     180           
     181            return true;
    164182        }
    165183    }
     
    247265       
    248266        return foundString;
    249     }
    250    
    251     private void fetchParameters(String functionName)
    252     {
    253         inputParameters.clear();
    254         outputParameters.clear();
    255        
    256         Collection<ElementsInfo> elementsInfo;
    257        
    258         try
    259         {
    260             elementsInfo = CompilerProxy.getElementsInfo(functionName);
    261         }
    262         catch (ConnectException e)
    263         {
    264             ErrorManager.showCompilerError(e);
    265             return;
    266         }
    267         catch (CompilerException e)
    268         {
    269             ErrorManager.logError(e);
    270             return;
    271         }
    272 
    273         functionProposal = functionName;
    274        
    275         for(ElementsInfo info : elementsInfo)
    276         {
    277             boolean elementIsPublic = false;
    278             boolean elementIsComponent = false;
    279             boolean elementIsInput = false;
    280             boolean elementIsOutput = false;
    281             boolean elementNamesFound = false;
    282             String name = null;
    283             String typename = "";
    284             String direction = null;           
    285            
    286             elementIsPublic = info.getElementVisibility().equals("public");
    287             elementIsComponent = info.getElementType().equals("component");
    288 
    289             if (elementIsComponent)
    290             {
    291                 List comp = ModelicaParser.parseList(info.getNames());
    292                
    293                 name = comp.elementAt(0).toString();
    294                 elementNamesFound = true;
    295             }
    296             typename = info.getTypeName();
    297            
    298             direction = info.getDirection();
    299    
    300             if (direction != null)
    301             {
    302                 elementIsInput = direction.equals("input");
    303                 elementIsOutput = direction.equals("output");
    304             }
    305            
    306             if(elementIsPublic && elementIsComponent
    307                     && elementIsInput && elementNamesFound)
    308             {
    309                 inputParameters.add(typename + " " + name);
    310             }
    311             else if(elementIsPublic && elementIsComponent
    312                     && elementIsOutput && elementNamesFound)
    313             {
    314                 outputParameters.add(typename + " " + name);
    315             }
    316         }
    317267    }
    318268   
     
    640590            int offset)
    641591    {
    642         /* make sure we don't back over the document... */
     592        /* If the offset is 0, there is no prefix and there can be no
     593         * context information */
    643594        if(offset == 0)
    644595        {
    645             return new IContextInformation[0];
    646         }
    647        
    648         String className = getPrefix(viewer.getDocument(), offset - 1);
    649 
    650        
    651         fetchParameters(className);
    652        
    653         String proposal = "";
    654        
    655         if(inputParameters.size() > 0)
    656         {
    657             proposal += "Input: ";
    658             for(String s : inputParameters)
    659             {
    660                 proposal += s + ", ";
    661             }
    662         }
    663         if(outputParameters.size() > 0)
    664         {
    665             proposal += "Output: ";
    666             for(int i = 0;i < outputParameters.size();i++)
    667             {
    668                 if(i + 1 < outputParameters.size())
    669                     proposal += outputParameters.get(i) + ", ";
    670                 else
    671                     proposal += outputParameters.get(i);
    672             }
    673         }
    674        
    675         if(proposal == "")
    676             return null;
    677        
    678         IContextInformation[] result = new IContextInformation[1];
    679        
    680         result[0] = new ContextInformation("Function proposal", proposal);
    681        
    682         return result;
    683     }
    684 
     596            return new ContextInformation[0];
     597        }
     598       
     599        IEditorInput input = editor.getEditorInput();
     600       
     601        if((input instanceof ModelicaElementEditorInput) == false)
     602        {
     603            ErrorManager.logBug(UIPlugin.getSymbolicName(),
     604                    "Context information processor invoked on a non-modelica" +
     605                    " content.");
     606           
     607            return new ContextInformation[0];
     608           
     609            // TODO see todo in computeCompletionProposals
     610        }
     611       
     612        String prefix = getPrefix(viewer.getDocument(), offset - 1);
     613       
     614        /* If the prefix ends with a dot, there is no function name that we
     615         * can fetch parameters from */
     616        if(prefix.endsWith("."))
     617        {
     618            return new ContextInformation[0];
     619        }
     620       
     621        LinkedList<IContextInformation> information =
     622            new LinkedList<IContextInformation>();
     623       
     624        IModelicaSourceFile file =
     625            ((ModelicaElementEditorInput)input).getSourceFile();
     626       
     627        try
     628        {
     629            IModelicaClass modelicaClass = file.getClassAt(offset);
     630            if(modelicaClass != null)
     631            {
     632                computeContextInformationFromImports(modelicaClass, prefix,
     633                        offset, information);
     634                computeContextInformationFromStdLib(modelicaClass, prefix,
     635                        offset, information);
     636            }
     637            else
     638            {
     639                return new IContextInformation[0];
     640            }
     641        }
     642        catch(CoreException e)
     643        {
     644            ErrorManager.showCoreError(e);
     645        }
     646        catch(CompilerException e)
     647        {
     648            ErrorManager.showCompilerError(e);
     649        }
     650       
     651        return information.toArray(new IContextInformation[information.size()]);       
     652    }
     653   
     654    private void computeContextInformationFromStdLib(
     655            IModelicaClass modelicaClass, String prefix, int offset,
     656            LinkedList<IContextInformation> info)
     657        throws ConnectException, CompilerInstantiationException,
     658            UnexpectedReplyException, InvocationError, CoreException
     659    {
     660        IStandardLibrary stdLib =
     661            ModelicaCore.getModelicaRoot().getStandardLibrary();
     662       
     663        for(IModelicaClass pkg : stdLib.getPackages())
     664        {
     665            computeContextInformationFromPackage(pkg, null, prefix, offset,
     666                    info);
     667        }
     668    }
     669
     670    private void computeContextInformationFromImports(
     671            IModelicaClass modelicaClass, String prefix, int offset,
     672            LinkedList<IContextInformation> info)
     673        throws ConnectException,
     674            UnexpectedReplyException, InvocationError,
     675            CompilerInstantiationException, CoreException
     676    {
     677        Collection<IModelicaImport> imports = new LinkedList<IModelicaImport>();
     678       
     679        /* I wanted a for-loop and I got a for-loop. Hah! */
     680        for(IModelicaClass currClass = modelicaClass;
     681            currClass != null;
     682            currClass = currClass.getParentNamespace())
     683        {
     684            imports.addAll(currClass.getImports());
     685        }
     686       
     687        for(IModelicaImport imp : imports)
     688        {
     689            IModelicaClass importedPackage = imp.getImportedPackage();
     690
     691            switch(imp.getType())
     692            {
     693            case QUALIFIED:
     694                computeContextInformationFromPackage(importedPackage, null,
     695                        prefix, offset, info);
     696                break;
     697            case UNQUALIFIED:
     698                for(IModelicaElement child : importedPackage.getChildren())
     699                {
     700                    computeContextInformationFromPackage((IModelicaClass)child,
     701                            null, prefix, offset, info);
     702                }
     703                break;
     704            }
     705        }
     706    }
     707   
     708    private void computeContextInformationFromPackage(
     709            IModelicaClass importedPackage, String packageAlias, String prefix,
     710            int offset, Collection<IContextInformation> info)
     711        throws ConnectException, UnexpectedReplyException, InvocationError,
     712            CompilerInstantiationException, CoreException
     713    {
     714        String packageName;
     715       
     716        if(packageAlias != null)
     717        {
     718            packageName = packageAlias;
     719        }
     720        else
     721        {
     722            packageName = importedPackage.getElementName();
     723        }
     724
     725        int firstDot = prefix.indexOf('.');
     726        if(firstDot == -1)
     727        {
     728           
     729            if(!packageName.equals(prefix))
     730            {
     731                return;
     732            }
     733
     734            String proposal = constructProposalString(importedPackage);
     735           
     736            if(info.size() == 0)
     737            {
     738                info.add(new ContextInformation(proposal, proposal));
     739                functionProposal = prefix;
     740            }
     741            return;
     742        }
     743        else if(packageName.equals(prefix.substring(0, firstDot)) == false)
     744        {
     745            return;
     746        }
     747       
     748        int lastDot = prefix.lastIndexOf('.');
     749        String levelName = prefix.substring(0, lastDot);
     750       
     751        String childPrefix = prefix.substring(lastDot + 1);
     752       
     753        StringTokenizer st = new StringTokenizer(levelName, ".");
     754        String token;
     755       
     756        IParent currLevel = (IParent)importedPackage;
     757       
     758        if(st.hasMoreTokens())
     759        {
     760            st.nextToken();
     761        }
     762       
     763        while(st.hasMoreTokens())
     764        {
     765            token = st.nextToken();
     766            boolean foundNextLevel = false;
     767           
     768            for(IModelicaElement child : currLevel.getChildren())
     769            {
     770                if(child.getElementName().equals(token))
     771                {
     772                    foundNextLevel = true;
     773                    if(child instanceof IParent)
     774                    {
     775                        currLevel = (IParent)child;
     776                    }
     777                    else
     778                    {
     779                        return;
     780                    }
     781                }
     782            }
     783           
     784            if(foundNextLevel == false)
     785            {
     786                return;
     787            }
     788        }
     789       
     790        for(IModelicaElement element : currLevel.getChildren())
     791        {
     792            String elementName = element.getElementName();
     793           
     794            if(elementName.equals(childPrefix) == false)
     795            {
     796                continue;
     797            }
     798
     799            if(element instanceof IModelicaClass)
     800            {
     801                String proposal =
     802                    constructProposalString((IModelicaClass)element);
     803
     804                if(info.size() == 0)
     805                {
     806                    info.add(new ContextInformation(proposal, proposal));
     807                    functionProposal = prefix;
     808                }
     809            }
     810        }
     811    }
     812   
     813    private String constructProposalString(IModelicaClass modelicaClass)
     814        throws ConnectException, InvocationError, UnexpectedReplyException,
     815            CompilerInstantiationException, CoreException
     816    {
     817        ISignature signature = modelicaClass.getSignature();
     818        if(signature == null)
     819        {
     820            return "";
     821        }
     822       
     823        String proposal;
     824       
     825        IParameter[] outputs = signature.getOutputs();
     826
     827        if(outputs.length >= 2)
     828        {
     829            proposal = "(";
     830           
     831            int i = 0;
     832            for(;i < outputs.length - 1;i++)
     833            {
     834                proposal += outputs[i].getType() + ", ";
     835            }
     836           
     837            proposal += outputs[i].getType() + ") ";
     838        }
     839        else if(outputs.length == 1)
     840        {
     841            proposal = outputs[0].getType() + " ";
     842        }
     843        else
     844        {
     845            proposal = "";
     846        }
     847       
     848        functionNameStart = proposal.length();
     849       
     850        proposal += modelicaClass.getElementName() + "(";
     851       
     852        functionNameEnd = proposal.length() - 1;
     853       
     854        IParameter[] inputs = signature.getInputs();
     855        if(inputs.length >= 1)
     856        {
     857            int i = 0;
     858            for(;i < inputs.length - 1;i++)
     859            {
     860                proposal += inputs[i].getType() + " "
     861                    + inputs[i].getName() + ", ";
     862            }
     863            proposal += inputs[i].getType() + " " + inputs[i].getName();
     864        }
     865        proposal += ")";
     866
     867        return proposal;
     868    }
     869   
    685870    public char[] getCompletionProposalAutoActivationCharacters()
    686871    {
Note: See TracChangeset for help on using the changeset viewer.