This is an automated email from the ASF dual-hosted git repository.

joshtynjala pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-compiler.git


The following commit(s) were added to refs/heads/develop by this push:
     new fd1a5920e linter: more performance optimization
fd1a5920e is described below

commit fd1a5920e64d9939da95d701319791ab616c2615
Author: Josh Tynjala <[email protected]>
AuthorDate: Wed Dec 18 14:48:22 2024 -0800

    linter: more performance optimization
    
    TokenQuery now uses binary search to find the nearest token to a specified 
source location. Luckily, the array of tokens is pre-sorted by position.
    
    linting royale-asjs/frameworks/projects went from 26s to 14s on my machine 
(nearly half the time!)
---
 .../java/org/apache/royale/linter/TokenQuery.java  | 182 ++++++++++++---------
 1 file changed, 109 insertions(+), 73 deletions(-)

diff --git a/linter/src/main/java/org/apache/royale/linter/TokenQuery.java 
b/linter/src/main/java/org/apache/royale/linter/TokenQuery.java
index 798e49d0d..1c6ea5cfe 100644
--- a/linter/src/main/java/org/apache/royale/linter/TokenQuery.java
+++ b/linter/src/main/java/org/apache/royale/linter/TokenQuery.java
@@ -56,13 +56,16 @@ public class TokenQuery {
         */
        public IASToken[] getTokens(IASNode node, boolean skipComments, boolean 
skipWhitespace) {
                List<IASToken> result = new ArrayList<>();
-               for (IASToken token : allTokens) {
-                       if (token.getAbsoluteStart() < node.getAbsoluteStart()) 
{
-                               continue;
-                       }
+               int start = findNearestToken(allTokens, node);
+               int end = allTokens.length;
+               for (int i = start; i < end; i++) {
+                       IASToken token = allTokens[i];
                        if (token.getAbsoluteStart() >= node.getAbsoluteEnd()) {
                                break;
                        }
+                       if (token.getAbsoluteStart() < node.getAbsoluteStart()) 
{
+                               continue;
+                       }
                        if (skipComments && isComment(token)) {
                                continue;
                        }
@@ -87,20 +90,21 @@ public class TokenQuery {
         * to skip comment and whitespace tokens.
         */
        public IASToken getTokenBefore(ISourceLocation sourceLocation, boolean 
skipComments, boolean skipWhitespace) {
-               IASToken result = null;
-               for (IASToken token : allTokens) {
+               int start = findNearestToken(allTokens, sourceLocation);
+               for (int i = start - 1; i >= 0; i--) {
+                       IASToken token = allTokens[i];
+                       if (token.getAbsoluteStart() >= 
sourceLocation.getAbsoluteStart()) {
+                               continue;
+                       }
                        if (skipComments && isComment(token)) {
                                continue;
                        }
                        if (skipWhitespace && isWhitespace(token)) {
                                continue;
                        }
-                       if (token.getAbsoluteStart() >= 
sourceLocation.getAbsoluteStart()) {
-                               return result;
-                       }
-                       result = token;
+                       return token;
                }
-               return result;
+               return null;
        }
 
        /**
@@ -116,16 +120,20 @@ public class TokenQuery {
         * skip comment and whitespace tokens.
         */
        public IASToken getTokenAfter(ISourceLocation sourceLocation, boolean 
skipComments, boolean skipWhitespace) {
-               for (IASToken token : allTokens) {
-                       if (token.getAbsoluteStart() >= 
sourceLocation.getAbsoluteEnd()) {
-                               if (skipComments && isComment(token)) {
-                                       continue;
-                               }
-                               if (skipWhitespace && isWhitespace(token)) {
-                                       continue;
-                               }
-                               return token;
+               int start = findNearestToken(allTokens, sourceLocation);
+               int end = allTokens.length;
+               for (int i = start; i < end; i++) {
+                       IASToken token = allTokens[i];
+                       if (token.getAbsoluteStart() < 
sourceLocation.getAbsoluteEnd()) {
+                               continue;
+                       }
+                       if (skipComments && isComment(token)) {
+                               continue;
+                       }
+                       if (skipWhitespace && isWhitespace(token)) {
+                               continue;
                        }
+                       return token;
                }
                return null;
        }
@@ -143,18 +151,11 @@ public class TokenQuery {
         * skip comment and whitespace tokens.
         */
        public IASToken getFirstToken(IASNode node, boolean skipComments, 
boolean skipWhitespace) {
-               for (IASToken token : allTokens) {
-                       if (token.getAbsoluteStart() >= 
node.getAbsoluteStart()) {
-                               if (skipComments && isComment(token)) {
-                                       continue;
-                               }
-                               if (skipWhitespace && isWhitespace(token)) {
-                                       continue;
-                               }
-                               return token;
-                       }
+               IASToken[] tokens = getTokens(node, skipComments, 
skipWhitespace);
+               if (tokens.length == 0) {
+                       return null;
                }
-               return null;
+               return tokens[0];
        }
 
        /**
@@ -170,21 +171,11 @@ public class TokenQuery {
         * skip comment and whitespace tokens.
         */
        public IASToken getLastToken(IASNode node, boolean skipComments, 
boolean skipWhitespace) {
-               IASToken result = null;
-               for (IASToken token : allTokens) {
-                       if (token.getAbsoluteStart() >= 
node.getAbsoluteStart()) {
-                               if (skipComments && isComment(token)) {
-                                       continue;
-                               }
-                               if (skipWhitespace && isWhitespace(token)) {
-                                       continue;
-                               }
-                               result = token;
-                       } else if (result != null) {
-                               break;
-                       }
+               IASToken[] tokens = getTokens(node, skipComments, 
skipWhitespace);
+               if (tokens.length == 0) {
+                       return null;
                }
-               return result;
+               return tokens[tokens.length - 1];
        }
 
        /**
@@ -192,16 +183,18 @@ public class TokenQuery {
         * start of a particular source location.
         */
        public IASToken getPreviousTokenOfType(ISourceLocation before, int 
type) {
-               IASToken result = null;
-               for (IASToken token : allTokens) {
-                       if (token.getAbsoluteStart() >= 
before.getAbsoluteStart()) {
-                               return result;
+               int start = findNearestToken(allTokens, before);
+               for (int i = start - 1; i >= 0; i--) {
+                       IASToken token = allTokens[i];
+                       if (token.getType() != type) {
+                               continue;
                        }
-                       if (token.getType() == type) {
-                               result = token;
+                       if (token.getAbsoluteStart() >= 
before.getAbsoluteStart()) {
+                               continue;
                        }
+                       return token;
                }
-               return result;
+               return null;
        }
 
        /**
@@ -209,10 +202,17 @@ public class TokenQuery {
         * of a particular source location.
         */
        public IASToken getNextTokenOfType(ISourceLocation after, int type) {
-               for (IASToken token : allTokens) {
-                       if (token.getType() == type && token.getAbsoluteStart() 
>= after.getAbsoluteEnd()) {
-                               return token;
+               int start = findNearestToken(allTokens, after);
+               int end = allTokens.length;
+               for (int i = start; i < end; i++) {
+                       IASToken token = allTokens[i];
+                       if (token.getType() != type) {
+                               continue;
+                       }
+                       if (token.getAbsoluteStart() < after.getAbsoluteEnd()) {
+                               continue;
                        }
+                       return token;
                }
                return null;
        }
@@ -246,16 +246,18 @@ public class TokenQuery {
         * source location.
         */
        public IASToken getCommentBefore(ISourceLocation before) {
-               IASToken result = null;
-               for (IASToken token : allTokens) {
+               int start = findNearestToken(allTokens, before);
+               for (int i = start - 1; i >= 0; i--) {
+                       IASToken token = allTokens[i];
                        if (token.getAbsoluteStart() >= 
before.getAbsoluteStart()) {
-                               return result;
+                               continue;
                        }
-                       if (isComment(token)) {
-                               result = token;
+                       if (!isComment(token)) {
+                               continue;
                        }
+                       return token;
                }
-               return result;
+               return null;
        }
 
        /**
@@ -263,10 +265,17 @@ public class TokenQuery {
         * source location.
         */
        public IASToken getCommentAfter(ISourceLocation after) {
-               for (IASToken token : allTokens) {
-                       if (token.getAbsoluteStart() >= after.getAbsoluteEnd() 
&& isComment(token)) {
-                               return token;
+               int start = findNearestToken(allTokens, after);
+               int end = allTokens.length;
+               for (int i = start; i < end; i++) {
+                       IASToken token = allTokens[i];
+                       if (!isComment(token)) {
+                               continue;
                        }
+                       if (token.getAbsoluteStart() < after.getAbsoluteEnd()) {
+                               continue;
+                       }
+                       return token;
                }
                return null;
        }
@@ -283,16 +292,18 @@ public class TokenQuery {
         * particular source location.
         */
        public IASToken getWhitespaceBefore(ISourceLocation before) {
-               IASToken result = null;
-               for (IASToken token : allTokens) {
+               int start = findNearestToken(allTokens, before);
+               for (int i = start - 1; i >= 0; i--) {
+                       IASToken token = allTokens[i];
                        if (token.getAbsoluteStart() >= 
before.getAbsoluteStart()) {
-                               return result;
+                               continue;
                        }
-                       if (isWhitespace(token)) {
-                               result = token;
+                       if (!isWhitespace(token)) {
+                               continue;
                        }
+                       return token;
                }
-               return result;
+               return null;
        }
 
        /**
@@ -300,10 +311,17 @@ public class TokenQuery {
         * particular source location.
         */
        public IASToken getWhitespaceAfter(ISourceLocation after) {
-               for (IASToken token : allTokens) {
-                       if (token.getAbsoluteStart() >= after.getAbsoluteEnd() 
&& isWhitespace(token)) {
-                               return token;
+               int start = findNearestToken(allTokens, after);
+               int end = allTokens.length;
+               for (int i = start; i < end; i++) {
+                       IASToken token = allTokens[i];
+                       if (!isWhitespace(token)) {
+                               continue;
                        }
+                       if (token.getAbsoluteStart() < after.getAbsoluteEnd()) {
+                               continue;
+                       }
+                       return token;
                }
                return null;
        }
@@ -323,4 +341,22 @@ public class TokenQuery {
        public IASToken getSignificantTokenAfter(ISourceLocation after) {
                return getTokenAfter(after, true, true);
        }
+
+       private static int findNearestToken(IASToken[] array, ISourceLocation 
toFind) {
+               int low = 0;
+               int high = array.length - 1;
+               int keyVal = toFind.getAbsoluteStart();
+               while (low <= high) {
+                       int mid = (low + high) / 2;
+                       int midVal = array[mid].getAbsoluteStart();
+                       if (midVal < keyVal) {
+                               low = mid + 1;
+                       } else if (midVal > keyVal) {
+                               high = mid - 1;
+                       } else {
+                               return mid;
+                       }
+               }
+               return low;
+       }
 }

Reply via email to