|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2004 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.javacore.parser; import java.io.*; import java.net.URI; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import javax.swing.text.Position.Bias; import org.netbeans.api.java.classpath.ClassPath; import org.netbeans.api.java.queries.SourceLevelQuery; import org.netbeans.jmi.javamodel.Resource; import org.netbeans.lib.java.parser.*; import org.netbeans.modules.javacore.JMManager; import org.openide.ErrorManager; import org.openide.cookies.EditorCookie; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; import org.openide.loaders.DataObject; import org.openide.text.EditorSupport; import org.openide.text.PositionBounds; import org.openide.text.PositionRef; /** * * @author Tomas Hurka */ public class ASTProvider implements ParserTokens, ASTreeTypes, ASTContext { DataObject dobj; private EditorSupport editor; private ASTree topNode; private Token[] tokens; private String sourceText; private Resource rsc; static ASTree[] NULL_TREE=new ASTree[0]; boolean documentPositions; boolean hasSyntaxErrors; /** Creates a new instance of ASTProvider */ public ASTProvider(Resource r,DataObject obj) { rsc=r; dobj = obj; if (obj == null) throw new NullPointerException(); } protected ASTProvider(Resource r, DataObject obj, String sourceText, boolean isFromDoc) { this(r, obj); this.sourceText = sourceText; this.documentPositions = isFromDoc; } private void createASTree() { Reader r; int status=-1; hasSyntaxErrors = false; try { r=getReader(); } catch (Exception ex) { JMManager.getLog().log("Error opening stream for: " + getResource().getName() + "; " + ex.toString()); ErrorManager.getDefault().notify(ex); return; } JParser parser=Factory.getDefault().getParser(this, r, dobj.getName()); try { status=parser.parse(); } catch (Exception ex) { dumpSource(ex); } if (status!=0) { hasSyntaxErrors = true; ASTree compUnit=parser.getASTree(); if (compUnit!=null && compUnit.getType()==COMPILATION_UNIT) topNode=compUnit; // System.out.println("Error in file: "+dobj.getPrimaryFile().getPath()+" has ASTree "+(topNode!=null)); if (topNode != null) { fixTree(topNode); } //return; } topNode=parser.getASTree(); tokens=parser.getTokens(); if (tokens == null) tokens = new Token[0]; if (topNode == null || topNode.getSubTrees() == null) { // let's create a fake AST TokenIterator ti = new TokenIterator(ASTProvider.this); int i = 0; try { while (ti.getNextTokenType() != 0) i++; } catch (IOException e) { ErrorManager.getDefault().notify(e); } topNode = new ASTreeNode(COMPILATION_UNIT, 0, i - 1, new ASTree[] {null, null, null}); } } private ASTree fixTree(ASTree tree) { if (tree == null) return null; int type = tree.getType(); ASTree parts[] = tree.getSubTrees(); switch (type) { case ENUM_BODY: case COMPILATION_UNIT: { fixChildren(parts); break; } case ENUM_CONSTANT: { if (parts == null) return null; parts[1] = parts[2] = null; } case TYPE_PARAMETER: case SUPER_: case CONSTRUCTOR_DECLARATOR: case PACKAGE_DECLARATION: { fixChildren(parts); if (parts == null || parts[0] == null || (parts[0].getType() != IDENTIFIER && parts[0].getType() != MULTI_PART_ID)) { return null; } break; } case PRIMITIVE_TYPE: { fixChildren(parts); if (parts == null || parts[0] == null) { return null; } switch (parts[0].getType()) { case BOOLEAN: case BYTE: case CHAR: case DOUBLE: case FLOAT: case INT: case LONG: case SHORT: case VOID: break; default: return null; } break; } case METHOD_DECLARATOR: { fixChildren(parts); if (parts == null || parts[0] == null || parts[0].getType() != IDENTIFIER) { return null; } break; } case MULTI_PART_ID: { if (parts == null) return null; fixChildren(parts); if ((parts[0] != null) && (parts[0].getType() != IDENTIFIER) && (parts[0].getType() != MULTI_PART_ID)) { return null; } if (parts[1] == null || parts[1].getType() != IDENTIFIER) { return null; } break; } case SINGLE_TYPE_IMPORT: case TYPE_IMPORT_ON_DEMAND: { if (parts == null) return null; fixChildren(parts); if (parts[1] == null) { return null; } break; } case REFERENCE_TYPE: { if (parts == null) return null; fixChildren(parts); if (parts[0] == null || parts[1] == null) { return null; } break; } case ANNOTATION_TYPE_DECLARATION: case FIELD_DECLARATION: case ANNOTATION_ATTRIBUTE_DECLARATION: { if (parts == null) return null; fixChildren(parts); if (parts[1] == null || parts[2] == null) { return null; } break; } case ENUM_DECLARATION: { if (parts == null) return null; fixChildren(parts); if (parts[1] == null || parts[1].getType() != IDENTIFIER || parts[3] == null) { return null; } break; } case FORMAL_PARAMETER: { if (parts == null) return null; fixChildren(parts); if (parts[1] == null || parts[3] == null) { return null; } break; } case CLASS_DECLARATION: case INTERFACE_DECLARATION: { if (parts == null) return null; fixChildren(parts); if (parts[1] == null || parts[1].getType() != IDENTIFIER || parts[5] == null) { return null; } break; } case CONSTRUCTOR_DECLARATION: { if (parts == null) return null; fixChildren(parts); if (parts[3] == null || parts[5] == null || parts[5].getType() != BLOCK_STATEMENTS) { return null; } break; } case METHOD_DECLARATION: { if (parts == null) return null; fixChildren(parts); if (parts[2] == null || parts[3] == null || parts[5] == null || (parts[5].getType() != BLOCK_STATEMENTS && parts[5].getType() != SEMICOLON)) { return null; } break; } case VARIABLE_DECLARATORS: { ASTree result = fixChildren(tree, type, parts); if (result != null && result.getSubTrees().length == 1) { result = result.getSubTrees()[0]; } return result; } case VARIABLE_DECLARATOR: { if (parts == null) return null; if (parts.length > 2) parts[2] = null; fixChildren(parts); if (parts[0] == null || parts[0].getType() != IDENTIFIER) { return null; } break; } case TYPE_ARGUMENTS: case TYPE_DECLARATIONS: case MODIFIERS: case TYPE_PARAMETER_LIST: case BOUND_LIST: case FORMAL_PARAMETER_LIST: case ENUM_CONSTANTS: case IMPORT_DECLARATIONS: { return fixChildren(tree, type, parts); } case TYPE_LIST: { return fixChildren(tree, type, parts,new int[] {MULTI_PART_ID|IDENTIFIER}); } case ANNOTATION_TYPE_BODY_DECLARATIONS: case ENUM_BODY_DECLARATIONS: case INTERFACE_MEMBER_DECLARATIONS: case CLASS_BODY_DECLARATIONS: { ASTree result = fixChildren(tree, type, parts); return result == null ? new ASTreeNode(type, tree.getFirstToken(), tree.getLastToken(), NULL_TREE) : result; } case WILDCARD: { if (parts == null) return null; fixChildren(parts); if ((parts[0] == null) != (parts[1] == null)) { return null; } break; } case BLOCK_STATEMENTS: { return new ASTreeNode(type, tree.getFirstToken(), tree.getLastToken(), NULL_TREE); } case ERRONEOUS: case ANNOTATION: case INSTANCE_INITIALIZER: case STATIC_INITIALIZER: case DEFAULT_VALUE: { return null; } } return tree; } private ASTree fixChildren(ASTree tree, int type, ASTree[] parts) { return fixChildren(tree, type, parts, null); } /** NOTE !! * allowedTypes must be sorted */ private ASTree fixChildren(ASTree tree, int type, ASTree[] parts,int[] allowedTypes) { if (parts == null) return null; int i = 0, j = 0; for (; i < parts.length; i++) { parts[i] = fixTree(parts[i]); if (parts[i] != null && (allowedTypes==null || Arrays.binarySearch(allowedTypes,parts[i].getType())>=0)) { j++; } } if (j == 0) return null; if (j < i) { ASTree[] newParts = new ASTree[j]; for (i = 0, j = 0; i < parts.length; i++) { if (parts[i] != null) { newParts[j++] = parts[i]; } } return new ASTreeNode(type, tree.getFirstToken(), tree.getLastToken(), newParts); } return tree; } private void fixChildren(ASTree[] parts) { if (parts == null) return; for (int i = 0; i < parts.length; i++) { parts[i] = fixTree(parts[i]); } } public ASTree getASTree() { if (!dobj.isValid()) return null; if (topNode==null) createASTree(); return topNode; } public boolean hasSyntaxError() { return hasSyntaxErrors; } DataObject getDataObject() { return dobj; } String getRealSource(boolean overridePositions) throws FileNotFoundException, UnsupportedEncodingException, IOException { EditorCookie editor; Document doc=null; editor = (EditorCookie) dobj.getCookie(EditorCookie.class); if (editor!=null) { doc = editor.getDocument(); } if (doc != null) { if (overridePositions) documentPositions = true; // loading from the memory (Document) final String[] str = new String[1]; // safely take the text from the document final Document doc2 = doc; Runnable run = new Runnable() { public void run() { try { str[0] = doc2.getText(0, doc2.getLength()); } catch (BadLocationException e) { // impossible } } }; doc.render(run); return str[0]; } else { // loading from the file FileObject fo = dobj.getPrimaryFile(); InputStream is = fo.getInputStream(); Reader fileReader; // if (filter) { // reader = new GuardedReader(is, true); // } else { String encoding=Util.getFileEncoding(fo); if (encoding == null) { fileReader = new InputStreamReader(is); } else { fileReader = new InputStreamReader(is, encoding); } } char[] c = Util.readContents(fileReader); fileReader.close(); return new String(c); } } Reader getFileReader(boolean overridePositions) throws FileNotFoundException, UnsupportedEncodingException, IOException { return new StringReader(getRealSource(overridePositions)); } /** Returns contents of DataObject obj. If the object is opened in the editor, * the function returns current contents of the edited document. * If the file is not opened in a JavaEditor, it is read from the disk and * guarded sections are filtered out. * @return contents of the file/editor document; guarded section markers are filtered out. * */ public Reader getReader() throws FileNotFoundException, UnsupportedEncodingException, IOException { if (sourceText==null) { sourceText = getRealSource(true); } return new StringReader(sourceText); } public Resource getResource() { return rsc; } public String getJavaDoc(ASTree tree) { String javadoText=null; Token javaDocToken=getComment(tree); if (javaDocToken.getType()==DOC_COMMENT) { javadoText=getText(javaDocToken); } return removeJavadocStars(javadoText); } public ASTree findTree(ASTree parentTree, int firstToken, int lastToken, int type) { ASTree[] children = parentTree.getSubTrees(); for (int i = 0; i < children.length; i++) { ASTree ch = children[i]; if (ch != null) { int first = ch.getFirstToken(); int last = ch.getLastToken(); if (first == firstToken && last == lastToken && type == ch.getType()) { return ch; } if (first <= firstToken && last >= lastToken) { return findTree(ch, firstToken, lastToken, type); } } } throw new IllegalArgumentException("Child tree not found."); // NOI18N } public Token getComment(ASTree t) { Token first=getToken(t.getFirstToken()); Token pad[]=first.getPadding(); int i; for(i=pad.length-1;i>=0;i--) { Token c=pad[i]; if (c.getType()==DOC_COMMENT) return c; } return first; } ASTree[] check(ASTree tree) { if (tree==null || tree.getType()==SEMICOLON) return null; return NULL_TREE; } public ASTree[] filterParts(ASTree parts[]) { if (parts!=null) { List typeDecl=null; int i; for (i=parts.length-1;i>=0;i--) { ASTree tree=parts[i]; ASTree checked[]=check(tree); if (checked!=NULL_TREE) { if (typeDecl==null) { typeDecl=new ArrayList(Arrays.asList((Object[]) parts)); } if (checked==null) typeDecl.remove(i); else typeDecl.addAll(i, Arrays.asList((Object[]) checked)); } } if (typeDecl!=null) { return (ASTree[])typeDecl.toArray(new ASTree[typeDecl.size()]); } } return parts; } public String getText(ASTree tree) { if (tree == null) { return null; } else { return getText(tree,tree); } } public String getText(ASTree first,ASTree last) { int start=getToken(first.getFirstToken()).getStartOffset(); int end=getToken(last.getLastToken()).getEndOffset(); return sourceText.substring(start,end); } public String getText(Token token) { int start=token.getStartOffset(); int end=token.getEndOffset(); return sourceText.substring(start,end); } public Token getToken(int index) { return (index >= 0 && index < tokens.length) ? tokens[index] : null; } public ASTree getParent(ASTree tree) { ASTree parent=getASTree(); int index=tree.getFirstToken(); while(true) { ASTree parts[]=parent.getSubTrees(); ASTree element=null; int i; for (i=0;i |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.