private CeylonParseController parse() { CeylonParseController cpc = new CeylonParseController(); cpc.initialize( editor.getParseController().getPath(), editor.getParseController().getProject(), null); cpc.parse(editor.getCeylonSourceViewer().getDocument(), new NullProgressMonitor(), null); return cpc; }
static int nextTokenType(CeylonParseController cpc, CommonToken token) { for (int i = token.getTokenIndex() + 1; i < cpc.getTokens().size(); i++) { CommonToken tok = cpc.getTokens().get(i); if (tok.getChannel() != CommonToken.HIDDEN_CHANNEL) { return tok.getType(); } } return -1; }
static void addPackageDescriptorCompletion( CeylonParseController cpc, int offset, String prefix, List<ICompletionProposal> result) { if (!"package".startsWith(prefix)) return; IFile file = cpc.getProject().getFile(cpc.getPath()); String packageName = getPackageName(file); if (packageName != null) { result.add(new PackageDescriptorProposal(offset, prefix, packageName)); } }
private boolean terminateWithSemicolon() throws Exception { final IDocument doc = editor.getCeylonSourceViewer().getDocument(); final TextChange change = new DocumentChange("Terminate Statement", doc); change.setEdit(new MultiTextEdit()); CeylonParseController parser = parse(); CompilationUnit rootNode = parser.getRootNode(); IRegion li = getLineInfo(doc); String lineText = doc.get(li.getOffset(), li.getLength()); final List<CommonToken> tokens = parser.getTokens(); // final int startOfCodeInLine = getCodeStart(li, lineText, tokens); final int endOfCodeInLine = getCodeEnd(li, lineText, tokens); if (!doc.get(endOfCodeInLine, 1).equals(";")) { new Processor() { @Override public void visit(Tree.Annotation that) { super.visit(that); terminateWithSemicolon(that); } @Override public void visit(Tree.StatementOrArgument that) { super.visit(that); if (that instanceof Tree.ExecutableStatement && !(that instanceof Tree.ControlStatement) || that instanceof Tree.AttributeDeclaration || that instanceof Tree.MethodDeclaration || that instanceof Tree.ClassDeclaration || that instanceof Tree.InterfaceDeclaration || that instanceof Tree.SpecifiedArgument) { terminateWithSemicolon(that); } } private void terminateWithSemicolon(Node that) { try { if (that.getStartIndex() <= endOfCodeInLine && that.getStopIndex() >= endOfCodeInLine) { Token et = that.getEndToken(); if (et == null || et.getType() != CeylonLexer.SEMICOLON || that.getStopIndex() > endOfCodeInLine) { if (!change.getEdit().hasChildren()) { change.addEdit(new InsertEdit(endOfCodeInLine + 1, ";")); } } } } catch (Exception e) { e.printStackTrace(); } } }.visit(rootNode); if (change.getEdit().hasChildren()) { change.perform(new NullProgressMonitor()); return true; } } return false; }
static void addCurrentPackageNameCompletion( CeylonParseController cpc, int offset, String prefix, List<ICompletionProposal> result) { IFile file = cpc.getProject().getFile(cpc.getPath()); String moduleName = getPackageName(file); if (moduleName != null) { result.add( new CompletionProposal( offset, prefix, isModuleDescriptor(cpc) ? MODULE : PACKAGE, moduleName, moduleName)); } }
@Override protected IStructureComparator createStructureComparator( Object input, IDocument document, ISharedDocumentAdapter sharedDocumentAdapter, IProgressMonitor monitor) throws CoreException { if (input instanceof CeylonDocumentRangeNode) { return (CeylonDocumentRangeNode) input; } final boolean isEditable; if (input instanceof IEditableContent) { IEditableContent ec = (IEditableContent) input; isEditable = ec.isEditable(); } else { isEditable = false; } StructureRootNode structureRootNode = new StructureRootNode(document, input, this, sharedDocumentAdapter) { @Override public boolean isEditable() { return isEditable; } }; CeylonParseController pc = new CeylonParseController(); if (input instanceof ResourceNode) { ResourceNode node = (ResourceNode) input; IResource file = node.getResource(); pc.initialize(file.getProjectRelativePath(), file.getProject(), null); } else { pc.initialize(null, null, null); } if (pc.parseAndTypecheck(document, 10, monitor, null) != null) { // now visit the model, creating TreeCompareNodes for each ModelTreeNode CeylonOutlineNode tree = new CeylonOutlineBuilder() { // don't create nodes for shortcut refinement // because we can't distinguish them w/o a // full typecheck public void visit(Tree.SpecifierStatement that) {} }.buildTree(pc); if (tree != null) { buildCompareTree(tree, structureRootNode, document); } } return structureRootNode; }
@Override public boolean isEnabled() { IEditorPart editor = getCurrentEditor(); if (super.isEnabled() && editor instanceof CeylonEditor && editor.getEditorInput() instanceof IFileEditorInput) { CeylonParseController cpc = ((CeylonEditor) editor).getParseController(); return cpc == null || cpc.getRootNode() == null ? false : true; // !cpc.getRootNode().getImportList().getImports().isEmpty(); } return false; }
@Override public IHyperlink[] detectHyperlinks( ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) { if (controller == null || controller.getLastCompilationUnit() == null) { return null; } else { Node node = findNode( controller.getLastCompilationUnit(), controller.getTokens(), region.getOffset(), region.getOffset() + region.getLength()); if (node == null) { return null; } else { Node id = getIdentifyingNode(node); if (id == null) { return null; } else { Referenceable referenceable = getReferencedModel(node); Backends supportedBackends = supportedBackends(); if (referenceable instanceof Declaration) { Declaration dec = (Declaration) referenceable; if (dec.isNative()) { if (supportedBackends.none()) { return null; } else { referenceable = resolveNative(referenceable, dec, supportedBackends); } } else { if (!supportedBackends.none()) { return null; } } } else { // Module or package descriptors if (!supportedBackends.none()) { return null; } } Node r = getReferencedNode(referenceable); if (r == null) { return null; } else { return new IHyperlink[] {new CeylonNodeLink(r, id)}; } } } } }
static boolean isEmptyPackageDescriptor(CeylonParseController cpc) { Tree.CompilationUnit lcu = cpc.getLastCompilationUnit(); return lcu != null && lcu.getUnit() != null && lcu.getUnit().getFilename().equals("package.ceylon") && lcu.getPackageDescriptors().isEmpty(); }
static Tree.CompilationUnit getRootNode(PhasedUnit unit) { IEditorPart ce = getCurrentEditor(); if (ce instanceof CeylonEditor) { CeylonEditor editor = (CeylonEditor) ce; CeylonParseController cpc = editor.getParseController(); if (cpc != null) { Tree.CompilationUnit rn = cpc.getTypecheckedRootNode(); if (rn != null) { Unit u = rn.getUnit(); if (u.equals(unit.getUnit())) { return rn; } } } } return unit.getCompilationUnit(); }
private Tree.Declaration getSelectionTarget(ITextSelection textSel) { CeylonEditor editor = (CeylonEditor) getCurrentEditor(); CeylonParseController pc = editor.getParseController(); if (pc == null) { return null; } else { Tree.CompilationUnit ast = pc.getRootNode(); if (ast == null) { return null; } else { Object sourceNode = findNode(ast, textSel.getOffset()); if (sourceNode == null) { return null; } else { return getReferencedNode(sourceNode, pc); } } } }
static boolean isModuleDescriptor(CeylonParseController cpc) { Tree.CompilationUnit lcu = cpc.getLastCompilationUnit(); return lcu != null && lcu.getUnit() != null && lcu.getUnit().getFilename().equals("module.ceylon"); }
public static String getInitialValueDescription( final Declaration dec, CeylonParseController cpc) { if (cpc != null) { Node refnode = getReferencedNode(dec); Tree.SpecifierOrInitializerExpression sie = null; String arrow = null; if (refnode instanceof Tree.AttributeDeclaration) { Tree.AttributeDeclaration ad = (Tree.AttributeDeclaration) refnode; sie = ad.getSpecifierOrInitializerExpression(); arrow = " = "; } else if (refnode instanceof Tree.MethodDeclaration) { Tree.MethodDeclaration md = (Tree.MethodDeclaration) refnode; sie = md.getSpecifierExpression(); arrow = " => "; } Tree.CompilationUnit lcu = cpc.getLastCompilationUnit(); if (sie == null) { class FindInitializerVisitor extends Visitor { Tree.SpecifierOrInitializerExpression result; @Override public void visit(Tree.InitializerParameter that) { super.visit(that); Declaration d = that.getParameterModel().getModel(); if (d != null && d.equals(dec)) { result = that.getSpecifierExpression(); } } } FindInitializerVisitor fiv = new FindInitializerVisitor(); fiv.visit(lcu); sie = fiv.result; } if (sie != null) { Tree.Expression e = sie.getExpression(); if (e != null) { Tree.Term term = e.getTerm(); if (term instanceof Tree.Literal) { String text = term.getToken().getText(); if (text.length() < 20) { return arrow + text; } } else if (term instanceof Tree.BaseMemberOrTypeExpression) { Tree.BaseMemberOrTypeExpression bme = (Tree.BaseMemberOrTypeExpression) term; Tree.Identifier id = bme.getIdentifier(); if (id != null && bme.getTypeArguments() == null) { return arrow + id.getText(); } } else if (term != null) { Unit unit = lcu.getUnit(); if (term.getUnit().equals(unit)) { String impl = Nodes.text(term, cpc.getTokens()); if (impl.length() < 10) { return arrow + impl; } } } // don't have the token stream :-/ // TODO: figure out where to get it from! return arrow + "..."; } } } return ""; }
static boolean isEmptyModuleDescriptor(CeylonParseController cpc) { Tree.CompilationUnit lcu = cpc.getLastCompilationUnit(); return isModuleDescriptor(cpc) && lcu != null && lcu.getModuleDescriptors().isEmpty(); }
private boolean terminateWithBrace() throws Exception { IDocument doc = editor.getCeylonSourceViewer().getDocument(); final TextChange change = new DocumentChange("Terminate Statement", doc); change.setEdit(new MultiTextEdit()); CeylonParseController parser = parse(); CompilationUnit rootNode = parser.getRootNode(); IRegion li = getLineInfo(doc); final String lineText = doc.get(li.getOffset(), li.getLength()); final List<CommonToken> tokens = parser.getTokens(); final int startOfCodeInLine = getCodeStart(li, lineText, tokens); final int endOfCodeInLine = getCodeEnd(li, lineText, tokens); new Processor() { @Override public void visit(Tree.Expression that) { super.visit(that); if (that.getStopIndex() <= endOfCodeInLine && that.getStartIndex() >= startOfCodeInLine) { Token et = that.getMainEndToken(); Token st = that.getMainToken(); if (st != null && st.getType() == CeylonLexer.LPAREN && (et == null || et.getType() != CeylonLexer.RPAREN)) { if (!change.getEdit().hasChildren()) { change.addEdit(new InsertEdit(that.getStopIndex() + 1, ")")); } } } } @Override public void visit(Tree.ParameterList that) { super.visit(that); terminate(that, CeylonLexer.RPAREN, ")"); } public void visit(Tree.IndexExpression that) { super.visit(that); terminate(that, CeylonLexer.RBRACKET, "]"); } @Override public void visit(Tree.TypeParameterList that) { super.visit(that); terminate(that, CeylonLexer.LARGER_OP, ">"); } @Override public void visit(Tree.TypeArgumentList that) { super.visit(that); terminate(that, CeylonLexer.LARGER_OP, ">"); } @Override public void visit(Tree.PositionalArgumentList that) { super.visit(that); if (that.getToken().getType() == CeylonLexer.LPAREN) { // for infix function syntax terminate(that, CeylonLexer.RPAREN, ")"); } } @Override public void visit(Tree.NamedArgumentList that) { super.visit(that); terminate(that, CeylonLexer.RBRACE, " }"); } @Override public void visit(Tree.SequenceEnumeration that) { super.visit(that); terminate(that, CeylonLexer.RBRACE, " }"); } @Override public void visit(Tree.IterableType that) { super.visit(that); terminate(that, CeylonLexer.RBRACE, "}"); } @Override public void visit(Tree.Tuple that) { super.visit(that); terminate(that, CeylonLexer.RBRACKET, "]"); } @Override public void visit(Tree.TupleType that) { super.visit(that); terminate(that, CeylonLexer.RBRACKET, "]"); } @Override public void visit(Tree.ConditionList that) { super.visit(that); initiate(that, CeylonLexer.LPAREN, "("); // does not really work right: terminate(that, CeylonLexer.RPAREN, ")"); } @Override public void visit(Tree.ForIterator that) { super.visit(that); initiate(that, CeylonLexer.LPAREN, "("); // does not really work right: terminate(that, CeylonLexer.RPAREN, ")"); } @Override public void visit(Tree.ImportMemberOrTypeList that) { super.visit(that); terminate(that, CeylonLexer.RBRACE, " }"); } @Override public void visit(Tree.ImportModule that) { super.visit(that); terminate(that, CeylonLexer.SEMICOLON, ";"); } @Override public void visit(Tree.ImportModuleList that) { super.visit(that); terminate(that, CeylonLexer.RBRACE, " }"); } @Override public void visit(Tree.PackageDescriptor that) { super.visit(that); terminate(that, CeylonLexer.SEMICOLON, ";"); } @Override public void visit(Tree.Body that) { super.visit(that); terminate(that, CeylonLexer.RBRACE, " }"); } @Override public void visit(Tree.StatementOrArgument that) { super.visit(that); if ( /*that instanceof Tree.ExecutableStatement && !(that instanceof Tree.ControlStatement) || that instanceof Tree.AttributeDeclaration || that instanceof Tree.MethodDeclaration || that instanceof Tree.ClassDeclaration || that instanceof Tree.InterfaceDeclaration ||*/ that instanceof Tree.SpecifiedArgument) { terminate(that, CeylonLexer.SEMICOLON, ";"); } } private void initiate(Node that, int tokenType, String ch) { if (that.getStartIndex() >= startOfCodeInLine && that.getStartIndex() <= endOfCodeInLine) { Token et = that.getMainToken(); if (et == null || et.getType() != tokenType || et.getText().startsWith("<missing ")) { if (!change.getEdit().hasChildren()) { change.addEdit(new InsertEdit(that.getStartIndex(), ch)); } } } } private void terminate(Node that, int tokenType, String ch) { if (that.getStartIndex() >= startOfCodeInLine && that.getStartIndex() <= endOfCodeInLine) { Token et = that.getMainEndToken(); if ((et == null || et.getType() != tokenType) || that.getStopIndex() > endOfCodeInLine) { if (!change.getEdit().hasChildren()) { change.addEdit(new InsertEdit(min(endOfCodeInLine, that.getStopIndex()) + 1, ch)); } } } } }.visit(rootNode); if (change.getEdit().hasChildren()) { change.perform(new NullProgressMonitor()); return true; } return false; }